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 #include <osdep.h> 20 #include "wmi.h" 21 #include "wmi_unified_priv.h" 22 #include "wmi_unified_twt_param.h" 23 #include "wmi_unified_twt_api.h" 24 25 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle, 26 struct wmi_twt_enable_param *params) 27 { 28 wmi_twt_enable_cmd_fixed_param *cmd; 29 wmi_buf_t buf; 30 QDF_STATUS status; 31 32 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 33 if (!buf) { 34 wmi_err("Failed to allocate memory"); 35 return QDF_STATUS_E_FAILURE; 36 } 37 38 cmd = (wmi_twt_enable_cmd_fixed_param *) wmi_buf_data(buf); 39 WMITLV_SET_HDR(&cmd->tlv_header, 40 WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param, 41 WMITLV_GET_STRUCT_TLVLEN 42 (wmi_twt_enable_cmd_fixed_param)); 43 44 cmd->pdev_id = 45 wmi_handle->ops->convert_pdev_id_host_to_target( 46 wmi_handle, 47 params->pdev_id); 48 cmd->sta_cong_timer_ms = params->sta_cong_timer_ms; 49 cmd->mbss_support = params->mbss_support; 50 cmd->default_slot_size = params->default_slot_size; 51 cmd->congestion_thresh_setup = params->congestion_thresh_setup; 52 cmd->congestion_thresh_teardown = params->congestion_thresh_teardown; 53 cmd->congestion_thresh_critical = params->congestion_thresh_critical; 54 cmd->interference_thresh_teardown = 55 params->interference_thresh_teardown; 56 cmd->interference_thresh_setup = params->interference_thresh_setup; 57 cmd->min_no_sta_setup = params->min_no_sta_setup; 58 cmd->min_no_sta_teardown = params->min_no_sta_teardown; 59 cmd->no_of_bcast_mcast_slots = params->no_of_bcast_mcast_slots; 60 cmd->min_no_twt_slots = params->min_no_twt_slots; 61 cmd->max_no_sta_twt = params->max_no_sta_twt; 62 cmd->mode_check_interval = params->mode_check_interval; 63 cmd->add_sta_slot_interval = params->add_sta_slot_interval; 64 cmd->remove_sta_slot_interval = params->remove_sta_slot_interval; 65 66 TWT_EN_DIS_FLAGS_SET_BTWT(cmd->flags, params->b_twt_enable); 67 TWT_EN_DIS_FLAGS_SET_L_MBSSID(cmd->flags, 68 params->b_twt_legacy_mbss_enable); 69 TWT_EN_DIS_FLAGS_SET_AX_MBSSID(cmd->flags, 70 params->b_twt_ax_mbss_enable); 71 if (params->ext_conf_present) { 72 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 73 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 74 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 75 } 76 77 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 78 WMI_TWT_ENABLE_CMDID); 79 if (QDF_IS_STATUS_ERROR(status)) { 80 wmi_err("Failed to send WMI_TWT_ENABLE_CMDID"); 81 wmi_buf_free(buf); 82 } 83 84 return status; 85 } 86 87 88 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle, 89 struct wmi_twt_disable_param *params) 90 { 91 wmi_twt_disable_cmd_fixed_param *cmd; 92 wmi_buf_t buf; 93 QDF_STATUS status; 94 95 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 96 if (!buf) { 97 wmi_err("Failed to allocate memory"); 98 return QDF_STATUS_E_FAILURE; 99 } 100 101 cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf); 102 WMITLV_SET_HDR(&cmd->tlv_header, 103 WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param, 104 WMITLV_GET_STRUCT_TLVLEN 105 (wmi_twt_disable_cmd_fixed_param)); 106 107 cmd->pdev_id = 108 wmi_handle->ops->convert_pdev_id_host_to_target( 109 wmi_handle, 110 params->pdev_id); 111 if (params->ext_conf_present) { 112 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 113 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 114 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 115 } 116 117 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 118 WMI_TWT_DISABLE_CMDID); 119 if (QDF_IS_STATUS_ERROR(status)) { 120 wmi_err("Failed to send WMI_TWT_DISABLE_CMDID"); 121 wmi_buf_free(buf); 122 } 123 124 return status; 125 } 126 127 #ifdef WLAN_SUPPORT_BCAST_TWT 128 static void 129 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params, 130 wmi_twt_add_dialog_cmd_fixed_param *cmd) 131 { 132 TWT_FLAGS_SET_BTWT_ID0(cmd->flags, params->flag_b_twt_id0); 133 cmd->b_twt_persistence = params->b_twt_persistence; 134 cmd->b_twt_recommendation = params->b_twt_recommendation; 135 136 return; 137 } 138 #else 139 static void 140 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params, 141 wmi_twt_add_dialog_cmd_fixed_param *cmd) 142 { 143 return; 144 } 145 #endif 146 147 static QDF_STATUS 148 send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle, 149 struct wmi_twt_add_dialog_param *params) 150 { 151 wmi_twt_add_dialog_cmd_fixed_param *cmd; 152 wmi_buf_t buf; 153 QDF_STATUS status; 154 155 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 156 if (!buf) { 157 wmi_err("Failed to allocate memory"); 158 return QDF_STATUS_E_FAILURE; 159 } 160 161 cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf); 162 WMITLV_SET_HDR(&cmd->tlv_header, 163 WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param, 164 WMITLV_GET_STRUCT_TLVLEN 165 (wmi_twt_add_dialog_cmd_fixed_param)); 166 167 cmd->vdev_id = params->vdev_id; 168 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 169 cmd->dialog_id = params->dialog_id; 170 cmd->wake_intvl_us = params->wake_intvl_us; 171 cmd->wake_intvl_mantis = params->wake_intvl_mantis; 172 cmd->wake_dura_us = params->wake_dura_us; 173 cmd->sp_offset_us = params->sp_offset_us; 174 cmd->min_wake_intvl_us = params->min_wake_intvl_us; 175 cmd->max_wake_intvl_us = params->max_wake_intvl_us; 176 cmd->min_wake_dura_us = params->min_wake_dura_us; 177 cmd->max_wake_dura_us = params->max_wake_dura_us; 178 TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd); 179 TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast); 180 TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger); 181 TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type); 182 TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection); 183 184 twt_add_dialog_set_bcast_twt_params(params, cmd); 185 186 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 187 WMI_TWT_ADD_DIALOG_CMDID); 188 if (QDF_IS_STATUS_ERROR(status)) { 189 wmi_err("Failed to send WMI_TWT_ADD_DIALOG_CMDID"); 190 wmi_buf_free(buf); 191 } 192 193 return status; 194 } 195 196 #ifdef WLAN_SUPPORT_BCAST_TWT 197 static void 198 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params, 199 wmi_twt_del_dialog_cmd_fixed_param *cmd) 200 { 201 cmd->b_twt_persistence = params->b_twt_persistence; 202 return; 203 } 204 #else 205 static void 206 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params, 207 wmi_twt_del_dialog_cmd_fixed_param *cmd) 208 { 209 return; 210 } 211 #endif 212 213 static QDF_STATUS 214 send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle, 215 struct wmi_twt_del_dialog_param *params) 216 { 217 wmi_twt_del_dialog_cmd_fixed_param *cmd; 218 wmi_buf_t buf; 219 QDF_STATUS status; 220 221 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 222 if (!buf) { 223 wmi_err("Failed to allocate memory"); 224 return QDF_STATUS_E_FAILURE; 225 } 226 227 cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf); 228 WMITLV_SET_HDR(&cmd->tlv_header, 229 WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param, 230 WMITLV_GET_STRUCT_TLVLEN 231 (wmi_twt_del_dialog_cmd_fixed_param)); 232 233 cmd->vdev_id = params->vdev_id; 234 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 235 cmd->dialog_id = params->dialog_id; 236 237 twt_del_dialog_set_bcast_twt_params(params, cmd); 238 239 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 240 WMI_TWT_DEL_DIALOG_CMDID); 241 if (QDF_IS_STATUS_ERROR(status)) { 242 wmi_err("Failed to send WMI_TWT_DEL_DIALOG_CMDID"); 243 wmi_buf_free(buf); 244 } 245 246 return status; 247 } 248 249 static QDF_STATUS 250 send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle, 251 struct wmi_twt_pause_dialog_cmd_param *params) 252 { 253 wmi_twt_pause_dialog_cmd_fixed_param *cmd; 254 wmi_buf_t buf; 255 QDF_STATUS status; 256 257 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 258 if (!buf) { 259 wmi_err("Failed to allocate memory"); 260 return QDF_STATUS_E_FAILURE; 261 } 262 263 cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf); 264 WMITLV_SET_HDR(&cmd->tlv_header, 265 WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param, 266 WMITLV_GET_STRUCT_TLVLEN 267 (wmi_twt_pause_dialog_cmd_fixed_param)); 268 269 cmd->vdev_id = params->vdev_id; 270 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 271 cmd->dialog_id = params->dialog_id; 272 273 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 274 WMI_TWT_PAUSE_DIALOG_CMDID); 275 if (QDF_IS_STATUS_ERROR(status)) { 276 wmi_err("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID"); 277 wmi_buf_free(buf); 278 } 279 280 return status; 281 } 282 283 static QDF_STATUS 284 send_twt_nudge_dialog_cmd_tlv(wmi_unified_t wmi_handle, 285 struct wmi_twt_nudge_dialog_cmd_param *params) 286 { 287 wmi_twt_nudge_dialog_cmd_fixed_param *cmd; 288 wmi_buf_t buf; 289 QDF_STATUS status; 290 291 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 292 if (!buf) 293 return QDF_STATUS_E_FAILURE; 294 295 cmd = (wmi_twt_nudge_dialog_cmd_fixed_param *) wmi_buf_data(buf); 296 WMITLV_SET_HDR(&cmd->tlv_header, 297 WMITLV_TAG_STRUC_wmi_twt_nudge_dialog_cmd_fixed_param, 298 WMITLV_GET_STRUCT_TLVLEN 299 (wmi_twt_nudge_dialog_cmd_fixed_param)); 300 301 cmd->vdev_id = params->vdev_id; 302 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 303 cmd->dialog_id = params->dialog_id; 304 cmd->suspend_duration_ms = params->suspend_duration / 1000; 305 cmd->next_twt_size = params->next_twt_size; 306 307 wmi_debug("vdev_id: %d dialog_id: %d duration(in ms): %u next_twt_size: %d " 308 "peer_macaddr: "QDF_MAC_ADDR_FMT, cmd->vdev_id, 309 cmd->dialog_id, cmd->suspend_duration_ms, cmd->next_twt_size, 310 QDF_MAC_ADDR_REF(params->peer_macaddr)); 311 312 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 313 WMI_TWT_NUDGE_DIALOG_CMDID); 314 if (QDF_IS_STATUS_ERROR(status)) 315 wmi_buf_free(buf); 316 317 return status; 318 } 319 320 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle, 321 struct wmi_twt_resume_dialog_cmd_param *params) 322 { 323 wmi_twt_resume_dialog_cmd_fixed_param *cmd; 324 wmi_buf_t buf; 325 QDF_STATUS status; 326 327 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 328 if (!buf) { 329 wmi_err("Failed to allocate memory"); 330 return QDF_STATUS_E_FAILURE; 331 } 332 333 cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf); 334 WMITLV_SET_HDR(&cmd->tlv_header, 335 WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param, 336 WMITLV_GET_STRUCT_TLVLEN 337 (wmi_twt_resume_dialog_cmd_fixed_param)); 338 339 cmd->vdev_id = params->vdev_id; 340 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 341 cmd->dialog_id = params->dialog_id; 342 cmd->sp_offset_us = params->sp_offset_us; 343 cmd->next_twt_size = params->next_twt_size; 344 345 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 346 WMI_TWT_RESUME_DIALOG_CMDID); 347 if (QDF_IS_STATUS_ERROR(status)) { 348 wmi_err("Failed to send WMI_TWT_RESUME_DIALOG_CMDID"); 349 wmi_buf_free(buf); 350 } 351 352 return status; 353 } 354 355 #ifdef WLAN_SUPPORT_BCAST_TWT 356 static QDF_STATUS 357 send_twt_btwt_invite_sta_cmd_tlv(wmi_unified_t wmi_handle, 358 struct wmi_twt_btwt_invite_sta_cmd_param 359 *params) 360 { 361 wmi_twt_btwt_invite_sta_cmd_fixed_param *cmd; 362 wmi_buf_t buf; 363 QDF_STATUS status; 364 365 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 366 if (!buf) { 367 wmi_err("Failed to allocate memory"); 368 return QDF_STATUS_E_FAILURE; 369 } 370 371 cmd = (wmi_twt_btwt_invite_sta_cmd_fixed_param *)wmi_buf_data(buf); 372 WMITLV_SET_HDR(&cmd->tlv_header, 373 WMITLV_TAG_STRUC_wmi_twt_btwt_invite_sta_cmd_fixed_param, 374 WMITLV_GET_STRUCT_TLVLEN 375 (wmi_twt_btwt_invite_sta_cmd_fixed_param)); 376 377 cmd->vdev_id = params->vdev_id; 378 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 379 cmd->dialog_id = params->dialog_id; 380 381 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 382 WMI_TWT_BTWT_INVITE_STA_CMDID); 383 if (QDF_IS_STATUS_ERROR(status)) { 384 wmi_buf_free(buf); 385 } 386 387 return status; 388 } 389 390 static QDF_STATUS 391 send_twt_btwt_remove_sta_cmd_tlv(wmi_unified_t wmi_handle, 392 struct wmi_twt_btwt_remove_sta_cmd_param 393 *params) 394 { 395 wmi_twt_btwt_remove_sta_cmd_fixed_param *cmd; 396 wmi_buf_t buf; 397 QDF_STATUS status; 398 399 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 400 if (!buf) { 401 wmi_err("Failed to allocate memory"); 402 return QDF_STATUS_E_FAILURE; 403 } 404 405 cmd = (wmi_twt_btwt_remove_sta_cmd_fixed_param *)wmi_buf_data(buf); 406 WMITLV_SET_HDR(&cmd->tlv_header, 407 WMITLV_TAG_STRUC_wmi_twt_btwt_remove_sta_cmd_fixed_param, 408 WMITLV_GET_STRUCT_TLVLEN 409 (wmi_twt_btwt_remove_sta_cmd_fixed_param)); 410 411 cmd->vdev_id = params->vdev_id; 412 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 413 cmd->dialog_id = params->dialog_id; 414 415 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 416 WMI_TWT_BTWT_REMOVE_STA_CMDID); 417 if (QDF_IS_STATUS_ERROR(status)) { 418 wmi_buf_free(buf); 419 } 420 421 return status; 422 } 423 #endif 424 425 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle, 426 uint8_t *evt_buf, 427 struct wmi_twt_enable_complete_event_param *params) 428 { 429 WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 430 wmi_twt_enable_complete_event_fixed_param *ev; 431 432 param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 433 if (!param_buf) { 434 wmi_err("evt_buf is NULL"); 435 return QDF_STATUS_E_INVAL; 436 } 437 438 ev = param_buf->fixed_param; 439 440 params->pdev_id = 441 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 442 ev->pdev_id); 443 params->status = ev->status; 444 445 return QDF_STATUS_SUCCESS; 446 } 447 448 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle, 449 uint8_t *evt_buf, 450 struct wmi_twt_disable_complete_event *params) 451 { 452 WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 453 wmi_twt_disable_complete_event_fixed_param *ev; 454 455 param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 456 if (!param_buf) { 457 wmi_err("evt_buf is NULL"); 458 return QDF_STATUS_E_INVAL; 459 } 460 461 ev = param_buf->fixed_param; 462 463 #if 0 464 params->pdev_id = 465 wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id); 466 params->status = ev->status; 467 #endif 468 469 return QDF_STATUS_SUCCESS; 470 } 471 472 static enum WMI_HOST_ADD_TWT_STATUS 473 wmi_get_converted_twt_add_dialog_status(WMI_ADD_TWT_STATUS_T tgt_status) 474 { 475 switch (tgt_status) { 476 case WMI_ADD_TWT_STATUS_OK: 477 return WMI_HOST_ADD_TWT_STATUS_OK; 478 case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED: 479 return WMI_HOST_ADD_TWT_STATUS_TWT_NOT_ENABLED; 480 case WMI_ADD_TWT_STATUS_USED_DIALOG_ID: 481 return WMI_HOST_ADD_TWT_STATUS_USED_DIALOG_ID; 482 case WMI_ADD_TWT_STATUS_INVALID_PARAM: 483 return WMI_HOST_ADD_TWT_STATUS_INVALID_PARAM; 484 case WMI_ADD_TWT_STATUS_NOT_READY: 485 return WMI_HOST_ADD_TWT_STATUS_NOT_READY; 486 case WMI_ADD_TWT_STATUS_NO_RESOURCE: 487 return WMI_HOST_ADD_TWT_STATUS_NO_RESOURCE; 488 case WMI_ADD_TWT_STATUS_NO_ACK: 489 return WMI_HOST_ADD_TWT_STATUS_NO_ACK; 490 case WMI_ADD_TWT_STATUS_NO_RESPONSE: 491 return WMI_HOST_ADD_TWT_STATUS_NO_RESPONSE; 492 case WMI_ADD_TWT_STATUS_DENIED: 493 return WMI_HOST_ADD_TWT_STATUS_DENIED; 494 case WMI_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE: 495 return WMI_HOST_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE; 496 case WMI_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED: 497 return WMI_HOST_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED; 498 case WMI_ADD_TWT_STATUS_ROAM_IN_PROGRESS: 499 return WMI_HOST_ADD_TWT_STATUS_ROAM_IN_PROGRESS; 500 case WMI_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS: 501 return WMI_HOST_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS; 502 case WMI_ADD_TWT_STATUS_SCAN_IN_PROGRESS: 503 return WMI_HOST_ADD_TWT_STATUS_SCAN_IN_PROGRESS; 504 default: 505 return WMI_HOST_ADD_TWT_STATUS_UNKNOWN_ERROR; 506 } 507 } 508 509 /** 510 * extract_twt_add_dialog_comp_event_tlv - Extacts twt add dialog complete wmi 511 * event from firmware 512 * @wmi_hande: WMI handle 513 * @evt_buf: Pointer to wmi event buf of twt add dialog complete event 514 * @params: Pointer to store the extracted parameters 515 * 516 * Return: QDF_STATUS_SUCCESS on success or QDF STATUS error values on failure 517 */ 518 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv( 519 wmi_unified_t wmi_handle, 520 uint8_t *evt_buf, 521 struct wmi_twt_add_dialog_complete_event_param *params) 522 { 523 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 524 wmi_twt_add_dialog_complete_event_fixed_param *ev; 525 526 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 527 if (!param_buf) { 528 wmi_err("evt_buf is NULL"); 529 return QDF_STATUS_E_INVAL; 530 } 531 532 ev = param_buf->fixed_param; 533 534 params->vdev_id = ev->vdev_id; 535 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 536 params->status = wmi_get_converted_twt_add_dialog_status(ev->status); 537 params->dialog_id = ev->dialog_id; 538 params->num_additional_twt_params = param_buf->num_twt_params; 539 540 return QDF_STATUS_SUCCESS; 541 } 542 543 /** 544 * extract_twt_add_dialog_comp_additional_parameters() - Extracts additional twt 545 * twt parameters, as part of add dialog completion event 546 * @wmi_hdl: wmi handle 547 * @evt_buf: Pointer event buffer 548 * @evt_buf_len: length of the add dialog event buffer 549 * @idx: index of num_twt_params 550 * @additional_params: twt additional parameters to extract 551 * 552 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL for failure 553 */ 554 static QDF_STATUS extract_twt_add_dialog_comp_additional_parameters 555 ( 556 wmi_unified_t wmi_handle, uint8_t *evt_buf, 557 uint32_t evt_buf_len, uint32_t idx, 558 struct wmi_twt_add_dialog_additional_params *additional_params 559 ) 560 { 561 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 562 wmi_twt_add_dialog_complete_event_fixed_param *ev; 563 uint32_t flags = 0; 564 uint32_t expected_len; 565 566 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 567 if (!param_buf) { 568 wmi_err("evt_buf is NULL"); 569 return QDF_STATUS_E_INVAL; 570 } 571 572 ev = param_buf->fixed_param; 573 574 if (idx >= param_buf->num_twt_params) { 575 wmi_err("Invalid idx %d while num_twt_params = %d", 576 idx, param_buf->num_twt_params); 577 return QDF_STATUS_E_INVAL; 578 } 579 580 if (!param_buf->twt_params) { 581 wmi_err("Unable to extract additional twt parameters"); 582 return QDF_STATUS_E_INVAL; 583 } 584 585 expected_len = (sizeof(wmi_twt_add_dialog_complete_event_fixed_param) + 586 WMI_TLV_HDR_SIZE + (param_buf->num_twt_params * 587 sizeof(wmi_twt_add_dialog_additional_params))); 588 589 if (evt_buf_len != expected_len) { 590 wmi_err("Got invalid len data from FW %d expected %d", 591 evt_buf_len, expected_len); 592 return QDF_STATUS_E_INVAL; 593 } 594 595 flags = param_buf->twt_params[idx].flags; 596 additional_params->twt_cmd = TWT_FLAGS_GET_CMD(flags); 597 additional_params->bcast = TWT_FLAGS_GET_BROADCAST(flags); 598 additional_params->trig_en = TWT_FLAGS_GET_TRIGGER(flags); 599 additional_params->announce = TWT_FLAGS_GET_FLOW_TYPE(flags); 600 additional_params->protection = TWT_FLAGS_GET_PROTECTION(flags); 601 additional_params->b_twt_id0 = TWT_FLAGS_GET_BTWT_ID0(flags); 602 additional_params->info_frame_disabled = 603 TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flags); 604 additional_params->wake_dur_us = param_buf->twt_params[idx].wake_dur_us; 605 additional_params->wake_intvl_us = 606 param_buf->twt_params[idx].wake_intvl_us; 607 additional_params->sp_offset_us = 608 param_buf->twt_params[idx].sp_offset_us; 609 additional_params->sp_tsf_us_lo = 610 param_buf->twt_params[idx].sp_tsf_us_lo; 611 additional_params->sp_tsf_us_hi = 612 param_buf->twt_params[idx].sp_tsf_us_hi; 613 614 return QDF_STATUS_SUCCESS; 615 } 616 617 static enum WMI_HOST_DEL_TWT_STATUS 618 wmi_get_converted_twt_del_dialog_status(WMI_DEL_TWT_STATUS_T tgt_status) 619 { 620 switch (tgt_status) { 621 case WMI_DEL_TWT_STATUS_OK: 622 return WMI_HOST_DEL_TWT_STATUS_OK; 623 case WMI_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST: 624 return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST; 625 case WMI_DEL_TWT_STATUS_INVALID_PARAM: 626 return WMI_HOST_DEL_TWT_STATUS_INVALID_PARAM; 627 case WMI_DEL_TWT_STATUS_DIALOG_ID_BUSY: 628 return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_BUSY; 629 case WMI_DEL_TWT_STATUS_NO_RESOURCE: 630 return WMI_HOST_DEL_TWT_STATUS_NO_RESOURCE; 631 case WMI_DEL_TWT_STATUS_NO_ACK: 632 return WMI_HOST_DEL_TWT_STATUS_NO_ACK; 633 case WMI_DEL_TWT_STATUS_UNKNOWN_ERROR: 634 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 635 case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN: 636 return WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN; 637 case WMI_DEL_TWT_STATUS_ROAMING: 638 return WMI_HOST_DEL_TWT_STATUS_ROAMING; 639 case WMI_DEL_TWT_STATUS_CONCURRENCY: 640 return WMI_HOST_DEL_TWT_STATUS_CONCURRENCY; 641 case WMI_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS: 642 return WMI_HOST_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS; 643 case WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS: 644 return WMI_HOST_DEL_TWT_STATUS_SCAN_IN_PROGRESS; 645 default: 646 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 647 } 648 649 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 650 } 651 652 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv( 653 wmi_unified_t wmi_handle, 654 uint8_t *evt_buf, 655 struct wmi_twt_del_dialog_complete_event_param *params) 656 { 657 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 658 wmi_twt_del_dialog_complete_event_fixed_param *ev; 659 660 param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 661 if (!param_buf) { 662 wmi_err("evt_buf is NULL"); 663 return QDF_STATUS_E_INVAL; 664 } 665 666 ev = param_buf->fixed_param; 667 668 params->vdev_id = ev->vdev_id; 669 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 670 params->dialog_id = ev->dialog_id; 671 params->status = wmi_get_converted_twt_del_dialog_status(ev->status); 672 673 return QDF_STATUS_SUCCESS; 674 } 675 676 static enum WMI_HOST_PAUSE_TWT_STATUS 677 wmi_twt_pause_status_to_host_twt_status(WMI_PAUSE_TWT_STATUS_T status) 678 { 679 switch (status) { 680 case WMI_PAUSE_TWT_STATUS_OK: 681 return WMI_HOST_PAUSE_TWT_STATUS_OK; 682 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 683 return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST; 684 case WMI_PAUSE_TWT_STATUS_INVALID_PARAM: 685 return WMI_HOST_PAUSE_TWT_STATUS_INVALID_PARAM; 686 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_BUSY: 687 return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_BUSY; 688 case WMI_PAUSE_TWT_STATUS_NO_RESOURCE: 689 return WMI_HOST_PAUSE_TWT_STATUS_NO_RESOURCE; 690 case WMI_PAUSE_TWT_STATUS_NO_ACK: 691 return WMI_HOST_PAUSE_TWT_STATUS_NO_ACK; 692 case WMI_PAUSE_TWT_STATUS_UNKNOWN_ERROR: 693 return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR; 694 case WMI_PAUSE_TWT_STATUS_ALREADY_PAUSED: 695 return WMI_HOST_PAUSE_TWT_STATUS_ALREADY_PAUSED; 696 case WMI_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 697 return WMI_HOST_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS; 698 case WMI_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS: 699 return WMI_HOST_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS; 700 case WMI_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS: 701 return WMI_HOST_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS; 702 default: 703 return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR; 704 } 705 } 706 707 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv( 708 wmi_unified_t wmi_handle, 709 uint8_t *evt_buf, 710 struct wmi_twt_pause_dialog_complete_event_param *params) 711 { 712 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 713 wmi_twt_pause_dialog_complete_event_fixed_param *ev; 714 715 param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 716 if (!param_buf) { 717 wmi_err("evt_buf is NULL"); 718 return QDF_STATUS_E_INVAL; 719 } 720 721 ev = param_buf->fixed_param; 722 723 params->vdev_id = ev->vdev_id; 724 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 725 params->status = wmi_twt_pause_status_to_host_twt_status(ev->status); 726 params->dialog_id = ev->dialog_id; 727 728 return QDF_STATUS_SUCCESS; 729 } 730 731 static enum WMI_HOST_NUDGE_TWT_STATUS 732 wmi_twt_nudge_status_to_host_twt_status(WMI_TWT_NUDGE_STATUS_T status) 733 { 734 switch (status) { 735 case WMI_NUDGE_TWT_STATUS_OK: 736 return WMI_HOST_NUDGE_TWT_STATUS_OK; 737 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 738 return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST; 739 case WMI_NUDGE_TWT_STATUS_INVALID_PARAM: 740 return WMI_HOST_NUDGE_TWT_STATUS_INVALID_PARAM; 741 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_BUSY: 742 return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_BUSY; 743 case WMI_NUDGE_TWT_STATUS_NO_RESOURCE: 744 return WMI_HOST_NUDGE_TWT_STATUS_NO_RESOURCE; 745 case WMI_NUDGE_TWT_STATUS_NO_ACK: 746 return WMI_HOST_NUDGE_TWT_STATUS_NO_ACK; 747 case WMI_NUDGE_TWT_STATUS_UNKNOWN_ERROR: 748 return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR; 749 case WMI_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 750 return WMI_HOST_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS; 751 case WMI_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS: 752 return WMI_HOST_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS; 753 case WMI_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS: 754 return WMI_HOST_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS; 755 default: 756 return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR; 757 } 758 } 759 760 static QDF_STATUS extract_twt_nudge_dialog_comp_event_tlv( 761 wmi_unified_t wmi_handle, 762 uint8_t *evt_buf, 763 struct wmi_twt_nudge_dialog_complete_event_param *params) 764 { 765 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 766 wmi_twt_nudge_dialog_complete_event_fixed_param *ev; 767 768 param_buf = (WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 769 if (!param_buf) { 770 wmi_err("evt_buf is NULL"); 771 return QDF_STATUS_E_INVAL; 772 } 773 774 ev = param_buf->fixed_param; 775 776 params->vdev_id = ev->vdev_id; 777 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 778 params->status = wmi_twt_nudge_status_to_host_twt_status(ev->status); 779 params->dialog_id = ev->dialog_id; 780 params->next_twt_tsf_us_lo = ev->sp_tsf_us_lo; 781 params->next_twt_tsf_us_hi = ev->sp_tsf_us_hi; 782 783 wmi_debug("vdev_id: %d dialog_id: %d tsf hi : %x tsf lo: %x", 784 params->vdev_id, params->dialog_id, 785 params->next_twt_tsf_us_hi, params->next_twt_tsf_us_lo); 786 787 return QDF_STATUS_SUCCESS; 788 } 789 790 static enum WMI_HOST_RESUME_TWT_STATUS 791 wmi_get_converted_twt_resume_dialog_status(WMI_RESUME_TWT_STATUS_T tgt_status) 792 { 793 switch (tgt_status) { 794 case WMI_RESUME_TWT_STATUS_OK: 795 return WMI_HOST_RESUME_TWT_STATUS_OK; 796 case WMI_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST: 797 return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST; 798 case WMI_RESUME_TWT_STATUS_INVALID_PARAM: 799 return WMI_HOST_RESUME_TWT_STATUS_INVALID_PARAM; 800 case WMI_RESUME_TWT_STATUS_DIALOG_ID_BUSY: 801 return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_BUSY; 802 case WMI_RESUME_TWT_STATUS_NOT_PAUSED: 803 return WMI_HOST_RESUME_TWT_STATUS_NOT_PAUSED; 804 case WMI_RESUME_TWT_STATUS_NO_RESOURCE: 805 return WMI_HOST_RESUME_TWT_STATUS_NO_RESOURCE; 806 case WMI_RESUME_TWT_STATUS_NO_ACK: 807 return WMI_HOST_RESUME_TWT_STATUS_NO_ACK; 808 case WMI_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS: 809 return WMI_HOST_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS; 810 case WMI_RESUME_TWT_STATUS_ROAM_IN_PROGRESS: 811 return WMI_HOST_RESUME_TWT_STATUS_ROAM_IN_PROGRESS; 812 case WMI_RESUME_TWT_STATUS_SCAN_IN_PROGRESS: 813 return WMI_HOST_RESUME_TWT_STATUS_SCAN_IN_PROGRESS; 814 default: 815 return WMI_HOST_RESUME_TWT_STATUS_UNKNOWN_ERROR; 816 } 817 } 818 819 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv( 820 wmi_unified_t wmi_handle, 821 uint8_t *evt_buf, 822 struct wmi_twt_resume_dialog_complete_event_param *params) 823 { 824 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 825 wmi_twt_resume_dialog_complete_event_fixed_param *ev; 826 827 param_buf = 828 (WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 829 if (!param_buf) { 830 wmi_err("evt_buf is NULL"); 831 return QDF_STATUS_E_INVAL; 832 } 833 834 ev = param_buf->fixed_param; 835 836 params->vdev_id = ev->vdev_id; 837 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 838 params->status = wmi_get_converted_twt_resume_dialog_status(ev->status); 839 params->dialog_id = ev->dialog_id; 840 841 return QDF_STATUS_SUCCESS; 842 } 843 844 static QDF_STATUS extract_twt_notify_event_tlv( 845 wmi_unified_t wmi_handle, 846 uint8_t *evt_buf, 847 struct wmi_twt_notify_event_param *params) 848 { 849 WMI_TWT_NOTIFY_EVENTID_param_tlvs *param_buf; 850 wmi_twt_notify_event_fixed_param *ev; 851 852 param_buf = 853 (WMI_TWT_NOTIFY_EVENTID_param_tlvs *)evt_buf; 854 if (!param_buf) { 855 wmi_err("evt_buf is NULL"); 856 return QDF_STATUS_E_INVAL; 857 } 858 859 ev = param_buf->fixed_param; 860 861 params->vdev_id = ev->vdev_id; 862 863 return QDF_STATUS_SUCCESS; 864 } 865 866 #ifdef WLAN_SUPPORT_BCAST_TWT 867 static QDF_STATUS 868 extract_twt_btwt_invite_sta_comp_event_tlv( 869 wmi_unified_t wmi_handle, 870 uint8_t *evt_buf, 871 struct 872 wmi_twt_btwt_invite_sta_complete_event_param 873 *params) 874 { 875 WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 876 wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev; 877 878 param_buf = 879 (WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 880 if (!param_buf) { 881 wmi_err("evt_buf is NULL"); 882 return QDF_STATUS_E_INVAL; 883 } 884 885 ev = param_buf->fixed_param; 886 887 params->vdev_id = ev->vdev_id; 888 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 889 params->status = ev->status; 890 params->dialog_id = ev->dialog_id; 891 892 return QDF_STATUS_SUCCESS; 893 } 894 895 static QDF_STATUS 896 extract_twt_btwt_remove_sta_comp_event_tlv( 897 wmi_unified_t wmi_handle, 898 uint8_t *evt_buf, 899 struct 900 wmi_twt_btwt_remove_sta_complete_event_param 901 *params) 902 { 903 WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 904 wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev; 905 906 param_buf = 907 (WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 908 if (!param_buf) { 909 wmi_err("evt_buf is NULL"); 910 return QDF_STATUS_E_INVAL; 911 } 912 913 ev = param_buf->fixed_param; 914 915 params->vdev_id = ev->vdev_id; 916 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 917 params->status = ev->status; 918 params->dialog_id = ev->dialog_id; 919 920 return QDF_STATUS_SUCCESS; 921 } 922 #endif 923 924 #ifdef WLAN_SUPPORT_BCAST_TWT 925 static void 926 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 927 { 928 ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv; 929 ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv; 930 ops->extract_twt_btwt_invite_sta_comp_event = 931 extract_twt_btwt_invite_sta_comp_event_tlv; 932 ops->extract_twt_btwt_remove_sta_comp_event = 933 extract_twt_btwt_remove_sta_comp_event_tlv; 934 935 return; 936 } 937 #else 938 static void 939 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 940 { 941 return; 942 } 943 #endif 944 945 static QDF_STATUS 946 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle, 947 uint8_t *evt_buf, 948 struct wmi_twt_session_stats_event_param 949 *params) 950 { 951 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 952 wmi_pdev_twt_session_stats_event_fixed_param *ev; 953 954 param_buf = 955 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 956 if (!param_buf) { 957 wmi_err("evt_buf is NULL"); 958 return QDF_STATUS_E_INVAL; 959 } 960 961 ev = param_buf->fixed_param; 962 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 963 wmi_handle, 964 ev->pdev_id); 965 params->num_sessions = param_buf->num_twt_sessions; 966 967 wmi_debug("pdev_id=%d, num of TWT sessions=%d", 968 params->pdev_id, params->num_sessions); 969 970 return QDF_STATUS_SUCCESS; 971 } 972 973 static QDF_STATUS 974 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, 975 uint8_t *evt_buf, 976 struct wmi_twt_session_stats_event_param 977 *params, 978 struct wmi_host_twt_session_stats_info 979 *session, 980 uint32_t idx) 981 { 982 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 983 wmi_twt_session_stats_info *twt_session; 984 uint32_t flags; 985 wmi_mac_addr *m1; 986 uint8_t *m2; 987 988 param_buf = 989 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 990 if (!param_buf) { 991 wmi_err("evt_buf is NULL"); 992 return QDF_STATUS_E_INVAL; 993 } 994 995 if (idx >= param_buf->num_twt_sessions) { 996 wmi_err("wrong idx, idx=%d, num_sessions=%d", 997 idx, param_buf->num_twt_sessions); 998 return QDF_STATUS_E_INVAL; 999 } 1000 1001 twt_session = ¶m_buf->twt_sessions[idx]; 1002 1003 session->vdev_id = twt_session->vdev_id; 1004 m1 = &twt_session->peer_mac; 1005 m2 = session->peer_mac; 1006 WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2); 1007 session->event_type = twt_session->event_type; 1008 flags = twt_session->flow_id_flags; 1009 session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags); 1010 session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags); 1011 session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags); 1012 session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags); 1013 session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags); 1014 session->info_frame_disabled = 1015 WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags); 1016 session->dialog_id = twt_session->dialog_id; 1017 session->wake_dura_us = twt_session->wake_dura_us; 1018 session->wake_intvl_us = twt_session->wake_intvl_us; 1019 session->sp_offset_us = twt_session->sp_offset_us; 1020 session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo; 1021 session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi; 1022 wmi_debug("type=%d id=%d bcast=%d trig=%d announ=%d diagid=%d wake_dur=%ul wake_int=%ul offset=%ul", 1023 session->event_type, session->flow_id, 1024 session->bcast, session->trig, 1025 session->announ, session->dialog_id, session->wake_dura_us, 1026 session->wake_intvl_us, session->sp_offset_us); 1027 1028 return QDF_STATUS_SUCCESS; 1029 } 1030 1031 static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( 1032 wmi_unified_t wmi_handle, uint8_t *event, 1033 struct wmi_twt_cap_bitmap_params *var) 1034 { 1035 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 1036 wmi_twt_caps_params *twt_caps; 1037 1038 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 1039 if (!param_buf) 1040 return QDF_STATUS_E_INVAL; 1041 1042 twt_caps = param_buf->twt_caps; 1043 if (!twt_caps) 1044 return QDF_STATUS_E_INVAL; 1045 1046 var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap, 1047 0, 1); 1048 1049 return QDF_STATUS_SUCCESS; 1050 } 1051 1052 static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT 1053 wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd) 1054 { 1055 switch (tgt_cmd) { 1056 case WMI_TWT_ADD_DIALOG_CMDID: 1057 return WMI_HOST_TWT_ADD_DIALOG_CMDID; 1058 case WMI_TWT_DEL_DIALOG_CMDID: 1059 return WMI_HOST_TWT_DEL_DIALOG_CMDID; 1060 case WMI_TWT_PAUSE_DIALOG_CMDID: 1061 return WMI_HOST_TWT_PAUSE_DIALOG_CMDID; 1062 case WMI_TWT_RESUME_DIALOG_CMDID: 1063 return WMI_HOST_TWT_RESUME_DIALOG_CMDID; 1064 case WMI_TWT_NUDGE_DIALOG_CMDID: 1065 return WMI_HOST_TWT_NUDGE_DIALOG_CMDID; 1066 default: 1067 return WMI_HOST_TWT_UNKNOWN_CMDID; 1068 } 1069 } 1070 1071 static QDF_STATUS 1072 extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle, 1073 uint8_t *evt_buf, 1074 struct wmi_twt_ack_complete_event_param *var) 1075 { 1076 WMI_TWT_ACK_EVENTID_param_tlvs *param_buf; 1077 wmi_twt_ack_event_fixed_param *ack_event; 1078 1079 param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf; 1080 if (!param_buf) { 1081 wmi_err("evt_buf is NULL"); 1082 return QDF_STATUS_E_INVAL; 1083 } 1084 1085 ack_event = param_buf->fixed_param; 1086 1087 var->vdev_id = ack_event->vdev_id; 1088 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr, 1089 var->peer_macaddr.bytes); 1090 var->dialog_id = ack_event->dialog_id; 1091 var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event( 1092 ack_event->twt_cmd); 1093 1094 switch (ack_event->twt_cmd) { 1095 case WMI_TWT_ADD_DIALOG_CMDID: 1096 var->status = wmi_get_converted_twt_add_dialog_status( 1097 ack_event->status); 1098 break; 1099 case WMI_TWT_DEL_DIALOG_CMDID: 1100 var->status = wmi_get_converted_twt_del_dialog_status( 1101 ack_event->status); 1102 break; 1103 case WMI_TWT_PAUSE_DIALOG_CMDID: 1104 var->status = wmi_twt_pause_status_to_host_twt_status( 1105 ack_event->status); 1106 break; 1107 case WMI_TWT_RESUME_DIALOG_CMDID: 1108 var->status = wmi_get_converted_twt_resume_dialog_status( 1109 ack_event->status); 1110 break; 1111 case WMI_TWT_NUDGE_DIALOG_CMDID: 1112 var->status = wmi_twt_nudge_status_to_host_twt_status( 1113 ack_event->status); 1114 break; 1115 default: 1116 break; 1117 } 1118 return QDF_STATUS_SUCCESS; 1119 } 1120 1121 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) 1122 { 1123 struct wmi_ops *ops = wmi_handle->ops; 1124 1125 ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv; 1126 ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv; 1127 ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv; 1128 ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv; 1129 ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv; 1130 ops->send_twt_nudge_dialog_cmd = send_twt_nudge_dialog_cmd_tlv; 1131 ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv; 1132 ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv; 1133 ops->extract_twt_disable_comp_event = 1134 extract_twt_disable_comp_event_tlv; 1135 ops->extract_twt_add_dialog_comp_event = 1136 extract_twt_add_dialog_comp_event_tlv; 1137 ops->extract_twt_add_dialog_comp_additional_params = 1138 extract_twt_add_dialog_comp_additional_parameters; 1139 ops->extract_twt_del_dialog_comp_event = 1140 extract_twt_del_dialog_comp_event_tlv; 1141 ops->extract_twt_pause_dialog_comp_event = 1142 extract_twt_pause_dialog_comp_event_tlv; 1143 ops->extract_twt_nudge_dialog_comp_event = 1144 extract_twt_nudge_dialog_comp_event_tlv; 1145 ops->extract_twt_resume_dialog_comp_event = 1146 extract_twt_resume_dialog_comp_event_tlv; 1147 ops->extract_twt_session_stats_event = 1148 extract_twt_session_stats_event_tlv; 1149 ops->extract_twt_session_stats_data = 1150 extract_twt_session_stats_event_data; 1151 ops->extract_twt_notify_event = 1152 extract_twt_notify_event_tlv; 1153 ops->extract_twt_cap_service_ready_ext2 = 1154 extract_twt_cap_service_ready_ext2_tlv, 1155 ops->extract_twt_ack_comp_event = extract_twt_ack_comp_event_tlv; 1156 wmi_twt_attach_bcast_twt_tlv(ops); 1157 } 1158