1 /* 2 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <osdep.h> 21 #include "wmi.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_unified_twt_param.h" 24 #include "wmi_unified_twt_api.h" 25 26 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED) 27 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle, 28 struct twt_enable_param *params) 29 { 30 wmi_twt_enable_cmd_fixed_param *cmd; 31 wmi_buf_t buf; 32 QDF_STATUS status; 33 34 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 35 if (!buf) { 36 wmi_err("Failed to allocate memory"); 37 return QDF_STATUS_E_FAILURE; 38 } 39 40 cmd = (wmi_twt_enable_cmd_fixed_param *)wmi_buf_data(buf); 41 WMITLV_SET_HDR(&cmd->tlv_header, 42 WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param, 43 WMITLV_GET_STRUCT_TLVLEN 44 (wmi_twt_enable_cmd_fixed_param)); 45 46 cmd->pdev_id = 47 wmi_handle->ops->convert_pdev_id_host_to_target( 48 wmi_handle, 49 params->pdev_id); 50 cmd->sta_cong_timer_ms = params->sta_cong_timer_ms; 51 cmd->mbss_support = params->mbss_support; 52 cmd->default_slot_size = params->default_slot_size; 53 cmd->congestion_thresh_setup = params->congestion_thresh_setup; 54 cmd->congestion_thresh_teardown = params->congestion_thresh_teardown; 55 cmd->congestion_thresh_critical = params->congestion_thresh_critical; 56 cmd->interference_thresh_teardown = 57 params->interference_thresh_teardown; 58 cmd->interference_thresh_setup = params->interference_thresh_setup; 59 cmd->min_no_sta_setup = params->min_no_sta_setup; 60 cmd->min_no_sta_teardown = params->min_no_sta_teardown; 61 cmd->no_of_bcast_mcast_slots = params->no_of_bcast_mcast_slots; 62 cmd->min_no_twt_slots = params->min_no_twt_slots; 63 cmd->max_no_sta_twt = params->max_no_sta_twt; 64 cmd->mode_check_interval = params->mode_check_interval; 65 cmd->add_sta_slot_interval = params->add_sta_slot_interval; 66 cmd->remove_sta_slot_interval = params->remove_sta_slot_interval; 67 68 TWT_EN_DIS_FLAGS_SET_BTWT(cmd->flags, params->b_twt_enable); 69 TWT_EN_DIS_FLAGS_SET_L_MBSSID(cmd->flags, 70 params->b_twt_legacy_mbss_enable); 71 TWT_EN_DIS_FLAGS_SET_AX_MBSSID(cmd->flags, 72 params->b_twt_ax_mbss_enable); 73 if (params->ext_conf_present) { 74 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 75 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 76 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 77 } 78 79 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 80 WMI_TWT_ENABLE_CMDID); 81 if (QDF_IS_STATUS_ERROR(status)) { 82 wmi_err("Failed to send WMI_TWT_ENABLE_CMDID"); 83 wmi_buf_free(buf); 84 } 85 86 return status; 87 } 88 89 static WMI_DISABLE_TWT_REASON_T 90 wmi_convert_dis_reason_code(enum HOST_TWT_DISABLE_REASON reason) 91 { 92 switch (reason) { 93 case HOST_TWT_DISABLE_REASON_NONE: 94 return WMI_DISABLE_TWT_REASON_NONE; 95 case HOST_TWT_DISABLE_REASON_CONCURRENCY_SCC: 96 return WMI_DISABLE_TWT_REASON_CONCURRENCY_SCC; 97 case HOST_TWT_DISABLE_REASON_CONCURRENCY_MCC: 98 return WMI_DISABLE_TWT_REASON_CONCURRENCY_MCC; 99 case HOST_TWT_DISABLE_REASON_CHANGE_CONGESTION_TIMEOUT: 100 return WMI_DISABLE_TWT_REASON_CHANGE_CONGESTION_TIMEOUT; 101 case HOST_TWT_DISABLE_REASON_P2P_GO_NOA: 102 return WMI_DISABLE_TWT_REASON_P2P_GO_NOA; 103 default: 104 return WMI_DISABLE_TWT_REASON_NONE; 105 } 106 } 107 108 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle, 109 struct twt_disable_param *params) 110 { 111 wmi_twt_disable_cmd_fixed_param *cmd; 112 wmi_buf_t buf; 113 QDF_STATUS status; 114 115 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 116 if (!buf) { 117 wmi_err("Failed to allocate memory"); 118 return QDF_STATUS_E_FAILURE; 119 } 120 121 cmd = (wmi_twt_disable_cmd_fixed_param *)wmi_buf_data(buf); 122 WMITLV_SET_HDR(&cmd->tlv_header, 123 WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param, 124 WMITLV_GET_STRUCT_TLVLEN 125 (wmi_twt_disable_cmd_fixed_param)); 126 127 cmd->pdev_id = 128 wmi_handle->ops->convert_pdev_id_host_to_target( 129 wmi_handle, 130 params->pdev_id); 131 if (params->ext_conf_present) { 132 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 133 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 134 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 135 } 136 137 cmd->reason_code = wmi_convert_dis_reason_code( 138 params->dis_reason_code); 139 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 140 WMI_TWT_DISABLE_CMDID); 141 if (QDF_IS_STATUS_ERROR(status)) { 142 wmi_err("Failed to send WMI_TWT_DISABLE_CMDID"); 143 wmi_buf_free(buf); 144 } 145 146 return status; 147 } 148 149 #ifdef WLAN_SUPPORT_BCAST_TWT 150 static void 151 twt_add_dialog_set_bcast_twt_params(struct twt_add_dialog_param *params, 152 wmi_twt_add_dialog_cmd_fixed_param *cmd) 153 { 154 TWT_FLAGS_SET_BTWT_ID0(cmd->flags, params->flag_b_twt_id0); 155 cmd->b_twt_persistence = params->b_twt_persistence; 156 cmd->b_twt_recommendation = params->b_twt_recommendation; 157 } 158 #else 159 static void 160 twt_add_dialog_set_bcast_twt_params(struct twt_add_dialog_param *params, 161 wmi_twt_add_dialog_cmd_fixed_param *cmd) 162 { 163 } 164 #endif 165 166 static QDF_STATUS 167 send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle, 168 struct twt_add_dialog_param *params) 169 { 170 wmi_twt_add_dialog_cmd_fixed_param *cmd; 171 wmi_buf_t buf; 172 QDF_STATUS status; 173 174 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 175 if (!buf) { 176 wmi_err("Failed to allocate memory"); 177 return QDF_STATUS_E_FAILURE; 178 } 179 180 cmd = (wmi_twt_add_dialog_cmd_fixed_param *)wmi_buf_data(buf); 181 WMITLV_SET_HDR(&cmd->tlv_header, 182 WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param, 183 WMITLV_GET_STRUCT_TLVLEN 184 (wmi_twt_add_dialog_cmd_fixed_param)); 185 186 cmd->vdev_id = params->vdev_id; 187 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 188 &cmd->peer_macaddr); 189 cmd->dialog_id = params->dialog_id; 190 cmd->wake_intvl_us = params->wake_intvl_us; 191 cmd->wake_intvl_mantis = params->wake_intvl_mantis; 192 cmd->wake_dura_us = params->wake_dura_us; 193 cmd->sp_offset_us = params->sp_offset_us; 194 cmd->min_wake_intvl_us = params->min_wake_intvl_us; 195 cmd->max_wake_intvl_us = params->max_wake_intvl_us; 196 cmd->min_wake_dura_us = params->min_wake_dura_us; 197 cmd->max_wake_dura_us = params->max_wake_dura_us; 198 cmd->sp_start_tsf_lo = (uint32_t)(params->wake_time_tsf & 0xFFFFFFFF); 199 cmd->sp_start_tsf_hi = (uint32_t)(params->wake_time_tsf >> 32); 200 cmd->announce_timeout_us = params->announce_timeout_us; 201 TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd); 202 TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast); 203 TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger); 204 TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type); 205 TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection); 206 207 twt_add_dialog_set_bcast_twt_params(params, cmd); 208 209 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 210 WMI_TWT_ADD_DIALOG_CMDID); 211 if (QDF_IS_STATUS_ERROR(status)) { 212 wmi_err("Failed to send WMI_TWT_ADD_DIALOG_CMDID"); 213 wmi_buf_free(buf); 214 } 215 216 return status; 217 } 218 219 #ifdef WLAN_SUPPORT_BCAST_TWT 220 static void 221 twt_del_dialog_set_bcast_twt_params(struct twt_del_dialog_param *params, 222 wmi_twt_del_dialog_cmd_fixed_param *cmd) 223 { 224 cmd->b_twt_persistence = params->b_twt_persistence; 225 } 226 #else 227 static void 228 twt_del_dialog_set_bcast_twt_params(struct twt_del_dialog_param *params, 229 wmi_twt_del_dialog_cmd_fixed_param *cmd) 230 { 231 } 232 #endif 233 234 static QDF_STATUS 235 send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle, 236 struct twt_del_dialog_param *params) 237 { 238 wmi_twt_del_dialog_cmd_fixed_param *cmd; 239 wmi_buf_t buf; 240 QDF_STATUS status; 241 242 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 243 if (!buf) { 244 wmi_err("Failed to allocate memory"); 245 return QDF_STATUS_E_FAILURE; 246 } 247 248 cmd = (wmi_twt_del_dialog_cmd_fixed_param *)wmi_buf_data(buf); 249 WMITLV_SET_HDR(&cmd->tlv_header, 250 WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param, 251 WMITLV_GET_STRUCT_TLVLEN 252 (wmi_twt_del_dialog_cmd_fixed_param)); 253 254 cmd->vdev_id = params->vdev_id; 255 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 256 &cmd->peer_macaddr); 257 cmd->dialog_id = params->dialog_id; 258 259 twt_del_dialog_set_bcast_twt_params(params, cmd); 260 261 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 262 WMI_TWT_DEL_DIALOG_CMDID); 263 if (QDF_IS_STATUS_ERROR(status)) { 264 wmi_err("Failed to send WMI_TWT_DEL_DIALOG_CMDID"); 265 wmi_buf_free(buf); 266 } 267 268 return status; 269 } 270 271 static QDF_STATUS 272 send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle, 273 struct twt_pause_dialog_cmd_param *params) 274 { 275 wmi_twt_pause_dialog_cmd_fixed_param *cmd; 276 wmi_buf_t buf; 277 QDF_STATUS status; 278 279 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 280 if (!buf) { 281 wmi_err("Failed to allocate memory"); 282 return QDF_STATUS_E_FAILURE; 283 } 284 285 cmd = (wmi_twt_pause_dialog_cmd_fixed_param *)wmi_buf_data(buf); 286 WMITLV_SET_HDR(&cmd->tlv_header, 287 WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param, 288 WMITLV_GET_STRUCT_TLVLEN 289 (wmi_twt_pause_dialog_cmd_fixed_param)); 290 291 cmd->vdev_id = params->vdev_id; 292 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 293 &cmd->peer_macaddr); 294 cmd->dialog_id = params->dialog_id; 295 296 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 297 WMI_TWT_PAUSE_DIALOG_CMDID); 298 if (QDF_IS_STATUS_ERROR(status)) { 299 wmi_err("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID"); 300 wmi_buf_free(buf); 301 } 302 303 return status; 304 } 305 306 static QDF_STATUS 307 send_twt_nudge_dialog_cmd_tlv(wmi_unified_t wmi_handle, 308 struct twt_nudge_dialog_cmd_param *params) 309 { 310 wmi_twt_nudge_dialog_cmd_fixed_param *cmd; 311 wmi_buf_t buf; 312 QDF_STATUS status; 313 314 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 315 if (!buf) 316 return QDF_STATUS_E_FAILURE; 317 318 cmd = (wmi_twt_nudge_dialog_cmd_fixed_param *)wmi_buf_data(buf); 319 WMITLV_SET_HDR(&cmd->tlv_header, 320 WMITLV_TAG_STRUC_wmi_twt_nudge_dialog_cmd_fixed_param, 321 WMITLV_GET_STRUCT_TLVLEN 322 (wmi_twt_nudge_dialog_cmd_fixed_param)); 323 324 cmd->vdev_id = params->vdev_id; 325 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 326 &cmd->peer_macaddr); 327 cmd->dialog_id = params->dialog_id; 328 cmd->suspend_duration_ms = params->suspend_duration / 1000; 329 cmd->next_twt_size = params->next_twt_size; 330 331 wmi_debug("vdev_id: %d dialog_id: %d duration(in ms): %u next_twt_size: %d " 332 "peer_macaddr: "QDF_MAC_ADDR_FMT, cmd->vdev_id, 333 cmd->dialog_id, cmd->suspend_duration_ms, cmd->next_twt_size, 334 QDF_MAC_ADDR_REF(params->peer_macaddr.bytes)); 335 336 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 337 WMI_TWT_NUDGE_DIALOG_CMDID); 338 if (QDF_IS_STATUS_ERROR(status)) 339 wmi_buf_free(buf); 340 341 return status; 342 } 343 344 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle, 345 struct twt_resume_dialog_cmd_param *params) 346 { 347 wmi_twt_resume_dialog_cmd_fixed_param *cmd; 348 wmi_buf_t buf; 349 QDF_STATUS status; 350 351 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 352 if (!buf) { 353 wmi_err("Failed to allocate memory"); 354 return QDF_STATUS_E_FAILURE; 355 } 356 357 cmd = (wmi_twt_resume_dialog_cmd_fixed_param *)wmi_buf_data(buf); 358 WMITLV_SET_HDR(&cmd->tlv_header, 359 WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param, 360 WMITLV_GET_STRUCT_TLVLEN 361 (wmi_twt_resume_dialog_cmd_fixed_param)); 362 363 cmd->vdev_id = params->vdev_id; 364 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 365 &cmd->peer_macaddr); 366 cmd->dialog_id = params->dialog_id; 367 cmd->sp_offset_us = params->sp_offset_us; 368 cmd->next_twt_size = params->next_twt_size; 369 370 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 371 WMI_TWT_RESUME_DIALOG_CMDID); 372 if (QDF_IS_STATUS_ERROR(status)) { 373 wmi_err("Failed to send WMI_TWT_RESUME_DIALOG_CMDID"); 374 wmi_buf_free(buf); 375 } 376 377 return status; 378 } 379 380 #ifdef WLAN_SUPPORT_BCAST_TWT 381 static QDF_STATUS 382 send_twt_btwt_invite_sta_cmd_tlv(wmi_unified_t wmi_handle, 383 struct twt_btwt_invite_sta_cmd_param *params) 384 { 385 wmi_twt_btwt_invite_sta_cmd_fixed_param *cmd; 386 wmi_buf_t buf; 387 QDF_STATUS status; 388 389 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 390 if (!buf) { 391 wmi_err("Failed to allocate memory"); 392 return QDF_STATUS_E_FAILURE; 393 } 394 395 cmd = (wmi_twt_btwt_invite_sta_cmd_fixed_param *)wmi_buf_data(buf); 396 WMITLV_SET_HDR(&cmd->tlv_header, 397 WMITLV_TAG_STRUC_wmi_twt_btwt_invite_sta_cmd_fixed_param, 398 WMITLV_GET_STRUCT_TLVLEN 399 (wmi_twt_btwt_invite_sta_cmd_fixed_param)); 400 401 cmd->vdev_id = params->vdev_id; 402 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 403 &cmd->peer_macaddr); 404 cmd->dialog_id = params->dialog_id; 405 406 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 407 WMI_TWT_BTWT_INVITE_STA_CMDID); 408 if (QDF_IS_STATUS_ERROR(status)) { 409 wmi_buf_free(buf); 410 wmi_err("Failed to send WMI_TWT_BTWT_INVITE_STA_CMDID"); 411 } 412 413 return status; 414 } 415 416 static QDF_STATUS 417 send_twt_btwt_remove_sta_cmd_tlv(wmi_unified_t wmi_handle, 418 struct twt_btwt_remove_sta_cmd_param 419 *params) 420 { 421 wmi_twt_btwt_remove_sta_cmd_fixed_param *cmd; 422 wmi_buf_t buf; 423 QDF_STATUS status; 424 425 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 426 if (!buf) { 427 wmi_err("Failed to allocate memory"); 428 return QDF_STATUS_E_FAILURE; 429 } 430 431 cmd = (wmi_twt_btwt_remove_sta_cmd_fixed_param *)wmi_buf_data(buf); 432 WMITLV_SET_HDR(&cmd->tlv_header, 433 WMITLV_TAG_STRUC_wmi_twt_btwt_remove_sta_cmd_fixed_param, 434 WMITLV_GET_STRUCT_TLVLEN 435 (wmi_twt_btwt_remove_sta_cmd_fixed_param)); 436 437 cmd->vdev_id = params->vdev_id; 438 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr.bytes, 439 &cmd->peer_macaddr); 440 cmd->dialog_id = params->dialog_id; 441 442 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 443 WMI_TWT_BTWT_REMOVE_STA_CMDID); 444 if (QDF_IS_STATUS_ERROR(status)) { 445 wmi_buf_free(buf); 446 wmi_err("Failed to send WMI_TWT_BTWT_REMOVE_STA_CMDID"); 447 } 448 449 return status; 450 } 451 #endif 452 453 static enum HOST_TWT_ENABLE_STATUS 454 wmi_twt_enable_status_to_host_twt_status(WMI_ENABLE_TWT_STATUS_T status) 455 { 456 switch (status) { 457 case WMI_ENABLE_TWT_STATUS_OK: 458 return HOST_TWT_ENABLE_STATUS_OK; 459 case WMI_ENABLE_TWT_STATUS_ALREADY_ENABLED: 460 return HOST_TWT_ENABLE_STATUS_ALREADY_ENABLED; 461 case WMI_ENABLE_TWT_STATUS_NOT_READY: 462 return HOST_TWT_ENABLE_STATUS_NOT_READY; 463 case WMI_ENABLE_TWT_INVALID_PARAM: 464 return HOST_TWT_ENABLE_INVALID_PARAM; 465 default: 466 return HOST_TWT_ENABLE_STATUS_UNKNOWN_ERROR; 467 } 468 } 469 470 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle, 471 uint8_t *evt_buf, 472 struct twt_enable_complete_event_param *params) 473 { 474 WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 475 wmi_twt_enable_complete_event_fixed_param *ev; 476 477 param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 478 if (!param_buf) { 479 wmi_err("evt_buf is NULL"); 480 return QDF_STATUS_E_INVAL; 481 } 482 483 ev = param_buf->fixed_param; 484 485 params->pdev_id = 486 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 487 ev->pdev_id); 488 params->status = wmi_twt_enable_status_to_host_twt_status(ev->status); 489 490 return QDF_STATUS_SUCCESS; 491 } 492 493 static enum HOST_TWT_DISABLE_STATUS 494 wmi_twt_disable_status_to_host_twt_status(WMI_DISABLE_TWT_STATUS_T status) 495 { 496 switch (status) { 497 case WMI_DISABLE_TWT_STATUS_OK: 498 return HOST_TWT_DISABLE_STATUS_OK; 499 case WMI_DISABLE_TWT_STATUS_ROAM_IN_PROGRESS: 500 return HOST_TWT_DISABLE_STATUS_ROAM_IN_PROGRESS; 501 case WMI_DISABLE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 502 return HOST_TWT_DISABLE_STATUS_CHAN_SW_IN_PROGRESS; 503 case WMI_DISABLE_TWT_STATUS_SCAN_IN_PROGRESS: 504 return HOST_TWT_DISABLE_STATUS_SCAN_IN_PROGRESS; 505 default: 506 return HOST_TWT_DISABLE_STATUS_UNKNOWN_ERROR; 507 } 508 } 509 510 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle, 511 uint8_t *evt_buf, 512 struct twt_disable_complete_event_param *params) 513 { 514 WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 515 wmi_twt_disable_complete_event_fixed_param *ev; 516 517 param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 518 if (!param_buf) { 519 wmi_err("evt_buf is NULL"); 520 return QDF_STATUS_E_INVAL; 521 } 522 523 ev = param_buf->fixed_param; 524 525 params->pdev_id = 526 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 527 ev->pdev_id); 528 params->status = wmi_twt_disable_status_to_host_twt_status(ev->status); 529 530 return QDF_STATUS_SUCCESS; 531 } 532 533 static enum HOST_TWT_ADD_STATUS 534 wmi_get_converted_twt_add_dialog_status(WMI_ADD_TWT_STATUS_T tgt_status) 535 { 536 switch (tgt_status) { 537 case WMI_ADD_TWT_STATUS_OK: 538 return HOST_TWT_ADD_STATUS_OK; 539 case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED: 540 return HOST_TWT_ADD_STATUS_TWT_NOT_ENABLED; 541 case WMI_ADD_TWT_STATUS_USED_DIALOG_ID: 542 return HOST_TWT_ADD_STATUS_USED_DIALOG_ID; 543 case WMI_ADD_TWT_STATUS_INVALID_PARAM: 544 return HOST_TWT_ADD_STATUS_INVALID_PARAM; 545 case WMI_ADD_TWT_STATUS_NOT_READY: 546 return HOST_TWT_ADD_STATUS_NOT_READY; 547 case WMI_ADD_TWT_STATUS_NO_RESOURCE: 548 return HOST_TWT_ADD_STATUS_NO_RESOURCE; 549 case WMI_ADD_TWT_STATUS_NO_ACK: 550 return HOST_TWT_ADD_STATUS_NO_ACK; 551 case WMI_ADD_TWT_STATUS_NO_RESPONSE: 552 return HOST_TWT_ADD_STATUS_NO_RESPONSE; 553 case WMI_ADD_TWT_STATUS_DENIED: 554 return HOST_TWT_ADD_STATUS_DENIED; 555 case WMI_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE: 556 return HOST_TWT_ADD_STATUS_AP_PARAMS_NOT_IN_RANGE; 557 case WMI_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED: 558 return HOST_TWT_ADD_STATUS_AP_IE_VALIDATION_FAILED; 559 case WMI_ADD_TWT_STATUS_ROAM_IN_PROGRESS: 560 return HOST_TWT_ADD_STATUS_ROAM_IN_PROGRESS; 561 case WMI_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS: 562 return HOST_TWT_ADD_STATUS_CHAN_SW_IN_PROGRESS; 563 case WMI_ADD_TWT_STATUS_SCAN_IN_PROGRESS: 564 return HOST_TWT_ADD_STATUS_SCAN_IN_PROGRESS; 565 default: 566 return HOST_TWT_ADD_STATUS_UNKNOWN_ERROR; 567 } 568 } 569 570 /** 571 * extract_twt_add_dialog_comp_event_tlv - Extacts twt add dialog complete wmi 572 * event from firmware 573 * @wmi_hande: WMI handle 574 * @evt_buf: Pointer to wmi event buf of twt add dialog complete event 575 * @params: Pointer to store the extracted parameters 576 * 577 * Return: QDF_STATUS_SUCCESS on success or QDF STATUS error values on failure 578 */ 579 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv( 580 wmi_unified_t wmi_handle, 581 uint8_t *evt_buf, 582 struct twt_add_dialog_complete_event_param *params) 583 { 584 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 585 wmi_twt_add_dialog_complete_event_fixed_param *ev; 586 587 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 588 if (!param_buf) { 589 wmi_err("evt_buf is NULL"); 590 return QDF_STATUS_E_INVAL; 591 } 592 593 ev = param_buf->fixed_param; 594 595 params->vdev_id = ev->vdev_id; 596 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 597 params->peer_macaddr.bytes); 598 params->status = wmi_get_converted_twt_add_dialog_status(ev->status); 599 params->dialog_id = ev->dialog_id; 600 params->num_additional_twt_params = param_buf->num_twt_params; 601 602 return QDF_STATUS_SUCCESS; 603 } 604 605 /** 606 * extract_twt_add_dialog_comp_additional_parameters() - Extracts additional twt 607 * twt parameters, as part of add dialog completion event 608 * @wmi_hdl: wmi handle 609 * @evt_buf: Pointer event buffer 610 * @evt_buf_len: length of the add dialog event buffer 611 * @idx: index of num_twt_params 612 * @additional_params: twt additional parameters to extract 613 * 614 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL for failure 615 */ 616 static QDF_STATUS extract_twt_add_dialog_comp_additional_parameters 617 ( 618 wmi_unified_t wmi_handle, uint8_t *evt_buf, 619 uint32_t evt_buf_len, uint32_t idx, 620 struct twt_add_dialog_additional_params *additional_params 621 ) 622 { 623 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 624 wmi_twt_add_dialog_complete_event_fixed_param *ev; 625 uint32_t flags = 0; 626 uint32_t expected_len; 627 628 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 629 if (!param_buf) { 630 wmi_err("evt_buf is NULL"); 631 return QDF_STATUS_E_INVAL; 632 } 633 634 ev = param_buf->fixed_param; 635 636 if (idx >= param_buf->num_twt_params) { 637 wmi_err("Invalid idx %d while num_twt_params = %d", 638 idx, param_buf->num_twt_params); 639 return QDF_STATUS_E_INVAL; 640 } 641 642 if (!param_buf->twt_params) { 643 wmi_err("Unable to extract additional twt parameters"); 644 return QDF_STATUS_E_INVAL; 645 } 646 647 expected_len = (sizeof(wmi_twt_add_dialog_complete_event_fixed_param) + 648 WMI_TLV_HDR_SIZE + (param_buf->num_twt_params * 649 sizeof(wmi_twt_add_dialog_additional_params))); 650 651 if (evt_buf_len != expected_len) { 652 wmi_err("Got invalid len data from FW %d expected %d", 653 evt_buf_len, expected_len); 654 return QDF_STATUS_E_INVAL; 655 } 656 657 flags = param_buf->twt_params[idx].flags; 658 additional_params->twt_cmd = TWT_FLAGS_GET_CMD(flags); 659 additional_params->bcast = TWT_FLAGS_GET_BROADCAST(flags); 660 additional_params->trig_en = TWT_FLAGS_GET_TRIGGER(flags); 661 additional_params->announce = TWT_FLAGS_GET_FLOW_TYPE(flags); 662 additional_params->protection = TWT_FLAGS_GET_PROTECTION(flags); 663 additional_params->b_twt_id0 = TWT_FLAGS_GET_BTWT_ID0(flags); 664 additional_params->info_frame_disabled = 665 TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flags); 666 additional_params->wake_dur_us = param_buf->twt_params[idx].wake_dur_us; 667 additional_params->wake_intvl_us = 668 param_buf->twt_params[idx].wake_intvl_us; 669 additional_params->sp_offset_us = 670 param_buf->twt_params[idx].sp_offset_us; 671 additional_params->sp_tsf_us_lo = 672 param_buf->twt_params[idx].sp_tsf_us_lo; 673 additional_params->sp_tsf_us_hi = 674 param_buf->twt_params[idx].sp_tsf_us_hi; 675 676 return QDF_STATUS_SUCCESS; 677 } 678 679 static enum HOST_TWT_DEL_STATUS 680 wmi_get_converted_twt_del_dialog_status(WMI_DEL_TWT_STATUS_T tgt_status) 681 { 682 switch (tgt_status) { 683 case WMI_DEL_TWT_STATUS_OK: 684 return HOST_TWT_DEL_STATUS_OK; 685 case WMI_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST: 686 return HOST_TWT_DEL_STATUS_DIALOG_ID_NOT_EXIST; 687 case WMI_DEL_TWT_STATUS_INVALID_PARAM: 688 return HOST_TWT_DEL_STATUS_INVALID_PARAM; 689 case WMI_DEL_TWT_STATUS_DIALOG_ID_BUSY: 690 return HOST_TWT_DEL_STATUS_DIALOG_ID_BUSY; 691 case WMI_DEL_TWT_STATUS_NO_RESOURCE: 692 return HOST_TWT_DEL_STATUS_NO_RESOURCE; 693 case WMI_DEL_TWT_STATUS_NO_ACK: 694 return HOST_TWT_DEL_STATUS_NO_ACK; 695 case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN: 696 return HOST_TWT_DEL_STATUS_PEER_INIT_TEARDOWN; 697 case WMI_DEL_TWT_STATUS_ROAMING: 698 return HOST_TWT_DEL_STATUS_ROAMING; 699 case WMI_DEL_TWT_STATUS_CONCURRENCY: 700 return HOST_TWT_DEL_STATUS_CONCURRENCY; 701 case WMI_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS: 702 return HOST_TWT_DEL_STATUS_CHAN_SW_IN_PROGRESS; 703 case WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS: 704 return HOST_TWT_DEL_STATUS_SCAN_IN_PROGRESS; 705 default: 706 return HOST_TWT_DEL_STATUS_UNKNOWN_ERROR; 707 } 708 } 709 710 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv( 711 wmi_unified_t wmi_handle, 712 uint8_t *evt_buf, 713 struct twt_del_dialog_complete_event_param *params) 714 { 715 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 716 wmi_twt_del_dialog_complete_event_fixed_param *ev; 717 718 param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 719 if (!param_buf) { 720 wmi_err("evt_buf is NULL"); 721 return QDF_STATUS_E_INVAL; 722 } 723 724 ev = param_buf->fixed_param; 725 726 params->vdev_id = ev->vdev_id; 727 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 728 params->peer_macaddr.bytes); 729 params->dialog_id = ev->dialog_id; 730 params->status = wmi_get_converted_twt_del_dialog_status(ev->status); 731 732 return QDF_STATUS_SUCCESS; 733 } 734 735 static enum HOST_TWT_PAUSE_STATUS 736 wmi_twt_pause_status_to_host_twt_status(WMI_PAUSE_TWT_STATUS_T status) 737 { 738 switch (status) { 739 case WMI_PAUSE_TWT_STATUS_OK: 740 return HOST_TWT_PAUSE_STATUS_OK; 741 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 742 return HOST_TWT_PAUSE_STATUS_DIALOG_ID_NOT_EXIST; 743 case WMI_PAUSE_TWT_STATUS_INVALID_PARAM: 744 return HOST_TWT_PAUSE_STATUS_INVALID_PARAM; 745 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_BUSY: 746 return HOST_TWT_PAUSE_STATUS_DIALOG_ID_BUSY; 747 case WMI_PAUSE_TWT_STATUS_NO_RESOURCE: 748 return HOST_TWT_PAUSE_STATUS_NO_RESOURCE; 749 case WMI_PAUSE_TWT_STATUS_NO_ACK: 750 return HOST_TWT_PAUSE_STATUS_NO_ACK; 751 case WMI_PAUSE_TWT_STATUS_ALREADY_PAUSED: 752 return HOST_TWT_PAUSE_STATUS_ALREADY_PAUSED; 753 case WMI_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 754 return HOST_TWT_PAUSE_STATUS_CHAN_SW_IN_PROGRESS; 755 case WMI_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS: 756 return HOST_TWT_PAUSE_STATUS_ROAM_IN_PROGRESS; 757 case WMI_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS: 758 return HOST_TWT_PAUSE_STATUS_SCAN_IN_PROGRESS; 759 default: 760 return HOST_TWT_PAUSE_STATUS_UNKNOWN_ERROR; 761 } 762 } 763 764 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv( 765 wmi_unified_t wmi_handle, 766 uint8_t *evt_buf, 767 struct twt_pause_dialog_complete_event_param *params) 768 { 769 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 770 wmi_twt_pause_dialog_complete_event_fixed_param *ev; 771 772 param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 773 if (!param_buf) { 774 wmi_err("evt_buf is NULL"); 775 return QDF_STATUS_E_INVAL; 776 } 777 778 ev = param_buf->fixed_param; 779 780 params->vdev_id = ev->vdev_id; 781 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 782 params->peer_macaddr.bytes); 783 params->status = wmi_twt_pause_status_to_host_twt_status(ev->status); 784 params->dialog_id = ev->dialog_id; 785 786 return QDF_STATUS_SUCCESS; 787 } 788 789 static enum HOST_TWT_NUDGE_STATUS 790 wmi_twt_nudge_status_to_host_twt_status(WMI_TWT_NUDGE_STATUS_T status) 791 { 792 switch (status) { 793 case WMI_NUDGE_TWT_STATUS_OK: 794 return HOST_TWT_NUDGE_STATUS_OK; 795 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 796 return HOST_TWT_NUDGE_STATUS_DIALOG_ID_NOT_EXIST; 797 case WMI_NUDGE_TWT_STATUS_INVALID_PARAM: 798 return HOST_TWT_NUDGE_STATUS_INVALID_PARAM; 799 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_BUSY: 800 return HOST_TWT_NUDGE_STATUS_DIALOG_ID_BUSY; 801 case WMI_NUDGE_TWT_STATUS_NO_RESOURCE: 802 return HOST_TWT_NUDGE_STATUS_NO_RESOURCE; 803 case WMI_NUDGE_TWT_STATUS_NO_ACK: 804 return HOST_TWT_NUDGE_STATUS_NO_ACK; 805 case WMI_NUDGE_TWT_STATUS_ALREADY_PAUSED: 806 return HOST_TWT_NUDGE_STATUS_ALREADY_PAUSED; 807 case WMI_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 808 return HOST_TWT_NUDGE_STATUS_CHAN_SW_IN_PROGRESS; 809 case WMI_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS: 810 return HOST_TWT_NUDGE_STATUS_ROAM_IN_PROGRESS; 811 case WMI_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS: 812 return HOST_TWT_NUDGE_STATUS_SCAN_IN_PROGRESS; 813 default: 814 return HOST_TWT_NUDGE_STATUS_UNKNOWN_ERROR; 815 } 816 } 817 818 static QDF_STATUS extract_twt_nudge_dialog_comp_event_tlv( 819 wmi_unified_t wmi_handle, 820 uint8_t *evt_buf, 821 struct twt_nudge_dialog_complete_event_param *params) 822 { 823 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 824 wmi_twt_nudge_dialog_complete_event_fixed_param *ev; 825 826 param_buf = (WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 827 if (!param_buf) { 828 wmi_err("evt_buf is NULL"); 829 return QDF_STATUS_E_INVAL; 830 } 831 832 ev = param_buf->fixed_param; 833 834 params->vdev_id = ev->vdev_id; 835 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 836 params->peer_macaddr.bytes); 837 params->status = wmi_twt_nudge_status_to_host_twt_status(ev->status); 838 params->dialog_id = ev->dialog_id; 839 params->next_twt_tsf_us_lo = ev->sp_tsf_us_lo; 840 params->next_twt_tsf_us_hi = ev->sp_tsf_us_hi; 841 842 wmi_debug("vdev_id: %d dialog_id: %d tsf hi : %x tsf lo: %x", 843 params->vdev_id, params->dialog_id, 844 params->next_twt_tsf_us_hi, params->next_twt_tsf_us_lo); 845 846 return QDF_STATUS_SUCCESS; 847 } 848 849 static enum HOST_TWT_RESUME_STATUS 850 wmi_get_converted_twt_resume_dialog_status(WMI_RESUME_TWT_STATUS_T tgt_status) 851 { 852 switch (tgt_status) { 853 case WMI_RESUME_TWT_STATUS_OK: 854 return HOST_TWT_RESUME_STATUS_OK; 855 case WMI_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST: 856 return HOST_TWT_RESUME_STATUS_DIALOG_ID_NOT_EXIST; 857 case WMI_RESUME_TWT_STATUS_INVALID_PARAM: 858 return HOST_TWT_RESUME_STATUS_INVALID_PARAM; 859 case WMI_RESUME_TWT_STATUS_DIALOG_ID_BUSY: 860 return HOST_TWT_RESUME_STATUS_DIALOG_ID_BUSY; 861 case WMI_RESUME_TWT_STATUS_NOT_PAUSED: 862 return HOST_TWT_RESUME_STATUS_NOT_PAUSED; 863 case WMI_RESUME_TWT_STATUS_NO_RESOURCE: 864 return HOST_TWT_RESUME_STATUS_NO_RESOURCE; 865 case WMI_RESUME_TWT_STATUS_NO_ACK: 866 return HOST_TWT_RESUME_STATUS_NO_ACK; 867 case WMI_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS: 868 return HOST_TWT_RESUME_STATUS_CHAN_SW_IN_PROGRESS; 869 case WMI_RESUME_TWT_STATUS_ROAM_IN_PROGRESS: 870 return HOST_TWT_RESUME_STATUS_ROAM_IN_PROGRESS; 871 case WMI_RESUME_TWT_STATUS_SCAN_IN_PROGRESS: 872 return HOST_TWT_RESUME_STATUS_SCAN_IN_PROGRESS; 873 default: 874 return HOST_TWT_RESUME_STATUS_UNKNOWN_ERROR; 875 } 876 } 877 878 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv( 879 wmi_unified_t wmi_handle, 880 uint8_t *evt_buf, 881 struct twt_resume_dialog_complete_event_param *params) 882 { 883 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 884 wmi_twt_resume_dialog_complete_event_fixed_param *ev; 885 886 param_buf = 887 (WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 888 if (!param_buf) { 889 wmi_err("evt_buf is NULL"); 890 return QDF_STATUS_E_INVAL; 891 } 892 893 ev = param_buf->fixed_param; 894 895 params->vdev_id = ev->vdev_id; 896 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 897 params->peer_macaddr.bytes); 898 params->status = wmi_get_converted_twt_resume_dialog_status(ev->status); 899 params->dialog_id = ev->dialog_id; 900 901 return QDF_STATUS_SUCCESS; 902 } 903 904 static enum HOST_TWT_NOTIFY_STATUS 905 wmi_get_converted_twt_notify_status(WMI_TWT_NOTIFICATION_ID_T tgt_status) 906 { 907 switch (tgt_status) { 908 case WMI_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_SET: 909 return HOST_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_SET; 910 case WMI_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_CLEAR: 911 return HOST_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_CLEAR; 912 default: 913 return HOST_TWT_NOTIFY_EVENT_READY; 914 } 915 } 916 917 static QDF_STATUS extract_twt_notify_event_tlv( 918 wmi_unified_t wmi_handle, 919 uint8_t *evt_buf, 920 struct twt_notify_event_param *params) 921 { 922 WMI_TWT_NOTIFY_EVENTID_param_tlvs *param_buf; 923 wmi_twt_notify_event_fixed_param *ev; 924 925 param_buf = 926 (WMI_TWT_NOTIFY_EVENTID_param_tlvs *)evt_buf; 927 if (!param_buf) { 928 wmi_err("evt_buf is NULL"); 929 return QDF_STATUS_E_INVAL; 930 } 931 932 ev = param_buf->fixed_param; 933 934 if (ev->event_id > WMI_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_CLEAR) { 935 wmi_debug("Incorrect TWT notify event vdev_id: %d, status: %d", 936 ev->vdev_id, ev->event_id); 937 return QDF_STATUS_E_INVAL; 938 } 939 940 params->vdev_id = ev->vdev_id; 941 params->status = wmi_get_converted_twt_notify_status(ev->event_id); 942 943 wmi_debug("Extract notify event vdev_id: %d, status: %d", 944 params->vdev_id, params->status); 945 946 return QDF_STATUS_SUCCESS; 947 } 948 949 #ifdef WLAN_SUPPORT_BCAST_TWT 950 static QDF_STATUS 951 extract_twt_btwt_invite_sta_comp_event_tlv( 952 wmi_unified_t wmi_handle, 953 uint8_t *evt_buf, 954 struct 955 twt_btwt_invite_sta_complete_event_param 956 *params) 957 { 958 WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 959 wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev; 960 961 param_buf = 962 (WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 963 if (!param_buf) { 964 wmi_err("evt_buf is NULL"); 965 return QDF_STATUS_E_INVAL; 966 } 967 968 ev = param_buf->fixed_param; 969 970 params->vdev_id = ev->vdev_id; 971 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 972 params->peer_macaddr.bytes); 973 params->status = ev->status; 974 params->dialog_id = ev->dialog_id; 975 976 return QDF_STATUS_SUCCESS; 977 } 978 979 static QDF_STATUS 980 extract_twt_btwt_remove_sta_comp_event_tlv( 981 wmi_unified_t wmi_handle, 982 uint8_t *evt_buf, 983 struct 984 twt_btwt_remove_sta_complete_event_param 985 *params) 986 { 987 WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 988 wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev; 989 990 param_buf = 991 (WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 992 if (!param_buf) { 993 wmi_err("evt_buf is NULL"); 994 return QDF_STATUS_E_INVAL; 995 } 996 997 ev = param_buf->fixed_param; 998 999 params->vdev_id = ev->vdev_id; 1000 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 1001 params->peer_macaddr.bytes); 1002 params->status = ev->status; 1003 params->dialog_id = ev->dialog_id; 1004 1005 return QDF_STATUS_SUCCESS; 1006 } 1007 #endif 1008 1009 #ifdef WLAN_SUPPORT_BCAST_TWT 1010 static void 1011 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 1012 { 1013 ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv; 1014 ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv; 1015 ops->extract_twt_btwt_invite_sta_comp_event = 1016 extract_twt_btwt_invite_sta_comp_event_tlv; 1017 ops->extract_twt_btwt_remove_sta_comp_event = 1018 extract_twt_btwt_remove_sta_comp_event_tlv; 1019 } 1020 #else 1021 static void 1022 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 1023 { 1024 } 1025 #endif 1026 1027 static QDF_STATUS 1028 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle, 1029 uint8_t *evt_buf, 1030 struct twt_session_stats_event_param 1031 *params) 1032 { 1033 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 1034 wmi_pdev_twt_session_stats_event_fixed_param *ev; 1035 1036 param_buf = 1037 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 1038 if (!param_buf) { 1039 wmi_err("evt_buf is NULL"); 1040 return QDF_STATUS_E_INVAL; 1041 } 1042 1043 ev = param_buf->fixed_param; 1044 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 1045 wmi_handle, 1046 ev->pdev_id); 1047 params->num_sessions = param_buf->num_twt_sessions; 1048 1049 wmi_debug("pdev_id=%d, num of TWT sessions=%d", 1050 params->pdev_id, params->num_sessions); 1051 1052 return QDF_STATUS_SUCCESS; 1053 } 1054 1055 static QDF_STATUS 1056 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, 1057 uint8_t *evt_buf, 1058 struct twt_session_stats_event_param 1059 *params, 1060 struct twt_session_stats_info 1061 *session, 1062 uint32_t idx) 1063 { 1064 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 1065 wmi_twt_session_stats_info *twt_session; 1066 uint32_t flags; 1067 wmi_mac_addr *m1; 1068 uint8_t *m2; 1069 1070 param_buf = 1071 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 1072 if (!param_buf) { 1073 wmi_err("evt_buf is NULL"); 1074 return QDF_STATUS_E_INVAL; 1075 } 1076 1077 if (idx >= param_buf->num_twt_sessions) { 1078 wmi_err("wrong idx, idx=%d, num_sessions=%d", 1079 idx, param_buf->num_twt_sessions); 1080 return QDF_STATUS_E_INVAL; 1081 } 1082 1083 twt_session = ¶m_buf->twt_sessions[idx]; 1084 1085 session->vdev_id = twt_session->vdev_id; 1086 m1 = &twt_session->peer_mac; 1087 m2 = session->peer_mac.bytes; 1088 WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2); 1089 session->event_type = twt_session->event_type; 1090 flags = twt_session->flow_id_flags; 1091 session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags); 1092 session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags); 1093 session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags); 1094 session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags); 1095 session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags); 1096 session->info_frame_disabled = 1097 WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags); 1098 session->dialog_id = twt_session->dialog_id; 1099 session->wake_dura_us = twt_session->wake_dura_us; 1100 session->wake_intvl_us = twt_session->wake_intvl_us; 1101 session->sp_offset_us = twt_session->sp_offset_us; 1102 session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo; 1103 session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi; 1104 wmi_debug("type=%d id=%d bcast=%d trig=%d announ=%d diagid=%d wake_dur=%ul wake_int=%ul offset=%ul", 1105 session->event_type, session->flow_id, 1106 session->bcast, session->trig, 1107 session->announ, session->dialog_id, session->wake_dura_us, 1108 session->wake_intvl_us, session->sp_offset_us); 1109 1110 return QDF_STATUS_SUCCESS; 1111 } 1112 1113 static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( 1114 wmi_unified_t wmi_handle, uint8_t *event, 1115 struct wmi_twt_cap_bitmap_params *var) 1116 { 1117 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 1118 wmi_twt_caps_params *twt_caps; 1119 1120 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 1121 if (!param_buf) 1122 return QDF_STATUS_E_INVAL; 1123 1124 twt_caps = param_buf->twt_caps; 1125 if (!twt_caps) 1126 return QDF_STATUS_E_INVAL; 1127 1128 var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap, 1129 0, 1); 1130 1131 return QDF_STATUS_SUCCESS; 1132 } 1133 1134 static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT 1135 wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd) 1136 { 1137 switch (tgt_cmd) { 1138 case WMI_TWT_ADD_DIALOG_CMDID: 1139 return WMI_HOST_TWT_ADD_DIALOG_CMDID; 1140 case WMI_TWT_DEL_DIALOG_CMDID: 1141 return WMI_HOST_TWT_DEL_DIALOG_CMDID; 1142 case WMI_TWT_PAUSE_DIALOG_CMDID: 1143 return WMI_HOST_TWT_PAUSE_DIALOG_CMDID; 1144 case WMI_TWT_RESUME_DIALOG_CMDID: 1145 return WMI_HOST_TWT_RESUME_DIALOG_CMDID; 1146 case WMI_TWT_NUDGE_DIALOG_CMDID: 1147 return WMI_HOST_TWT_NUDGE_DIALOG_CMDID; 1148 default: 1149 return WMI_HOST_TWT_UNKNOWN_CMDID; 1150 } 1151 } 1152 1153 static QDF_STATUS 1154 extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle, 1155 uint8_t *evt_buf, 1156 struct twt_ack_complete_event_param *var) 1157 { 1158 WMI_TWT_ACK_EVENTID_param_tlvs *param_buf; 1159 wmi_twt_ack_event_fixed_param *ack_event; 1160 1161 param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf; 1162 if (!param_buf) { 1163 wmi_err("evt_buf is NULL"); 1164 return QDF_STATUS_E_INVAL; 1165 } 1166 1167 ack_event = param_buf->fixed_param; 1168 1169 var->vdev_id = ack_event->vdev_id; 1170 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr, 1171 var->peer_macaddr.bytes); 1172 var->dialog_id = ack_event->dialog_id; 1173 var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event( 1174 ack_event->twt_cmd); 1175 1176 switch (ack_event->twt_cmd) { 1177 case WMI_TWT_ADD_DIALOG_CMDID: 1178 var->status = wmi_get_converted_twt_add_dialog_status( 1179 ack_event->status); 1180 break; 1181 case WMI_TWT_DEL_DIALOG_CMDID: 1182 var->status = wmi_get_converted_twt_del_dialog_status( 1183 ack_event->status); 1184 break; 1185 case WMI_TWT_PAUSE_DIALOG_CMDID: 1186 var->status = wmi_twt_pause_status_to_host_twt_status( 1187 ack_event->status); 1188 break; 1189 case WMI_TWT_RESUME_DIALOG_CMDID: 1190 var->status = wmi_get_converted_twt_resume_dialog_status( 1191 ack_event->status); 1192 break; 1193 case WMI_TWT_NUDGE_DIALOG_CMDID: 1194 var->status = wmi_twt_nudge_status_to_host_twt_status( 1195 ack_event->status); 1196 break; 1197 default: 1198 break; 1199 } 1200 return QDF_STATUS_SUCCESS; 1201 } 1202 #elif WLAN_SUPPORT_TWT 1203 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle, 1204 struct wmi_twt_enable_param *params) 1205 { 1206 wmi_twt_enable_cmd_fixed_param *cmd; 1207 wmi_buf_t buf; 1208 QDF_STATUS status; 1209 1210 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1211 if (!buf) { 1212 wmi_err("Failed to allocate memory"); 1213 return QDF_STATUS_E_FAILURE; 1214 } 1215 1216 cmd = (wmi_twt_enable_cmd_fixed_param *) wmi_buf_data(buf); 1217 WMITLV_SET_HDR(&cmd->tlv_header, 1218 WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param, 1219 WMITLV_GET_STRUCT_TLVLEN 1220 (wmi_twt_enable_cmd_fixed_param)); 1221 1222 cmd->pdev_id = 1223 wmi_handle->ops->convert_pdev_id_host_to_target( 1224 wmi_handle, 1225 params->pdev_id); 1226 cmd->sta_cong_timer_ms = params->sta_cong_timer_ms; 1227 cmd->mbss_support = params->mbss_support; 1228 cmd->default_slot_size = params->default_slot_size; 1229 cmd->congestion_thresh_setup = params->congestion_thresh_setup; 1230 cmd->congestion_thresh_teardown = params->congestion_thresh_teardown; 1231 cmd->congestion_thresh_critical = params->congestion_thresh_critical; 1232 cmd->interference_thresh_teardown = 1233 params->interference_thresh_teardown; 1234 cmd->interference_thresh_setup = params->interference_thresh_setup; 1235 cmd->min_no_sta_setup = params->min_no_sta_setup; 1236 cmd->min_no_sta_teardown = params->min_no_sta_teardown; 1237 cmd->no_of_bcast_mcast_slots = params->no_of_bcast_mcast_slots; 1238 cmd->min_no_twt_slots = params->min_no_twt_slots; 1239 cmd->max_no_sta_twt = params->max_no_sta_twt; 1240 cmd->mode_check_interval = params->mode_check_interval; 1241 cmd->add_sta_slot_interval = params->add_sta_slot_interval; 1242 cmd->remove_sta_slot_interval = params->remove_sta_slot_interval; 1243 1244 TWT_EN_DIS_FLAGS_SET_BTWT(cmd->flags, params->b_twt_enable); 1245 TWT_EN_DIS_FLAGS_SET_L_MBSSID(cmd->flags, 1246 params->b_twt_legacy_mbss_enable); 1247 TWT_EN_DIS_FLAGS_SET_AX_MBSSID(cmd->flags, 1248 params->b_twt_ax_mbss_enable); 1249 if (params->ext_conf_present) { 1250 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 1251 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 1252 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 1253 } 1254 1255 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1256 WMI_TWT_ENABLE_CMDID); 1257 if (QDF_IS_STATUS_ERROR(status)) { 1258 wmi_err("Failed to send WMI_TWT_ENABLE_CMDID"); 1259 wmi_buf_free(buf); 1260 } 1261 1262 return status; 1263 } 1264 1265 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle, 1266 struct wmi_twt_disable_param *params) 1267 { 1268 wmi_twt_disable_cmd_fixed_param *cmd; 1269 wmi_buf_t buf; 1270 QDF_STATUS status; 1271 1272 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1273 if (!buf) { 1274 wmi_err("Failed to allocate memory"); 1275 return QDF_STATUS_E_FAILURE; 1276 } 1277 1278 cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf); 1279 WMITLV_SET_HDR(&cmd->tlv_header, 1280 WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param, 1281 WMITLV_GET_STRUCT_TLVLEN 1282 (wmi_twt_disable_cmd_fixed_param)); 1283 1284 cmd->pdev_id = 1285 wmi_handle->ops->convert_pdev_id_host_to_target( 1286 wmi_handle, 1287 params->pdev_id); 1288 if (params->ext_conf_present) { 1289 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 1290 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 1291 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 1292 } 1293 1294 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1295 WMI_TWT_DISABLE_CMDID); 1296 if (QDF_IS_STATUS_ERROR(status)) { 1297 wmi_err("Failed to send WMI_TWT_DISABLE_CMDID"); 1298 wmi_buf_free(buf); 1299 } 1300 1301 return status; 1302 } 1303 1304 #ifdef WLAN_SUPPORT_BCAST_TWT 1305 static void 1306 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params, 1307 wmi_twt_add_dialog_cmd_fixed_param *cmd) 1308 { 1309 TWT_FLAGS_SET_BTWT_ID0(cmd->flags, params->flag_b_twt_id0); 1310 cmd->b_twt_persistence = params->b_twt_persistence; 1311 cmd->b_twt_recommendation = params->b_twt_recommendation; 1312 } 1313 #else 1314 static void 1315 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params, 1316 wmi_twt_add_dialog_cmd_fixed_param *cmd) 1317 { 1318 } 1319 #endif 1320 1321 static QDF_STATUS 1322 send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1323 struct wmi_twt_add_dialog_param *params) 1324 { 1325 wmi_twt_add_dialog_cmd_fixed_param *cmd; 1326 wmi_buf_t buf; 1327 QDF_STATUS status; 1328 1329 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1330 if (!buf) { 1331 wmi_err("Failed to allocate memory"); 1332 return QDF_STATUS_E_FAILURE; 1333 } 1334 1335 cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1336 WMITLV_SET_HDR(&cmd->tlv_header, 1337 WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param, 1338 WMITLV_GET_STRUCT_TLVLEN 1339 (wmi_twt_add_dialog_cmd_fixed_param)); 1340 1341 cmd->vdev_id = params->vdev_id; 1342 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1343 cmd->dialog_id = params->dialog_id; 1344 cmd->wake_intvl_us = params->wake_intvl_us; 1345 cmd->wake_intvl_mantis = params->wake_intvl_mantis; 1346 cmd->wake_dura_us = params->wake_dura_us; 1347 cmd->sp_offset_us = params->sp_offset_us; 1348 cmd->min_wake_intvl_us = params->min_wake_intvl_us; 1349 cmd->max_wake_intvl_us = params->max_wake_intvl_us; 1350 cmd->min_wake_dura_us = params->min_wake_dura_us; 1351 cmd->max_wake_dura_us = params->max_wake_dura_us; 1352 cmd->sp_start_tsf_lo = (uint32_t)(params->wake_time_tsf & 0xFFFFFFFF); 1353 cmd->sp_start_tsf_hi = (uint32_t)(params->wake_time_tsf >> 32); 1354 cmd->announce_timeout_us = params->announce_timeout_us; 1355 TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd); 1356 TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast); 1357 TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger); 1358 TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type); 1359 TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection); 1360 1361 twt_add_dialog_set_bcast_twt_params(params, cmd); 1362 1363 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1364 WMI_TWT_ADD_DIALOG_CMDID); 1365 if (QDF_IS_STATUS_ERROR(status)) { 1366 wmi_err("Failed to send WMI_TWT_ADD_DIALOG_CMDID"); 1367 wmi_buf_free(buf); 1368 } 1369 1370 return status; 1371 } 1372 1373 #ifdef WLAN_SUPPORT_BCAST_TWT 1374 static void 1375 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params, 1376 wmi_twt_del_dialog_cmd_fixed_param *cmd) 1377 { 1378 cmd->b_twt_persistence = params->b_twt_persistence; 1379 } 1380 #else 1381 static void 1382 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params, 1383 wmi_twt_del_dialog_cmd_fixed_param *cmd) 1384 { 1385 } 1386 #endif 1387 1388 static QDF_STATUS 1389 send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1390 struct wmi_twt_del_dialog_param *params) 1391 { 1392 wmi_twt_del_dialog_cmd_fixed_param *cmd; 1393 wmi_buf_t buf; 1394 QDF_STATUS status; 1395 1396 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1397 if (!buf) { 1398 wmi_err("Failed to allocate memory"); 1399 return QDF_STATUS_E_FAILURE; 1400 } 1401 1402 cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1403 WMITLV_SET_HDR(&cmd->tlv_header, 1404 WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param, 1405 WMITLV_GET_STRUCT_TLVLEN 1406 (wmi_twt_del_dialog_cmd_fixed_param)); 1407 1408 cmd->vdev_id = params->vdev_id; 1409 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1410 cmd->dialog_id = params->dialog_id; 1411 1412 twt_del_dialog_set_bcast_twt_params(params, cmd); 1413 1414 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1415 WMI_TWT_DEL_DIALOG_CMDID); 1416 if (QDF_IS_STATUS_ERROR(status)) { 1417 wmi_err("Failed to send WMI_TWT_DEL_DIALOG_CMDID"); 1418 wmi_buf_free(buf); 1419 } 1420 1421 return status; 1422 } 1423 1424 static QDF_STATUS 1425 send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1426 struct wmi_twt_pause_dialog_cmd_param *params) 1427 { 1428 wmi_twt_pause_dialog_cmd_fixed_param *cmd; 1429 wmi_buf_t buf; 1430 QDF_STATUS status; 1431 1432 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1433 if (!buf) { 1434 wmi_err("Failed to allocate memory"); 1435 return QDF_STATUS_E_FAILURE; 1436 } 1437 1438 cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1439 WMITLV_SET_HDR(&cmd->tlv_header, 1440 WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param, 1441 WMITLV_GET_STRUCT_TLVLEN 1442 (wmi_twt_pause_dialog_cmd_fixed_param)); 1443 1444 cmd->vdev_id = params->vdev_id; 1445 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1446 cmd->dialog_id = params->dialog_id; 1447 1448 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1449 WMI_TWT_PAUSE_DIALOG_CMDID); 1450 if (QDF_IS_STATUS_ERROR(status)) { 1451 wmi_err("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID"); 1452 wmi_buf_free(buf); 1453 } 1454 1455 return status; 1456 } 1457 1458 static QDF_STATUS 1459 send_twt_nudge_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1460 struct wmi_twt_nudge_dialog_cmd_param *params) 1461 { 1462 wmi_twt_nudge_dialog_cmd_fixed_param *cmd; 1463 wmi_buf_t buf; 1464 QDF_STATUS status; 1465 1466 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1467 if (!buf) 1468 return QDF_STATUS_E_FAILURE; 1469 1470 cmd = (wmi_twt_nudge_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1471 WMITLV_SET_HDR(&cmd->tlv_header, 1472 WMITLV_TAG_STRUC_wmi_twt_nudge_dialog_cmd_fixed_param, 1473 WMITLV_GET_STRUCT_TLVLEN 1474 (wmi_twt_nudge_dialog_cmd_fixed_param)); 1475 1476 cmd->vdev_id = params->vdev_id; 1477 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1478 cmd->dialog_id = params->dialog_id; 1479 cmd->suspend_duration_ms = params->suspend_duration / 1000; 1480 cmd->next_twt_size = params->next_twt_size; 1481 1482 wmi_debug("vdev_id: %d dialog_id: %d duration(in ms): %u next_twt_size: %d " 1483 "peer_macaddr: "QDF_MAC_ADDR_FMT, cmd->vdev_id, 1484 cmd->dialog_id, cmd->suspend_duration_ms, cmd->next_twt_size, 1485 QDF_MAC_ADDR_REF(params->peer_macaddr)); 1486 1487 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1488 WMI_TWT_NUDGE_DIALOG_CMDID); 1489 if (QDF_IS_STATUS_ERROR(status)) 1490 wmi_buf_free(buf); 1491 1492 return status; 1493 } 1494 1495 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1496 struct wmi_twt_resume_dialog_cmd_param *params) 1497 { 1498 wmi_twt_resume_dialog_cmd_fixed_param *cmd; 1499 wmi_buf_t buf; 1500 QDF_STATUS status; 1501 1502 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1503 if (!buf) { 1504 wmi_err("Failed to allocate memory"); 1505 return QDF_STATUS_E_FAILURE; 1506 } 1507 1508 cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1509 WMITLV_SET_HDR(&cmd->tlv_header, 1510 WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param, 1511 WMITLV_GET_STRUCT_TLVLEN 1512 (wmi_twt_resume_dialog_cmd_fixed_param)); 1513 1514 cmd->vdev_id = params->vdev_id; 1515 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1516 cmd->dialog_id = params->dialog_id; 1517 cmd->sp_offset_us = params->sp_offset_us; 1518 cmd->next_twt_size = params->next_twt_size; 1519 1520 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1521 WMI_TWT_RESUME_DIALOG_CMDID); 1522 if (QDF_IS_STATUS_ERROR(status)) { 1523 wmi_err("Failed to send WMI_TWT_RESUME_DIALOG_CMDID"); 1524 wmi_buf_free(buf); 1525 } 1526 1527 return status; 1528 } 1529 1530 #ifdef WLAN_SUPPORT_BCAST_TWT 1531 static QDF_STATUS 1532 send_twt_btwt_invite_sta_cmd_tlv(wmi_unified_t wmi_handle, 1533 struct wmi_twt_btwt_invite_sta_cmd_param 1534 *params) 1535 { 1536 wmi_twt_btwt_invite_sta_cmd_fixed_param *cmd; 1537 wmi_buf_t buf; 1538 QDF_STATUS status; 1539 1540 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1541 if (!buf) { 1542 wmi_err("Failed to allocate memory"); 1543 return QDF_STATUS_E_FAILURE; 1544 } 1545 1546 cmd = (wmi_twt_btwt_invite_sta_cmd_fixed_param *)wmi_buf_data(buf); 1547 WMITLV_SET_HDR(&cmd->tlv_header, 1548 WMITLV_TAG_STRUC_wmi_twt_btwt_invite_sta_cmd_fixed_param, 1549 WMITLV_GET_STRUCT_TLVLEN 1550 (wmi_twt_btwt_invite_sta_cmd_fixed_param)); 1551 1552 cmd->vdev_id = params->vdev_id; 1553 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1554 cmd->dialog_id = params->dialog_id; 1555 1556 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1557 WMI_TWT_BTWT_INVITE_STA_CMDID); 1558 if (QDF_IS_STATUS_ERROR(status)) { 1559 wmi_buf_free(buf); 1560 } 1561 1562 return status; 1563 } 1564 1565 static QDF_STATUS 1566 send_twt_btwt_remove_sta_cmd_tlv(wmi_unified_t wmi_handle, 1567 struct wmi_twt_btwt_remove_sta_cmd_param 1568 *params) 1569 { 1570 wmi_twt_btwt_remove_sta_cmd_fixed_param *cmd; 1571 wmi_buf_t buf; 1572 QDF_STATUS status; 1573 1574 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1575 if (!buf) { 1576 wmi_err("Failed to allocate memory"); 1577 return QDF_STATUS_E_FAILURE; 1578 } 1579 1580 cmd = (wmi_twt_btwt_remove_sta_cmd_fixed_param *)wmi_buf_data(buf); 1581 WMITLV_SET_HDR(&cmd->tlv_header, 1582 WMITLV_TAG_STRUC_wmi_twt_btwt_remove_sta_cmd_fixed_param, 1583 WMITLV_GET_STRUCT_TLVLEN 1584 (wmi_twt_btwt_remove_sta_cmd_fixed_param)); 1585 1586 cmd->vdev_id = params->vdev_id; 1587 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1588 cmd->dialog_id = params->dialog_id; 1589 1590 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1591 WMI_TWT_BTWT_REMOVE_STA_CMDID); 1592 if (QDF_IS_STATUS_ERROR(status)) { 1593 wmi_buf_free(buf); 1594 } 1595 1596 return status; 1597 } 1598 #endif 1599 1600 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle, 1601 uint8_t *evt_buf, 1602 struct wmi_twt_enable_complete_event_param *params) 1603 { 1604 WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 1605 wmi_twt_enable_complete_event_fixed_param *ev; 1606 1607 param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1608 if (!param_buf) { 1609 wmi_err("evt_buf is NULL"); 1610 return QDF_STATUS_E_INVAL; 1611 } 1612 1613 ev = param_buf->fixed_param; 1614 1615 params->pdev_id = 1616 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 1617 ev->pdev_id); 1618 params->status = ev->status; 1619 1620 return QDF_STATUS_SUCCESS; 1621 } 1622 1623 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle, 1624 uint8_t *evt_buf, 1625 struct wmi_twt_disable_complete_event *params) 1626 { 1627 WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 1628 wmi_twt_disable_complete_event_fixed_param *ev; 1629 1630 param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1631 if (!param_buf) { 1632 wmi_err("evt_buf is NULL"); 1633 return QDF_STATUS_E_INVAL; 1634 } 1635 1636 ev = param_buf->fixed_param; 1637 1638 #if 0 1639 params->pdev_id = 1640 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 1641 ev->pdev_id); 1642 params->status = ev->status; 1643 #endif 1644 1645 return QDF_STATUS_SUCCESS; 1646 } 1647 1648 static enum WMI_HOST_ADD_TWT_STATUS 1649 wmi_get_converted_twt_add_dialog_status(WMI_ADD_TWT_STATUS_T tgt_status) 1650 { 1651 switch (tgt_status) { 1652 case WMI_ADD_TWT_STATUS_OK: 1653 return WMI_HOST_ADD_TWT_STATUS_OK; 1654 case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED: 1655 return WMI_HOST_ADD_TWT_STATUS_TWT_NOT_ENABLED; 1656 case WMI_ADD_TWT_STATUS_USED_DIALOG_ID: 1657 return WMI_HOST_ADD_TWT_STATUS_USED_DIALOG_ID; 1658 case WMI_ADD_TWT_STATUS_INVALID_PARAM: 1659 return WMI_HOST_ADD_TWT_STATUS_INVALID_PARAM; 1660 case WMI_ADD_TWT_STATUS_NOT_READY: 1661 return WMI_HOST_ADD_TWT_STATUS_NOT_READY; 1662 case WMI_ADD_TWT_STATUS_NO_RESOURCE: 1663 return WMI_HOST_ADD_TWT_STATUS_NO_RESOURCE; 1664 case WMI_ADD_TWT_STATUS_NO_ACK: 1665 return WMI_HOST_ADD_TWT_STATUS_NO_ACK; 1666 case WMI_ADD_TWT_STATUS_NO_RESPONSE: 1667 return WMI_HOST_ADD_TWT_STATUS_NO_RESPONSE; 1668 case WMI_ADD_TWT_STATUS_DENIED: 1669 return WMI_HOST_ADD_TWT_STATUS_DENIED; 1670 case WMI_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE: 1671 return WMI_HOST_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE; 1672 case WMI_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED: 1673 return WMI_HOST_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED; 1674 case WMI_ADD_TWT_STATUS_ROAM_IN_PROGRESS: 1675 return WMI_HOST_ADD_TWT_STATUS_ROAM_IN_PROGRESS; 1676 case WMI_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1677 return WMI_HOST_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1678 case WMI_ADD_TWT_STATUS_SCAN_IN_PROGRESS: 1679 return WMI_HOST_ADD_TWT_STATUS_SCAN_IN_PROGRESS; 1680 default: 1681 return WMI_HOST_ADD_TWT_STATUS_UNKNOWN_ERROR; 1682 } 1683 } 1684 1685 /** 1686 * extract_twt_add_dialog_comp_event_tlv - Extacts twt add dialog complete wmi 1687 * event from firmware 1688 * @wmi_hande: WMI handle 1689 * @evt_buf: Pointer to wmi event buf of twt add dialog complete event 1690 * @params: Pointer to store the extracted parameters 1691 * 1692 * Return: QDF_STATUS_SUCCESS on success or QDF STATUS error values on failure 1693 */ 1694 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv( 1695 wmi_unified_t wmi_handle, 1696 uint8_t *evt_buf, 1697 struct wmi_twt_add_dialog_complete_event_param *params) 1698 { 1699 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1700 wmi_twt_add_dialog_complete_event_fixed_param *ev; 1701 1702 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1703 if (!param_buf) { 1704 wmi_err("evt_buf is NULL"); 1705 return QDF_STATUS_E_INVAL; 1706 } 1707 1708 ev = param_buf->fixed_param; 1709 1710 params->vdev_id = ev->vdev_id; 1711 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1712 params->status = wmi_get_converted_twt_add_dialog_status(ev->status); 1713 params->dialog_id = ev->dialog_id; 1714 params->num_additional_twt_params = param_buf->num_twt_params; 1715 1716 return QDF_STATUS_SUCCESS; 1717 } 1718 1719 /** 1720 * extract_twt_add_dialog_comp_additional_parameters() - Extracts additional twt 1721 * twt parameters, as part of add dialog completion event 1722 * @wmi_hdl: wmi handle 1723 * @evt_buf: Pointer event buffer 1724 * @evt_buf_len: length of the add dialog event buffer 1725 * @idx: index of num_twt_params 1726 * @additional_params: twt additional parameters to extract 1727 * 1728 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL for failure 1729 */ 1730 static QDF_STATUS extract_twt_add_dialog_comp_additional_parameters 1731 ( 1732 wmi_unified_t wmi_handle, uint8_t *evt_buf, 1733 uint32_t evt_buf_len, uint32_t idx, 1734 struct wmi_twt_add_dialog_additional_params *additional_params 1735 ) 1736 { 1737 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1738 wmi_twt_add_dialog_complete_event_fixed_param *ev; 1739 uint32_t flags = 0; 1740 uint32_t expected_len; 1741 1742 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1743 if (!param_buf) { 1744 wmi_err("evt_buf is NULL"); 1745 return QDF_STATUS_E_INVAL; 1746 } 1747 1748 ev = param_buf->fixed_param; 1749 1750 if (idx >= param_buf->num_twt_params) { 1751 wmi_err("Invalid idx %d while num_twt_params = %d", 1752 idx, param_buf->num_twt_params); 1753 return QDF_STATUS_E_INVAL; 1754 } 1755 1756 if (!param_buf->twt_params) { 1757 wmi_err("Unable to extract additional twt parameters"); 1758 return QDF_STATUS_E_INVAL; 1759 } 1760 1761 expected_len = (sizeof(wmi_twt_add_dialog_complete_event_fixed_param) + 1762 WMI_TLV_HDR_SIZE + (param_buf->num_twt_params * 1763 sizeof(wmi_twt_add_dialog_additional_params))); 1764 1765 if (evt_buf_len != expected_len) { 1766 wmi_err("Got invalid len data from FW %d expected %d", 1767 evt_buf_len, expected_len); 1768 return QDF_STATUS_E_INVAL; 1769 } 1770 1771 flags = param_buf->twt_params[idx].flags; 1772 additional_params->twt_cmd = TWT_FLAGS_GET_CMD(flags); 1773 additional_params->bcast = TWT_FLAGS_GET_BROADCAST(flags); 1774 additional_params->trig_en = TWT_FLAGS_GET_TRIGGER(flags); 1775 additional_params->announce = TWT_FLAGS_GET_FLOW_TYPE(flags); 1776 additional_params->protection = TWT_FLAGS_GET_PROTECTION(flags); 1777 additional_params->b_twt_id0 = TWT_FLAGS_GET_BTWT_ID0(flags); 1778 additional_params->info_frame_disabled = 1779 TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flags); 1780 additional_params->wake_dur_us = param_buf->twt_params[idx].wake_dur_us; 1781 additional_params->wake_intvl_us = 1782 param_buf->twt_params[idx].wake_intvl_us; 1783 additional_params->sp_offset_us = 1784 param_buf->twt_params[idx].sp_offset_us; 1785 additional_params->sp_tsf_us_lo = 1786 param_buf->twt_params[idx].sp_tsf_us_lo; 1787 additional_params->sp_tsf_us_hi = 1788 param_buf->twt_params[idx].sp_tsf_us_hi; 1789 additional_params->pm_responder_bit_valid = 1790 TWT_FLAGS_GET_PM_RESPONDER_MODE_VALID(flags); 1791 additional_params->pm_responder_bit = 1792 TWT_FLAGS_GET_PM_RESPONDER_MODE(flags); 1793 1794 return QDF_STATUS_SUCCESS; 1795 } 1796 1797 static enum WMI_HOST_DEL_TWT_STATUS 1798 wmi_get_converted_twt_del_dialog_status(WMI_DEL_TWT_STATUS_T tgt_status) 1799 { 1800 switch (tgt_status) { 1801 case WMI_DEL_TWT_STATUS_OK: 1802 return WMI_HOST_DEL_TWT_STATUS_OK; 1803 case WMI_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1804 return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1805 case WMI_DEL_TWT_STATUS_INVALID_PARAM: 1806 return WMI_HOST_DEL_TWT_STATUS_INVALID_PARAM; 1807 case WMI_DEL_TWT_STATUS_DIALOG_ID_BUSY: 1808 return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_BUSY; 1809 case WMI_DEL_TWT_STATUS_NO_RESOURCE: 1810 return WMI_HOST_DEL_TWT_STATUS_NO_RESOURCE; 1811 case WMI_DEL_TWT_STATUS_NO_ACK: 1812 return WMI_HOST_DEL_TWT_STATUS_NO_ACK; 1813 case WMI_DEL_TWT_STATUS_UNKNOWN_ERROR: 1814 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 1815 case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN: 1816 return WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN; 1817 case WMI_DEL_TWT_STATUS_ROAMING: 1818 return WMI_HOST_DEL_TWT_STATUS_ROAMING; 1819 case WMI_DEL_TWT_STATUS_CONCURRENCY: 1820 return WMI_HOST_DEL_TWT_STATUS_CONCURRENCY; 1821 case WMI_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1822 return WMI_HOST_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1823 case WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS: 1824 return WMI_HOST_DEL_TWT_STATUS_SCAN_IN_PROGRESS; 1825 default: 1826 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 1827 } 1828 1829 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 1830 } 1831 1832 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv( 1833 wmi_unified_t wmi_handle, 1834 uint8_t *evt_buf, 1835 struct wmi_twt_del_dialog_complete_event_param *params) 1836 { 1837 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1838 wmi_twt_del_dialog_complete_event_fixed_param *ev; 1839 1840 param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1841 if (!param_buf) { 1842 wmi_err("evt_buf is NULL"); 1843 return QDF_STATUS_E_INVAL; 1844 } 1845 1846 ev = param_buf->fixed_param; 1847 1848 params->vdev_id = ev->vdev_id; 1849 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1850 params->dialog_id = ev->dialog_id; 1851 params->status = wmi_get_converted_twt_del_dialog_status(ev->status); 1852 1853 return QDF_STATUS_SUCCESS; 1854 } 1855 1856 static enum WMI_HOST_PAUSE_TWT_STATUS 1857 wmi_twt_pause_status_to_host_twt_status(WMI_PAUSE_TWT_STATUS_T status) 1858 { 1859 switch (status) { 1860 case WMI_PAUSE_TWT_STATUS_OK: 1861 return WMI_HOST_PAUSE_TWT_STATUS_OK; 1862 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1863 return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1864 case WMI_PAUSE_TWT_STATUS_INVALID_PARAM: 1865 return WMI_HOST_PAUSE_TWT_STATUS_INVALID_PARAM; 1866 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_BUSY: 1867 return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_BUSY; 1868 case WMI_PAUSE_TWT_STATUS_NO_RESOURCE: 1869 return WMI_HOST_PAUSE_TWT_STATUS_NO_RESOURCE; 1870 case WMI_PAUSE_TWT_STATUS_NO_ACK: 1871 return WMI_HOST_PAUSE_TWT_STATUS_NO_ACK; 1872 case WMI_PAUSE_TWT_STATUS_UNKNOWN_ERROR: 1873 return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR; 1874 case WMI_PAUSE_TWT_STATUS_ALREADY_PAUSED: 1875 return WMI_HOST_PAUSE_TWT_STATUS_ALREADY_PAUSED; 1876 case WMI_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1877 return WMI_HOST_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1878 case WMI_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS: 1879 return WMI_HOST_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS; 1880 case WMI_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS: 1881 return WMI_HOST_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS; 1882 default: 1883 return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR; 1884 } 1885 } 1886 1887 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv( 1888 wmi_unified_t wmi_handle, 1889 uint8_t *evt_buf, 1890 struct wmi_twt_pause_dialog_complete_event_param *params) 1891 { 1892 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1893 wmi_twt_pause_dialog_complete_event_fixed_param *ev; 1894 1895 param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1896 if (!param_buf) { 1897 wmi_err("evt_buf is NULL"); 1898 return QDF_STATUS_E_INVAL; 1899 } 1900 1901 ev = param_buf->fixed_param; 1902 1903 params->vdev_id = ev->vdev_id; 1904 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1905 params->status = wmi_twt_pause_status_to_host_twt_status(ev->status); 1906 params->dialog_id = ev->dialog_id; 1907 1908 return QDF_STATUS_SUCCESS; 1909 } 1910 1911 static enum WMI_HOST_NUDGE_TWT_STATUS 1912 wmi_twt_nudge_status_to_host_twt_status(WMI_TWT_NUDGE_STATUS_T status) 1913 { 1914 switch (status) { 1915 case WMI_NUDGE_TWT_STATUS_OK: 1916 return WMI_HOST_NUDGE_TWT_STATUS_OK; 1917 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1918 return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1919 case WMI_NUDGE_TWT_STATUS_INVALID_PARAM: 1920 return WMI_HOST_NUDGE_TWT_STATUS_INVALID_PARAM; 1921 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_BUSY: 1922 return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_BUSY; 1923 case WMI_NUDGE_TWT_STATUS_NO_RESOURCE: 1924 return WMI_HOST_NUDGE_TWT_STATUS_NO_RESOURCE; 1925 case WMI_NUDGE_TWT_STATUS_NO_ACK: 1926 return WMI_HOST_NUDGE_TWT_STATUS_NO_ACK; 1927 case WMI_NUDGE_TWT_STATUS_UNKNOWN_ERROR: 1928 return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR; 1929 case WMI_NUDGE_TWT_STATUS_ALREADY_PAUSED: 1930 return WMI_HOST_NUDGE_TWT_STATUS_ALREADY_PAUSED; 1931 case WMI_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1932 return WMI_HOST_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1933 case WMI_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS: 1934 return WMI_HOST_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS; 1935 case WMI_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS: 1936 return WMI_HOST_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS; 1937 default: 1938 return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR; 1939 } 1940 } 1941 1942 static QDF_STATUS extract_twt_nudge_dialog_comp_event_tlv( 1943 wmi_unified_t wmi_handle, 1944 uint8_t *evt_buf, 1945 struct wmi_twt_nudge_dialog_complete_event_param *params) 1946 { 1947 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1948 wmi_twt_nudge_dialog_complete_event_fixed_param *ev; 1949 1950 param_buf = (WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1951 if (!param_buf) { 1952 wmi_err("evt_buf is NULL"); 1953 return QDF_STATUS_E_INVAL; 1954 } 1955 1956 ev = param_buf->fixed_param; 1957 1958 params->vdev_id = ev->vdev_id; 1959 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1960 params->status = wmi_twt_nudge_status_to_host_twt_status(ev->status); 1961 params->dialog_id = ev->dialog_id; 1962 params->next_twt_tsf_us_lo = ev->sp_tsf_us_lo; 1963 params->next_twt_tsf_us_hi = ev->sp_tsf_us_hi; 1964 1965 wmi_debug("vdev_id: %d dialog_id: %d tsf hi : %x tsf lo: %x", 1966 params->vdev_id, params->dialog_id, 1967 params->next_twt_tsf_us_hi, params->next_twt_tsf_us_lo); 1968 1969 return QDF_STATUS_SUCCESS; 1970 } 1971 1972 static enum WMI_HOST_RESUME_TWT_STATUS 1973 wmi_get_converted_twt_resume_dialog_status(WMI_RESUME_TWT_STATUS_T tgt_status) 1974 { 1975 switch (tgt_status) { 1976 case WMI_RESUME_TWT_STATUS_OK: 1977 return WMI_HOST_RESUME_TWT_STATUS_OK; 1978 case WMI_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1979 return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1980 case WMI_RESUME_TWT_STATUS_INVALID_PARAM: 1981 return WMI_HOST_RESUME_TWT_STATUS_INVALID_PARAM; 1982 case WMI_RESUME_TWT_STATUS_DIALOG_ID_BUSY: 1983 return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_BUSY; 1984 case WMI_RESUME_TWT_STATUS_NOT_PAUSED: 1985 return WMI_HOST_RESUME_TWT_STATUS_NOT_PAUSED; 1986 case WMI_RESUME_TWT_STATUS_NO_RESOURCE: 1987 return WMI_HOST_RESUME_TWT_STATUS_NO_RESOURCE; 1988 case WMI_RESUME_TWT_STATUS_NO_ACK: 1989 return WMI_HOST_RESUME_TWT_STATUS_NO_ACK; 1990 case WMI_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1991 return WMI_HOST_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1992 case WMI_RESUME_TWT_STATUS_ROAM_IN_PROGRESS: 1993 return WMI_HOST_RESUME_TWT_STATUS_ROAM_IN_PROGRESS; 1994 case WMI_RESUME_TWT_STATUS_SCAN_IN_PROGRESS: 1995 return WMI_HOST_RESUME_TWT_STATUS_SCAN_IN_PROGRESS; 1996 default: 1997 return WMI_HOST_RESUME_TWT_STATUS_UNKNOWN_ERROR; 1998 } 1999 } 2000 2001 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv( 2002 wmi_unified_t wmi_handle, 2003 uint8_t *evt_buf, 2004 struct wmi_twt_resume_dialog_complete_event_param *params) 2005 { 2006 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 2007 wmi_twt_resume_dialog_complete_event_fixed_param *ev; 2008 2009 param_buf = 2010 (WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 2011 if (!param_buf) { 2012 wmi_err("evt_buf is NULL"); 2013 return QDF_STATUS_E_INVAL; 2014 } 2015 2016 ev = param_buf->fixed_param; 2017 2018 params->vdev_id = ev->vdev_id; 2019 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 2020 params->status = wmi_get_converted_twt_resume_dialog_status(ev->status); 2021 params->dialog_id = ev->dialog_id; 2022 2023 return QDF_STATUS_SUCCESS; 2024 } 2025 2026 static QDF_STATUS extract_twt_notify_event_tlv( 2027 wmi_unified_t wmi_handle, 2028 uint8_t *evt_buf, 2029 struct wmi_twt_notify_event_param *params) 2030 { 2031 WMI_TWT_NOTIFY_EVENTID_param_tlvs *param_buf; 2032 wmi_twt_notify_event_fixed_param *ev; 2033 2034 param_buf = 2035 (WMI_TWT_NOTIFY_EVENTID_param_tlvs *)evt_buf; 2036 if (!param_buf) { 2037 wmi_err("evt_buf is NULL"); 2038 return QDF_STATUS_E_INVAL; 2039 } 2040 2041 ev = param_buf->fixed_param; 2042 2043 params->vdev_id = ev->vdev_id; 2044 2045 return QDF_STATUS_SUCCESS; 2046 } 2047 2048 #ifdef WLAN_SUPPORT_BCAST_TWT 2049 static QDF_STATUS 2050 extract_twt_btwt_invite_sta_comp_event_tlv( 2051 wmi_unified_t wmi_handle, 2052 uint8_t *evt_buf, 2053 struct 2054 wmi_twt_btwt_invite_sta_complete_event_param 2055 *params) 2056 { 2057 WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 2058 wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev; 2059 2060 param_buf = 2061 (WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 2062 if (!param_buf) { 2063 wmi_err("evt_buf is NULL"); 2064 return QDF_STATUS_E_INVAL; 2065 } 2066 2067 ev = param_buf->fixed_param; 2068 2069 params->vdev_id = ev->vdev_id; 2070 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 2071 params->status = ev->status; 2072 params->dialog_id = ev->dialog_id; 2073 2074 return QDF_STATUS_SUCCESS; 2075 } 2076 2077 static QDF_STATUS 2078 extract_twt_btwt_remove_sta_comp_event_tlv( 2079 wmi_unified_t wmi_handle, 2080 uint8_t *evt_buf, 2081 struct 2082 wmi_twt_btwt_remove_sta_complete_event_param 2083 *params) 2084 { 2085 WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 2086 wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev; 2087 2088 param_buf = 2089 (WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 2090 if (!param_buf) { 2091 wmi_err("evt_buf is NULL"); 2092 return QDF_STATUS_E_INVAL; 2093 } 2094 2095 ev = param_buf->fixed_param; 2096 2097 params->vdev_id = ev->vdev_id; 2098 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 2099 params->status = ev->status; 2100 params->dialog_id = ev->dialog_id; 2101 2102 return QDF_STATUS_SUCCESS; 2103 } 2104 #endif 2105 2106 #ifdef WLAN_SUPPORT_BCAST_TWT 2107 static void 2108 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 2109 { 2110 ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv; 2111 ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv; 2112 ops->extract_twt_btwt_invite_sta_comp_event = 2113 extract_twt_btwt_invite_sta_comp_event_tlv; 2114 ops->extract_twt_btwt_remove_sta_comp_event = 2115 extract_twt_btwt_remove_sta_comp_event_tlv; 2116 } 2117 #else 2118 static void 2119 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 2120 { 2121 } 2122 #endif 2123 2124 static QDF_STATUS 2125 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle, 2126 uint8_t *evt_buf, 2127 struct wmi_twt_session_stats_event_param 2128 *params) 2129 { 2130 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 2131 wmi_pdev_twt_session_stats_event_fixed_param *ev; 2132 2133 param_buf = 2134 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 2135 if (!param_buf) { 2136 wmi_err("evt_buf is NULL"); 2137 return QDF_STATUS_E_INVAL; 2138 } 2139 2140 ev = param_buf->fixed_param; 2141 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 2142 wmi_handle, 2143 ev->pdev_id); 2144 params->num_sessions = param_buf->num_twt_sessions; 2145 2146 wmi_debug("pdev_id=%d, num of TWT sessions=%d", 2147 params->pdev_id, params->num_sessions); 2148 2149 return QDF_STATUS_SUCCESS; 2150 } 2151 2152 static QDF_STATUS 2153 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, 2154 uint8_t *evt_buf, 2155 struct wmi_twt_session_stats_event_param 2156 *params, 2157 struct wmi_host_twt_session_stats_info 2158 *session, 2159 uint32_t idx) 2160 { 2161 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 2162 wmi_twt_session_stats_info *twt_session; 2163 uint32_t flags; 2164 wmi_mac_addr *m1; 2165 uint8_t *m2; 2166 2167 param_buf = 2168 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 2169 if (!param_buf) { 2170 wmi_err("evt_buf is NULL"); 2171 return QDF_STATUS_E_INVAL; 2172 } 2173 2174 if (idx >= param_buf->num_twt_sessions) { 2175 wmi_err("wrong idx, idx=%d, num_sessions=%d", 2176 idx, param_buf->num_twt_sessions); 2177 return QDF_STATUS_E_INVAL; 2178 } 2179 2180 twt_session = ¶m_buf->twt_sessions[idx]; 2181 2182 session->vdev_id = twt_session->vdev_id; 2183 m1 = &twt_session->peer_mac; 2184 m2 = session->peer_mac; 2185 WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2); 2186 session->event_type = twt_session->event_type; 2187 flags = twt_session->flow_id_flags; 2188 session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags); 2189 session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags); 2190 session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags); 2191 session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags); 2192 session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags); 2193 session->info_frame_disabled = 2194 WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags); 2195 session->pm_responder_bit = 2196 WMI_TWT_SESSION_FLAG_TWT_PM_RESPONDER_MODE_GET(flags); 2197 session->pm_responder_bit_valid = 2198 WMI_TWT_SESSION_FLAG_TWT_PM_RESPONDER_MODE_VALID_GET(flags); 2199 session->dialog_id = twt_session->dialog_id; 2200 session->wake_dura_us = twt_session->wake_dura_us; 2201 session->wake_intvl_us = twt_session->wake_intvl_us; 2202 session->sp_offset_us = twt_session->sp_offset_us; 2203 session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo; 2204 session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi; 2205 wmi_debug("type=%d id=%d bcast=%d trig=%d announ=%d diagid=%d wake_dur=%ul wake_int=%ul offset=%ul", 2206 session->event_type, session->flow_id, 2207 session->bcast, session->trig, 2208 session->announ, session->dialog_id, session->wake_dura_us, 2209 session->wake_intvl_us, session->sp_offset_us); 2210 wmi_debug("resp_pm_valid=%d resp_pm=%d", 2211 session->pm_responder_bit_valid, session->pm_responder_bit); 2212 2213 return QDF_STATUS_SUCCESS; 2214 } 2215 2216 static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( 2217 wmi_unified_t wmi_handle, uint8_t *event, 2218 struct wmi_twt_cap_bitmap_params *var) 2219 { 2220 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 2221 wmi_twt_caps_params *twt_caps; 2222 2223 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 2224 if (!param_buf) 2225 return QDF_STATUS_E_INVAL; 2226 2227 twt_caps = param_buf->twt_caps; 2228 if (!twt_caps) 2229 return QDF_STATUS_E_INVAL; 2230 2231 var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap, 2232 0, 1); 2233 2234 return QDF_STATUS_SUCCESS; 2235 } 2236 2237 static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT 2238 wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd) 2239 { 2240 switch (tgt_cmd) { 2241 case WMI_TWT_ADD_DIALOG_CMDID: 2242 return WMI_HOST_TWT_ADD_DIALOG_CMDID; 2243 case WMI_TWT_DEL_DIALOG_CMDID: 2244 return WMI_HOST_TWT_DEL_DIALOG_CMDID; 2245 case WMI_TWT_PAUSE_DIALOG_CMDID: 2246 return WMI_HOST_TWT_PAUSE_DIALOG_CMDID; 2247 case WMI_TWT_RESUME_DIALOG_CMDID: 2248 return WMI_HOST_TWT_RESUME_DIALOG_CMDID; 2249 case WMI_TWT_NUDGE_DIALOG_CMDID: 2250 return WMI_HOST_TWT_NUDGE_DIALOG_CMDID; 2251 default: 2252 return WMI_HOST_TWT_UNKNOWN_CMDID; 2253 } 2254 } 2255 2256 static QDF_STATUS 2257 extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle, 2258 uint8_t *evt_buf, 2259 struct wmi_twt_ack_complete_event_param *var) 2260 { 2261 WMI_TWT_ACK_EVENTID_param_tlvs *param_buf; 2262 wmi_twt_ack_event_fixed_param *ack_event; 2263 2264 param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf; 2265 if (!param_buf) { 2266 wmi_err("evt_buf is NULL"); 2267 return QDF_STATUS_E_INVAL; 2268 } 2269 2270 ack_event = param_buf->fixed_param; 2271 2272 var->vdev_id = ack_event->vdev_id; 2273 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr, 2274 var->peer_macaddr.bytes); 2275 var->dialog_id = ack_event->dialog_id; 2276 var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event( 2277 ack_event->twt_cmd); 2278 2279 switch (ack_event->twt_cmd) { 2280 case WMI_TWT_ADD_DIALOG_CMDID: 2281 var->status = wmi_get_converted_twt_add_dialog_status( 2282 ack_event->status); 2283 break; 2284 case WMI_TWT_DEL_DIALOG_CMDID: 2285 var->status = wmi_get_converted_twt_del_dialog_status( 2286 ack_event->status); 2287 break; 2288 case WMI_TWT_PAUSE_DIALOG_CMDID: 2289 var->status = wmi_twt_pause_status_to_host_twt_status( 2290 ack_event->status); 2291 break; 2292 case WMI_TWT_RESUME_DIALOG_CMDID: 2293 var->status = wmi_get_converted_twt_resume_dialog_status( 2294 ack_event->status); 2295 break; 2296 case WMI_TWT_NUDGE_DIALOG_CMDID: 2297 var->status = wmi_twt_nudge_status_to_host_twt_status( 2298 ack_event->status); 2299 break; 2300 default: 2301 break; 2302 } 2303 return QDF_STATUS_SUCCESS; 2304 } 2305 #endif 2306 2307 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) 2308 { 2309 struct wmi_ops *ops = wmi_handle->ops; 2310 2311 ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv; 2312 ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv; 2313 ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv; 2314 ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv; 2315 ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv; 2316 ops->send_twt_nudge_dialog_cmd = send_twt_nudge_dialog_cmd_tlv; 2317 ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv; 2318 ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv; 2319 ops->extract_twt_disable_comp_event = 2320 extract_twt_disable_comp_event_tlv; 2321 ops->extract_twt_add_dialog_comp_event = 2322 extract_twt_add_dialog_comp_event_tlv; 2323 ops->extract_twt_add_dialog_comp_additional_params = 2324 extract_twt_add_dialog_comp_additional_parameters; 2325 ops->extract_twt_del_dialog_comp_event = 2326 extract_twt_del_dialog_comp_event_tlv; 2327 ops->extract_twt_pause_dialog_comp_event = 2328 extract_twt_pause_dialog_comp_event_tlv; 2329 ops->extract_twt_nudge_dialog_comp_event = 2330 extract_twt_nudge_dialog_comp_event_tlv; 2331 ops->extract_twt_resume_dialog_comp_event = 2332 extract_twt_resume_dialog_comp_event_tlv; 2333 ops->extract_twt_session_stats_event = 2334 extract_twt_session_stats_event_tlv; 2335 ops->extract_twt_session_stats_data = 2336 extract_twt_session_stats_event_data; 2337 ops->extract_twt_notify_event = 2338 extract_twt_notify_event_tlv; 2339 ops->extract_twt_cap_service_ready_ext2 = 2340 extract_twt_cap_service_ready_ext2_tlv, 2341 ops->extract_twt_ack_comp_event = extract_twt_ack_comp_event_tlv; 2342 wmi_twt_attach_bcast_twt_tlv(ops); 2343 } 2344