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 additional_params->pm_responder_bit_valid = 676 TWT_FLAGS_GET_PM_RESPONDER_MODE_VALID(flags); 677 additional_params->pm_responder_bit = 678 TWT_FLAGS_GET_PM_RESPONDER_MODE(flags); 679 680 return QDF_STATUS_SUCCESS; 681 } 682 683 static enum HOST_TWT_DEL_STATUS 684 wmi_get_converted_twt_del_dialog_status(WMI_DEL_TWT_STATUS_T tgt_status) 685 { 686 switch (tgt_status) { 687 case WMI_DEL_TWT_STATUS_OK: 688 return HOST_TWT_DEL_STATUS_OK; 689 case WMI_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST: 690 return HOST_TWT_DEL_STATUS_DIALOG_ID_NOT_EXIST; 691 case WMI_DEL_TWT_STATUS_INVALID_PARAM: 692 return HOST_TWT_DEL_STATUS_INVALID_PARAM; 693 case WMI_DEL_TWT_STATUS_DIALOG_ID_BUSY: 694 return HOST_TWT_DEL_STATUS_DIALOG_ID_BUSY; 695 case WMI_DEL_TWT_STATUS_NO_RESOURCE: 696 return HOST_TWT_DEL_STATUS_NO_RESOURCE; 697 case WMI_DEL_TWT_STATUS_NO_ACK: 698 return HOST_TWT_DEL_STATUS_NO_ACK; 699 case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN: 700 return HOST_TWT_DEL_STATUS_PEER_INIT_TEARDOWN; 701 case WMI_DEL_TWT_STATUS_ROAMING: 702 return HOST_TWT_DEL_STATUS_ROAMING; 703 case WMI_DEL_TWT_STATUS_CONCURRENCY: 704 return HOST_TWT_DEL_STATUS_CONCURRENCY; 705 case WMI_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS: 706 return HOST_TWT_DEL_STATUS_CHAN_SW_IN_PROGRESS; 707 case WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS: 708 return HOST_TWT_DEL_STATUS_SCAN_IN_PROGRESS; 709 default: 710 return HOST_TWT_DEL_STATUS_UNKNOWN_ERROR; 711 } 712 } 713 714 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv( 715 wmi_unified_t wmi_handle, 716 uint8_t *evt_buf, 717 struct twt_del_dialog_complete_event_param *params) 718 { 719 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 720 wmi_twt_del_dialog_complete_event_fixed_param *ev; 721 722 param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 723 if (!param_buf) { 724 wmi_err("evt_buf is NULL"); 725 return QDF_STATUS_E_INVAL; 726 } 727 728 ev = param_buf->fixed_param; 729 730 params->vdev_id = ev->vdev_id; 731 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 732 params->peer_macaddr.bytes); 733 params->dialog_id = ev->dialog_id; 734 params->status = wmi_get_converted_twt_del_dialog_status(ev->status); 735 736 return QDF_STATUS_SUCCESS; 737 } 738 739 static enum HOST_TWT_PAUSE_STATUS 740 wmi_twt_pause_status_to_host_twt_status(WMI_PAUSE_TWT_STATUS_T status) 741 { 742 switch (status) { 743 case WMI_PAUSE_TWT_STATUS_OK: 744 return HOST_TWT_PAUSE_STATUS_OK; 745 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 746 return HOST_TWT_PAUSE_STATUS_DIALOG_ID_NOT_EXIST; 747 case WMI_PAUSE_TWT_STATUS_INVALID_PARAM: 748 return HOST_TWT_PAUSE_STATUS_INVALID_PARAM; 749 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_BUSY: 750 return HOST_TWT_PAUSE_STATUS_DIALOG_ID_BUSY; 751 case WMI_PAUSE_TWT_STATUS_NO_RESOURCE: 752 return HOST_TWT_PAUSE_STATUS_NO_RESOURCE; 753 case WMI_PAUSE_TWT_STATUS_NO_ACK: 754 return HOST_TWT_PAUSE_STATUS_NO_ACK; 755 case WMI_PAUSE_TWT_STATUS_ALREADY_PAUSED: 756 return HOST_TWT_PAUSE_STATUS_ALREADY_PAUSED; 757 case WMI_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 758 return HOST_TWT_PAUSE_STATUS_CHAN_SW_IN_PROGRESS; 759 case WMI_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS: 760 return HOST_TWT_PAUSE_STATUS_ROAM_IN_PROGRESS; 761 case WMI_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS: 762 return HOST_TWT_PAUSE_STATUS_SCAN_IN_PROGRESS; 763 default: 764 return HOST_TWT_PAUSE_STATUS_UNKNOWN_ERROR; 765 } 766 } 767 768 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv( 769 wmi_unified_t wmi_handle, 770 uint8_t *evt_buf, 771 struct twt_pause_dialog_complete_event_param *params) 772 { 773 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 774 wmi_twt_pause_dialog_complete_event_fixed_param *ev; 775 776 param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 777 if (!param_buf) { 778 wmi_err("evt_buf is NULL"); 779 return QDF_STATUS_E_INVAL; 780 } 781 782 ev = param_buf->fixed_param; 783 784 params->vdev_id = ev->vdev_id; 785 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 786 params->peer_macaddr.bytes); 787 params->status = wmi_twt_pause_status_to_host_twt_status(ev->status); 788 params->dialog_id = ev->dialog_id; 789 790 return QDF_STATUS_SUCCESS; 791 } 792 793 static enum HOST_TWT_NUDGE_STATUS 794 wmi_twt_nudge_status_to_host_twt_status(WMI_TWT_NUDGE_STATUS_T status) 795 { 796 switch (status) { 797 case WMI_NUDGE_TWT_STATUS_OK: 798 return HOST_TWT_NUDGE_STATUS_OK; 799 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 800 return HOST_TWT_NUDGE_STATUS_DIALOG_ID_NOT_EXIST; 801 case WMI_NUDGE_TWT_STATUS_INVALID_PARAM: 802 return HOST_TWT_NUDGE_STATUS_INVALID_PARAM; 803 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_BUSY: 804 return HOST_TWT_NUDGE_STATUS_DIALOG_ID_BUSY; 805 case WMI_NUDGE_TWT_STATUS_NO_RESOURCE: 806 return HOST_TWT_NUDGE_STATUS_NO_RESOURCE; 807 case WMI_NUDGE_TWT_STATUS_NO_ACK: 808 return HOST_TWT_NUDGE_STATUS_NO_ACK; 809 case WMI_NUDGE_TWT_STATUS_ALREADY_PAUSED: 810 return HOST_TWT_NUDGE_STATUS_ALREADY_PAUSED; 811 case WMI_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 812 return HOST_TWT_NUDGE_STATUS_CHAN_SW_IN_PROGRESS; 813 case WMI_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS: 814 return HOST_TWT_NUDGE_STATUS_ROAM_IN_PROGRESS; 815 case WMI_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS: 816 return HOST_TWT_NUDGE_STATUS_SCAN_IN_PROGRESS; 817 default: 818 return HOST_TWT_NUDGE_STATUS_UNKNOWN_ERROR; 819 } 820 } 821 822 static QDF_STATUS extract_twt_nudge_dialog_comp_event_tlv( 823 wmi_unified_t wmi_handle, 824 uint8_t *evt_buf, 825 struct twt_nudge_dialog_complete_event_param *params) 826 { 827 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 828 wmi_twt_nudge_dialog_complete_event_fixed_param *ev; 829 830 param_buf = (WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 831 if (!param_buf) { 832 wmi_err("evt_buf is NULL"); 833 return QDF_STATUS_E_INVAL; 834 } 835 836 ev = param_buf->fixed_param; 837 838 params->vdev_id = ev->vdev_id; 839 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 840 params->peer_macaddr.bytes); 841 params->status = wmi_twt_nudge_status_to_host_twt_status(ev->status); 842 params->dialog_id = ev->dialog_id; 843 params->next_twt_tsf_us_lo = ev->sp_tsf_us_lo; 844 params->next_twt_tsf_us_hi = ev->sp_tsf_us_hi; 845 846 wmi_debug("vdev_id: %d dialog_id: %d tsf hi : %x tsf lo: %x", 847 params->vdev_id, params->dialog_id, 848 params->next_twt_tsf_us_hi, params->next_twt_tsf_us_lo); 849 850 return QDF_STATUS_SUCCESS; 851 } 852 853 static enum HOST_TWT_RESUME_STATUS 854 wmi_get_converted_twt_resume_dialog_status(WMI_RESUME_TWT_STATUS_T tgt_status) 855 { 856 switch (tgt_status) { 857 case WMI_RESUME_TWT_STATUS_OK: 858 return HOST_TWT_RESUME_STATUS_OK; 859 case WMI_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST: 860 return HOST_TWT_RESUME_STATUS_DIALOG_ID_NOT_EXIST; 861 case WMI_RESUME_TWT_STATUS_INVALID_PARAM: 862 return HOST_TWT_RESUME_STATUS_INVALID_PARAM; 863 case WMI_RESUME_TWT_STATUS_DIALOG_ID_BUSY: 864 return HOST_TWT_RESUME_STATUS_DIALOG_ID_BUSY; 865 case WMI_RESUME_TWT_STATUS_NOT_PAUSED: 866 return HOST_TWT_RESUME_STATUS_NOT_PAUSED; 867 case WMI_RESUME_TWT_STATUS_NO_RESOURCE: 868 return HOST_TWT_RESUME_STATUS_NO_RESOURCE; 869 case WMI_RESUME_TWT_STATUS_NO_ACK: 870 return HOST_TWT_RESUME_STATUS_NO_ACK; 871 case WMI_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS: 872 return HOST_TWT_RESUME_STATUS_CHAN_SW_IN_PROGRESS; 873 case WMI_RESUME_TWT_STATUS_ROAM_IN_PROGRESS: 874 return HOST_TWT_RESUME_STATUS_ROAM_IN_PROGRESS; 875 case WMI_RESUME_TWT_STATUS_SCAN_IN_PROGRESS: 876 return HOST_TWT_RESUME_STATUS_SCAN_IN_PROGRESS; 877 default: 878 return HOST_TWT_RESUME_STATUS_UNKNOWN_ERROR; 879 } 880 } 881 882 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv( 883 wmi_unified_t wmi_handle, 884 uint8_t *evt_buf, 885 struct twt_resume_dialog_complete_event_param *params) 886 { 887 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 888 wmi_twt_resume_dialog_complete_event_fixed_param *ev; 889 890 param_buf = 891 (WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 892 if (!param_buf) { 893 wmi_err("evt_buf is NULL"); 894 return QDF_STATUS_E_INVAL; 895 } 896 897 ev = param_buf->fixed_param; 898 899 params->vdev_id = ev->vdev_id; 900 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 901 params->peer_macaddr.bytes); 902 params->status = wmi_get_converted_twt_resume_dialog_status(ev->status); 903 params->dialog_id = ev->dialog_id; 904 905 return QDF_STATUS_SUCCESS; 906 } 907 908 static enum HOST_TWT_NOTIFY_STATUS 909 wmi_get_converted_twt_notify_status(WMI_TWT_NOTIFICATION_ID_T tgt_status) 910 { 911 switch (tgt_status) { 912 case WMI_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_SET: 913 return HOST_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_SET; 914 case WMI_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_CLEAR: 915 return HOST_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_CLEAR; 916 default: 917 return HOST_TWT_NOTIFY_EVENT_READY; 918 } 919 } 920 921 static QDF_STATUS extract_twt_notify_event_tlv( 922 wmi_unified_t wmi_handle, 923 uint8_t *evt_buf, 924 struct twt_notify_event_param *params) 925 { 926 WMI_TWT_NOTIFY_EVENTID_param_tlvs *param_buf; 927 wmi_twt_notify_event_fixed_param *ev; 928 929 param_buf = 930 (WMI_TWT_NOTIFY_EVENTID_param_tlvs *)evt_buf; 931 if (!param_buf) { 932 wmi_err("evt_buf is NULL"); 933 return QDF_STATUS_E_INVAL; 934 } 935 936 ev = param_buf->fixed_param; 937 938 if (ev->event_id > WMI_TWT_NOTIFY_EVENT_AP_TWT_REQ_BIT_CLEAR) { 939 wmi_debug("Incorrect TWT notify event vdev_id: %d, status: %d", 940 ev->vdev_id, ev->event_id); 941 return QDF_STATUS_E_INVAL; 942 } 943 944 params->vdev_id = ev->vdev_id; 945 params->status = wmi_get_converted_twt_notify_status(ev->event_id); 946 947 wmi_debug("Extract notify event vdev_id: %d, status: %d", 948 params->vdev_id, params->status); 949 950 return QDF_STATUS_SUCCESS; 951 } 952 953 #ifdef WLAN_SUPPORT_BCAST_TWT 954 static QDF_STATUS 955 extract_twt_btwt_invite_sta_comp_event_tlv( 956 wmi_unified_t wmi_handle, 957 uint8_t *evt_buf, 958 struct 959 twt_btwt_invite_sta_complete_event_param 960 *params) 961 { 962 WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 963 wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev; 964 965 param_buf = 966 (WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 967 if (!param_buf) { 968 wmi_err("evt_buf is NULL"); 969 return QDF_STATUS_E_INVAL; 970 } 971 972 ev = param_buf->fixed_param; 973 974 params->vdev_id = ev->vdev_id; 975 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 976 params->peer_macaddr.bytes); 977 params->status = ev->status; 978 params->dialog_id = ev->dialog_id; 979 980 return QDF_STATUS_SUCCESS; 981 } 982 983 static QDF_STATUS 984 extract_twt_btwt_remove_sta_comp_event_tlv( 985 wmi_unified_t wmi_handle, 986 uint8_t *evt_buf, 987 struct 988 twt_btwt_remove_sta_complete_event_param 989 *params) 990 { 991 WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 992 wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev; 993 994 param_buf = 995 (WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 996 if (!param_buf) { 997 wmi_err("evt_buf is NULL"); 998 return QDF_STATUS_E_INVAL; 999 } 1000 1001 ev = param_buf->fixed_param; 1002 1003 params->vdev_id = ev->vdev_id; 1004 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 1005 params->peer_macaddr.bytes); 1006 params->status = ev->status; 1007 params->dialog_id = ev->dialog_id; 1008 1009 return QDF_STATUS_SUCCESS; 1010 } 1011 #endif 1012 1013 #ifdef WLAN_SUPPORT_BCAST_TWT 1014 static void 1015 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 1016 { 1017 ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv; 1018 ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv; 1019 ops->extract_twt_btwt_invite_sta_comp_event = 1020 extract_twt_btwt_invite_sta_comp_event_tlv; 1021 ops->extract_twt_btwt_remove_sta_comp_event = 1022 extract_twt_btwt_remove_sta_comp_event_tlv; 1023 } 1024 #else 1025 static void 1026 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 1027 { 1028 } 1029 #endif 1030 1031 static QDF_STATUS 1032 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle, 1033 uint8_t *evt_buf, 1034 struct twt_session_stats_event_param 1035 *params) 1036 { 1037 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 1038 wmi_pdev_twt_session_stats_event_fixed_param *ev; 1039 1040 param_buf = 1041 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 1042 if (!param_buf) { 1043 wmi_err("evt_buf is NULL"); 1044 return QDF_STATUS_E_INVAL; 1045 } 1046 1047 ev = param_buf->fixed_param; 1048 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 1049 wmi_handle, 1050 ev->pdev_id); 1051 params->num_sessions = param_buf->num_twt_sessions; 1052 1053 wmi_debug("pdev_id=%d, num of TWT sessions=%d", 1054 params->pdev_id, params->num_sessions); 1055 1056 return QDF_STATUS_SUCCESS; 1057 } 1058 1059 static QDF_STATUS 1060 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, 1061 uint8_t *evt_buf, 1062 struct twt_session_stats_event_param 1063 *params, 1064 struct twt_session_stats_info 1065 *session, 1066 uint32_t idx) 1067 { 1068 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 1069 wmi_twt_session_stats_info *twt_session; 1070 uint32_t flags; 1071 wmi_mac_addr *m1; 1072 uint8_t *m2; 1073 1074 param_buf = 1075 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 1076 if (!param_buf) { 1077 wmi_err("evt_buf is NULL"); 1078 return QDF_STATUS_E_INVAL; 1079 } 1080 1081 if (idx >= param_buf->num_twt_sessions) { 1082 wmi_err("wrong idx, idx=%d, num_sessions=%d", 1083 idx, param_buf->num_twt_sessions); 1084 return QDF_STATUS_E_INVAL; 1085 } 1086 1087 twt_session = ¶m_buf->twt_sessions[idx]; 1088 1089 session->vdev_id = twt_session->vdev_id; 1090 m1 = &twt_session->peer_mac; 1091 m2 = session->peer_mac.bytes; 1092 WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2); 1093 session->event_type = twt_session->event_type; 1094 flags = twt_session->flow_id_flags; 1095 session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags); 1096 session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags); 1097 session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags); 1098 session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags); 1099 session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags); 1100 session->info_frame_disabled = 1101 WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags); 1102 session->pm_responder_bit = 1103 WMI_TWT_SESSION_FLAG_TWT_PM_RESPONDER_MODE_GET(flags); 1104 session->pm_responder_bit_valid = 1105 WMI_TWT_SESSION_FLAG_TWT_PM_RESPONDER_MODE_VALID_GET(flags); 1106 session->dialog_id = twt_session->dialog_id; 1107 session->wake_dura_us = twt_session->wake_dura_us; 1108 session->wake_intvl_us = twt_session->wake_intvl_us; 1109 session->sp_offset_us = twt_session->sp_offset_us; 1110 session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo; 1111 session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi; 1112 wmi_debug("type=%d id=%d bcast=%d trig=%d announ=%d diagid=%d wake_dur=%ul wake_int=%ul offset=%ul", 1113 session->event_type, session->flow_id, 1114 session->bcast, session->trig, 1115 session->announ, session->dialog_id, session->wake_dura_us, 1116 session->wake_intvl_us, session->sp_offset_us); 1117 wmi_debug("resp_pm_valid=%d resp_pm=%d", 1118 session->pm_responder_bit_valid, session->pm_responder_bit); 1119 1120 return QDF_STATUS_SUCCESS; 1121 } 1122 1123 static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( 1124 wmi_unified_t wmi_handle, uint8_t *event, 1125 struct wmi_twt_cap_bitmap_params *var) 1126 { 1127 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 1128 wmi_twt_caps_params *twt_caps; 1129 1130 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 1131 if (!param_buf) 1132 return QDF_STATUS_E_INVAL; 1133 1134 twt_caps = param_buf->twt_caps; 1135 if (!twt_caps) 1136 return QDF_STATUS_E_INVAL; 1137 1138 var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap, 1139 0, 1); 1140 1141 return QDF_STATUS_SUCCESS; 1142 } 1143 1144 static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT 1145 wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd) 1146 { 1147 switch (tgt_cmd) { 1148 case WMI_TWT_ADD_DIALOG_CMDID: 1149 return WMI_HOST_TWT_ADD_DIALOG_CMDID; 1150 case WMI_TWT_DEL_DIALOG_CMDID: 1151 return WMI_HOST_TWT_DEL_DIALOG_CMDID; 1152 case WMI_TWT_PAUSE_DIALOG_CMDID: 1153 return WMI_HOST_TWT_PAUSE_DIALOG_CMDID; 1154 case WMI_TWT_RESUME_DIALOG_CMDID: 1155 return WMI_HOST_TWT_RESUME_DIALOG_CMDID; 1156 case WMI_TWT_NUDGE_DIALOG_CMDID: 1157 return WMI_HOST_TWT_NUDGE_DIALOG_CMDID; 1158 default: 1159 return WMI_HOST_TWT_UNKNOWN_CMDID; 1160 } 1161 } 1162 1163 static QDF_STATUS 1164 extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle, 1165 uint8_t *evt_buf, 1166 struct twt_ack_complete_event_param *var) 1167 { 1168 WMI_TWT_ACK_EVENTID_param_tlvs *param_buf; 1169 wmi_twt_ack_event_fixed_param *ack_event; 1170 1171 param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf; 1172 if (!param_buf) { 1173 wmi_err("evt_buf is NULL"); 1174 return QDF_STATUS_E_INVAL; 1175 } 1176 1177 ack_event = param_buf->fixed_param; 1178 1179 var->vdev_id = ack_event->vdev_id; 1180 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr, 1181 var->peer_macaddr.bytes); 1182 var->dialog_id = ack_event->dialog_id; 1183 var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event( 1184 ack_event->twt_cmd); 1185 1186 switch (ack_event->twt_cmd) { 1187 case WMI_TWT_ADD_DIALOG_CMDID: 1188 var->status = wmi_get_converted_twt_add_dialog_status( 1189 ack_event->status); 1190 break; 1191 case WMI_TWT_DEL_DIALOG_CMDID: 1192 var->status = wmi_get_converted_twt_del_dialog_status( 1193 ack_event->status); 1194 break; 1195 case WMI_TWT_PAUSE_DIALOG_CMDID: 1196 var->status = wmi_twt_pause_status_to_host_twt_status( 1197 ack_event->status); 1198 break; 1199 case WMI_TWT_RESUME_DIALOG_CMDID: 1200 var->status = wmi_get_converted_twt_resume_dialog_status( 1201 ack_event->status); 1202 break; 1203 case WMI_TWT_NUDGE_DIALOG_CMDID: 1204 var->status = wmi_twt_nudge_status_to_host_twt_status( 1205 ack_event->status); 1206 break; 1207 default: 1208 break; 1209 } 1210 return QDF_STATUS_SUCCESS; 1211 } 1212 #elif WLAN_SUPPORT_TWT 1213 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle, 1214 struct wmi_twt_enable_param *params) 1215 { 1216 wmi_twt_enable_cmd_fixed_param *cmd; 1217 wmi_buf_t buf; 1218 QDF_STATUS status; 1219 1220 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1221 if (!buf) { 1222 wmi_err("Failed to allocate memory"); 1223 return QDF_STATUS_E_FAILURE; 1224 } 1225 1226 cmd = (wmi_twt_enable_cmd_fixed_param *) wmi_buf_data(buf); 1227 WMITLV_SET_HDR(&cmd->tlv_header, 1228 WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param, 1229 WMITLV_GET_STRUCT_TLVLEN 1230 (wmi_twt_enable_cmd_fixed_param)); 1231 1232 cmd->pdev_id = 1233 wmi_handle->ops->convert_pdev_id_host_to_target( 1234 wmi_handle, 1235 params->pdev_id); 1236 cmd->sta_cong_timer_ms = params->sta_cong_timer_ms; 1237 cmd->mbss_support = params->mbss_support; 1238 cmd->default_slot_size = params->default_slot_size; 1239 cmd->congestion_thresh_setup = params->congestion_thresh_setup; 1240 cmd->congestion_thresh_teardown = params->congestion_thresh_teardown; 1241 cmd->congestion_thresh_critical = params->congestion_thresh_critical; 1242 cmd->interference_thresh_teardown = 1243 params->interference_thresh_teardown; 1244 cmd->interference_thresh_setup = params->interference_thresh_setup; 1245 cmd->min_no_sta_setup = params->min_no_sta_setup; 1246 cmd->min_no_sta_teardown = params->min_no_sta_teardown; 1247 cmd->no_of_bcast_mcast_slots = params->no_of_bcast_mcast_slots; 1248 cmd->min_no_twt_slots = params->min_no_twt_slots; 1249 cmd->max_no_sta_twt = params->max_no_sta_twt; 1250 cmd->mode_check_interval = params->mode_check_interval; 1251 cmd->add_sta_slot_interval = params->add_sta_slot_interval; 1252 cmd->remove_sta_slot_interval = params->remove_sta_slot_interval; 1253 1254 TWT_EN_DIS_FLAGS_SET_BTWT(cmd->flags, params->b_twt_enable); 1255 TWT_EN_DIS_FLAGS_SET_L_MBSSID(cmd->flags, 1256 params->b_twt_legacy_mbss_enable); 1257 TWT_EN_DIS_FLAGS_SET_AX_MBSSID(cmd->flags, 1258 params->b_twt_ax_mbss_enable); 1259 if (params->ext_conf_present) { 1260 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 1261 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 1262 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 1263 } 1264 1265 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1266 WMI_TWT_ENABLE_CMDID); 1267 if (QDF_IS_STATUS_ERROR(status)) { 1268 wmi_err("Failed to send WMI_TWT_ENABLE_CMDID"); 1269 wmi_buf_free(buf); 1270 } 1271 1272 return status; 1273 } 1274 1275 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle, 1276 struct wmi_twt_disable_param *params) 1277 { 1278 wmi_twt_disable_cmd_fixed_param *cmd; 1279 wmi_buf_t buf; 1280 QDF_STATUS status; 1281 1282 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1283 if (!buf) { 1284 wmi_err("Failed to allocate memory"); 1285 return QDF_STATUS_E_FAILURE; 1286 } 1287 1288 cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf); 1289 WMITLV_SET_HDR(&cmd->tlv_header, 1290 WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param, 1291 WMITLV_GET_STRUCT_TLVLEN 1292 (wmi_twt_disable_cmd_fixed_param)); 1293 1294 cmd->pdev_id = 1295 wmi_handle->ops->convert_pdev_id_host_to_target( 1296 wmi_handle, 1297 params->pdev_id); 1298 if (params->ext_conf_present) { 1299 TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1); 1300 TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role); 1301 TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper); 1302 } 1303 1304 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1305 WMI_TWT_DISABLE_CMDID); 1306 if (QDF_IS_STATUS_ERROR(status)) { 1307 wmi_err("Failed to send WMI_TWT_DISABLE_CMDID"); 1308 wmi_buf_free(buf); 1309 } 1310 1311 return status; 1312 } 1313 1314 #ifdef WLAN_SUPPORT_BCAST_TWT 1315 static void 1316 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params, 1317 wmi_twt_add_dialog_cmd_fixed_param *cmd) 1318 { 1319 TWT_FLAGS_SET_BTWT_ID0(cmd->flags, params->flag_b_twt_id0); 1320 cmd->b_twt_persistence = params->b_twt_persistence; 1321 cmd->b_twt_recommendation = params->b_twt_recommendation; 1322 } 1323 #else 1324 static void 1325 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params, 1326 wmi_twt_add_dialog_cmd_fixed_param *cmd) 1327 { 1328 } 1329 #endif 1330 1331 static QDF_STATUS 1332 send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1333 struct wmi_twt_add_dialog_param *params) 1334 { 1335 wmi_twt_add_dialog_cmd_fixed_param *cmd; 1336 wmi_buf_t buf; 1337 QDF_STATUS status; 1338 1339 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1340 if (!buf) { 1341 wmi_err("Failed to allocate memory"); 1342 return QDF_STATUS_E_FAILURE; 1343 } 1344 1345 cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1346 WMITLV_SET_HDR(&cmd->tlv_header, 1347 WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param, 1348 WMITLV_GET_STRUCT_TLVLEN 1349 (wmi_twt_add_dialog_cmd_fixed_param)); 1350 1351 cmd->vdev_id = params->vdev_id; 1352 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1353 cmd->dialog_id = params->dialog_id; 1354 cmd->wake_intvl_us = params->wake_intvl_us; 1355 cmd->wake_intvl_mantis = params->wake_intvl_mantis; 1356 cmd->wake_dura_us = params->wake_dura_us; 1357 cmd->sp_offset_us = params->sp_offset_us; 1358 cmd->min_wake_intvl_us = params->min_wake_intvl_us; 1359 cmd->max_wake_intvl_us = params->max_wake_intvl_us; 1360 cmd->min_wake_dura_us = params->min_wake_dura_us; 1361 cmd->max_wake_dura_us = params->max_wake_dura_us; 1362 cmd->sp_start_tsf_lo = (uint32_t)(params->wake_time_tsf & 0xFFFFFFFF); 1363 cmd->sp_start_tsf_hi = (uint32_t)(params->wake_time_tsf >> 32); 1364 cmd->announce_timeout_us = params->announce_timeout_us; 1365 TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd); 1366 TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast); 1367 TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger); 1368 TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type); 1369 TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection); 1370 1371 twt_add_dialog_set_bcast_twt_params(params, cmd); 1372 1373 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1374 WMI_TWT_ADD_DIALOG_CMDID); 1375 if (QDF_IS_STATUS_ERROR(status)) { 1376 wmi_err("Failed to send WMI_TWT_ADD_DIALOG_CMDID"); 1377 wmi_buf_free(buf); 1378 } 1379 1380 return status; 1381 } 1382 1383 #ifdef WLAN_SUPPORT_BCAST_TWT 1384 static void 1385 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params, 1386 wmi_twt_del_dialog_cmd_fixed_param *cmd) 1387 { 1388 cmd->b_twt_persistence = params->b_twt_persistence; 1389 } 1390 #else 1391 static void 1392 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params, 1393 wmi_twt_del_dialog_cmd_fixed_param *cmd) 1394 { 1395 } 1396 #endif 1397 1398 static QDF_STATUS 1399 send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1400 struct wmi_twt_del_dialog_param *params) 1401 { 1402 wmi_twt_del_dialog_cmd_fixed_param *cmd; 1403 wmi_buf_t buf; 1404 QDF_STATUS status; 1405 1406 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1407 if (!buf) { 1408 wmi_err("Failed to allocate memory"); 1409 return QDF_STATUS_E_FAILURE; 1410 } 1411 1412 cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1413 WMITLV_SET_HDR(&cmd->tlv_header, 1414 WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param, 1415 WMITLV_GET_STRUCT_TLVLEN 1416 (wmi_twt_del_dialog_cmd_fixed_param)); 1417 1418 cmd->vdev_id = params->vdev_id; 1419 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1420 cmd->dialog_id = params->dialog_id; 1421 1422 twt_del_dialog_set_bcast_twt_params(params, cmd); 1423 1424 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1425 WMI_TWT_DEL_DIALOG_CMDID); 1426 if (QDF_IS_STATUS_ERROR(status)) { 1427 wmi_err("Failed to send WMI_TWT_DEL_DIALOG_CMDID"); 1428 wmi_buf_free(buf); 1429 } 1430 1431 return status; 1432 } 1433 1434 static QDF_STATUS 1435 send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1436 struct wmi_twt_pause_dialog_cmd_param *params) 1437 { 1438 wmi_twt_pause_dialog_cmd_fixed_param *cmd; 1439 wmi_buf_t buf; 1440 QDF_STATUS status; 1441 1442 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1443 if (!buf) { 1444 wmi_err("Failed to allocate memory"); 1445 return QDF_STATUS_E_FAILURE; 1446 } 1447 1448 cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1449 WMITLV_SET_HDR(&cmd->tlv_header, 1450 WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param, 1451 WMITLV_GET_STRUCT_TLVLEN 1452 (wmi_twt_pause_dialog_cmd_fixed_param)); 1453 1454 cmd->vdev_id = params->vdev_id; 1455 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1456 cmd->dialog_id = params->dialog_id; 1457 1458 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1459 WMI_TWT_PAUSE_DIALOG_CMDID); 1460 if (QDF_IS_STATUS_ERROR(status)) { 1461 wmi_err("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID"); 1462 wmi_buf_free(buf); 1463 } 1464 1465 return status; 1466 } 1467 1468 static QDF_STATUS 1469 send_twt_nudge_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1470 struct wmi_twt_nudge_dialog_cmd_param *params) 1471 { 1472 wmi_twt_nudge_dialog_cmd_fixed_param *cmd; 1473 wmi_buf_t buf; 1474 QDF_STATUS status; 1475 1476 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1477 if (!buf) 1478 return QDF_STATUS_E_FAILURE; 1479 1480 cmd = (wmi_twt_nudge_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1481 WMITLV_SET_HDR(&cmd->tlv_header, 1482 WMITLV_TAG_STRUC_wmi_twt_nudge_dialog_cmd_fixed_param, 1483 WMITLV_GET_STRUCT_TLVLEN 1484 (wmi_twt_nudge_dialog_cmd_fixed_param)); 1485 1486 cmd->vdev_id = params->vdev_id; 1487 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1488 cmd->dialog_id = params->dialog_id; 1489 cmd->suspend_duration_ms = params->suspend_duration / 1000; 1490 cmd->next_twt_size = params->next_twt_size; 1491 1492 wmi_debug("vdev_id: %d dialog_id: %d duration(in ms): %u next_twt_size: %d " 1493 "peer_macaddr: "QDF_MAC_ADDR_FMT, cmd->vdev_id, 1494 cmd->dialog_id, cmd->suspend_duration_ms, cmd->next_twt_size, 1495 QDF_MAC_ADDR_REF(params->peer_macaddr)); 1496 1497 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1498 WMI_TWT_NUDGE_DIALOG_CMDID); 1499 if (QDF_IS_STATUS_ERROR(status)) 1500 wmi_buf_free(buf); 1501 1502 return status; 1503 } 1504 1505 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle, 1506 struct wmi_twt_resume_dialog_cmd_param *params) 1507 { 1508 wmi_twt_resume_dialog_cmd_fixed_param *cmd; 1509 wmi_buf_t buf; 1510 QDF_STATUS status; 1511 1512 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1513 if (!buf) { 1514 wmi_err("Failed to allocate memory"); 1515 return QDF_STATUS_E_FAILURE; 1516 } 1517 1518 cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf); 1519 WMITLV_SET_HDR(&cmd->tlv_header, 1520 WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param, 1521 WMITLV_GET_STRUCT_TLVLEN 1522 (wmi_twt_resume_dialog_cmd_fixed_param)); 1523 1524 cmd->vdev_id = params->vdev_id; 1525 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1526 cmd->dialog_id = params->dialog_id; 1527 cmd->sp_offset_us = params->sp_offset_us; 1528 cmd->next_twt_size = params->next_twt_size; 1529 1530 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1531 WMI_TWT_RESUME_DIALOG_CMDID); 1532 if (QDF_IS_STATUS_ERROR(status)) { 1533 wmi_err("Failed to send WMI_TWT_RESUME_DIALOG_CMDID"); 1534 wmi_buf_free(buf); 1535 } 1536 1537 return status; 1538 } 1539 1540 #ifdef WLAN_SUPPORT_BCAST_TWT 1541 static QDF_STATUS 1542 send_twt_btwt_invite_sta_cmd_tlv(wmi_unified_t wmi_handle, 1543 struct wmi_twt_btwt_invite_sta_cmd_param 1544 *params) 1545 { 1546 wmi_twt_btwt_invite_sta_cmd_fixed_param *cmd; 1547 wmi_buf_t buf; 1548 QDF_STATUS status; 1549 1550 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1551 if (!buf) { 1552 wmi_err("Failed to allocate memory"); 1553 return QDF_STATUS_E_FAILURE; 1554 } 1555 1556 cmd = (wmi_twt_btwt_invite_sta_cmd_fixed_param *)wmi_buf_data(buf); 1557 WMITLV_SET_HDR(&cmd->tlv_header, 1558 WMITLV_TAG_STRUC_wmi_twt_btwt_invite_sta_cmd_fixed_param, 1559 WMITLV_GET_STRUCT_TLVLEN 1560 (wmi_twt_btwt_invite_sta_cmd_fixed_param)); 1561 1562 cmd->vdev_id = params->vdev_id; 1563 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1564 cmd->dialog_id = params->dialog_id; 1565 1566 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1567 WMI_TWT_BTWT_INVITE_STA_CMDID); 1568 if (QDF_IS_STATUS_ERROR(status)) { 1569 wmi_buf_free(buf); 1570 } 1571 1572 return status; 1573 } 1574 1575 static QDF_STATUS 1576 send_twt_btwt_remove_sta_cmd_tlv(wmi_unified_t wmi_handle, 1577 struct wmi_twt_btwt_remove_sta_cmd_param 1578 *params) 1579 { 1580 wmi_twt_btwt_remove_sta_cmd_fixed_param *cmd; 1581 wmi_buf_t buf; 1582 QDF_STATUS status; 1583 1584 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1585 if (!buf) { 1586 wmi_err("Failed to allocate memory"); 1587 return QDF_STATUS_E_FAILURE; 1588 } 1589 1590 cmd = (wmi_twt_btwt_remove_sta_cmd_fixed_param *)wmi_buf_data(buf); 1591 WMITLV_SET_HDR(&cmd->tlv_header, 1592 WMITLV_TAG_STRUC_wmi_twt_btwt_remove_sta_cmd_fixed_param, 1593 WMITLV_GET_STRUCT_TLVLEN 1594 (wmi_twt_btwt_remove_sta_cmd_fixed_param)); 1595 1596 cmd->vdev_id = params->vdev_id; 1597 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 1598 cmd->dialog_id = params->dialog_id; 1599 1600 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 1601 WMI_TWT_BTWT_REMOVE_STA_CMDID); 1602 if (QDF_IS_STATUS_ERROR(status)) { 1603 wmi_buf_free(buf); 1604 } 1605 1606 return status; 1607 } 1608 #endif 1609 1610 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle, 1611 uint8_t *evt_buf, 1612 struct wmi_twt_enable_complete_event_param *params) 1613 { 1614 WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 1615 wmi_twt_enable_complete_event_fixed_param *ev; 1616 1617 param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1618 if (!param_buf) { 1619 wmi_err("evt_buf is NULL"); 1620 return QDF_STATUS_E_INVAL; 1621 } 1622 1623 ev = param_buf->fixed_param; 1624 1625 params->pdev_id = 1626 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 1627 ev->pdev_id); 1628 params->status = ev->status; 1629 1630 return QDF_STATUS_SUCCESS; 1631 } 1632 1633 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle, 1634 uint8_t *evt_buf, 1635 struct wmi_twt_disable_complete_event *params) 1636 { 1637 WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 1638 wmi_twt_disable_complete_event_fixed_param *ev; 1639 1640 param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1641 if (!param_buf) { 1642 wmi_err("evt_buf is NULL"); 1643 return QDF_STATUS_E_INVAL; 1644 } 1645 1646 ev = param_buf->fixed_param; 1647 1648 #if 0 1649 params->pdev_id = 1650 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 1651 ev->pdev_id); 1652 params->status = ev->status; 1653 #endif 1654 1655 return QDF_STATUS_SUCCESS; 1656 } 1657 1658 static enum WMI_HOST_ADD_TWT_STATUS 1659 wmi_get_converted_twt_add_dialog_status(WMI_ADD_TWT_STATUS_T tgt_status) 1660 { 1661 switch (tgt_status) { 1662 case WMI_ADD_TWT_STATUS_OK: 1663 return WMI_HOST_ADD_TWT_STATUS_OK; 1664 case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED: 1665 return WMI_HOST_ADD_TWT_STATUS_TWT_NOT_ENABLED; 1666 case WMI_ADD_TWT_STATUS_USED_DIALOG_ID: 1667 return WMI_HOST_ADD_TWT_STATUS_USED_DIALOG_ID; 1668 case WMI_ADD_TWT_STATUS_INVALID_PARAM: 1669 return WMI_HOST_ADD_TWT_STATUS_INVALID_PARAM; 1670 case WMI_ADD_TWT_STATUS_NOT_READY: 1671 return WMI_HOST_ADD_TWT_STATUS_NOT_READY; 1672 case WMI_ADD_TWT_STATUS_NO_RESOURCE: 1673 return WMI_HOST_ADD_TWT_STATUS_NO_RESOURCE; 1674 case WMI_ADD_TWT_STATUS_NO_ACK: 1675 return WMI_HOST_ADD_TWT_STATUS_NO_ACK; 1676 case WMI_ADD_TWT_STATUS_NO_RESPONSE: 1677 return WMI_HOST_ADD_TWT_STATUS_NO_RESPONSE; 1678 case WMI_ADD_TWT_STATUS_DENIED: 1679 return WMI_HOST_ADD_TWT_STATUS_DENIED; 1680 case WMI_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE: 1681 return WMI_HOST_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE; 1682 case WMI_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED: 1683 return WMI_HOST_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED; 1684 case WMI_ADD_TWT_STATUS_ROAM_IN_PROGRESS: 1685 return WMI_HOST_ADD_TWT_STATUS_ROAM_IN_PROGRESS; 1686 case WMI_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1687 return WMI_HOST_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1688 case WMI_ADD_TWT_STATUS_SCAN_IN_PROGRESS: 1689 return WMI_HOST_ADD_TWT_STATUS_SCAN_IN_PROGRESS; 1690 default: 1691 return WMI_HOST_ADD_TWT_STATUS_UNKNOWN_ERROR; 1692 } 1693 } 1694 1695 /** 1696 * extract_twt_add_dialog_comp_event_tlv - Extacts twt add dialog complete wmi 1697 * event from firmware 1698 * @wmi_hande: WMI handle 1699 * @evt_buf: Pointer to wmi event buf of twt add dialog complete event 1700 * @params: Pointer to store the extracted parameters 1701 * 1702 * Return: QDF_STATUS_SUCCESS on success or QDF STATUS error values on failure 1703 */ 1704 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv( 1705 wmi_unified_t wmi_handle, 1706 uint8_t *evt_buf, 1707 struct wmi_twt_add_dialog_complete_event_param *params) 1708 { 1709 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1710 wmi_twt_add_dialog_complete_event_fixed_param *ev; 1711 1712 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1713 if (!param_buf) { 1714 wmi_err("evt_buf is NULL"); 1715 return QDF_STATUS_E_INVAL; 1716 } 1717 1718 ev = param_buf->fixed_param; 1719 1720 params->vdev_id = ev->vdev_id; 1721 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1722 params->status = wmi_get_converted_twt_add_dialog_status(ev->status); 1723 params->dialog_id = ev->dialog_id; 1724 params->num_additional_twt_params = param_buf->num_twt_params; 1725 1726 return QDF_STATUS_SUCCESS; 1727 } 1728 1729 /** 1730 * extract_twt_add_dialog_comp_additional_parameters() - Extracts additional twt 1731 * twt parameters, as part of add dialog completion event 1732 * @wmi_hdl: wmi handle 1733 * @evt_buf: Pointer event buffer 1734 * @evt_buf_len: length of the add dialog event buffer 1735 * @idx: index of num_twt_params 1736 * @additional_params: twt additional parameters to extract 1737 * 1738 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL for failure 1739 */ 1740 static QDF_STATUS extract_twt_add_dialog_comp_additional_parameters 1741 ( 1742 wmi_unified_t wmi_handle, uint8_t *evt_buf, 1743 uint32_t evt_buf_len, uint32_t idx, 1744 struct wmi_twt_add_dialog_additional_params *additional_params 1745 ) 1746 { 1747 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1748 wmi_twt_add_dialog_complete_event_fixed_param *ev; 1749 uint32_t flags = 0; 1750 uint32_t expected_len; 1751 1752 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1753 if (!param_buf) { 1754 wmi_err("evt_buf is NULL"); 1755 return QDF_STATUS_E_INVAL; 1756 } 1757 1758 ev = param_buf->fixed_param; 1759 1760 if (idx >= param_buf->num_twt_params) { 1761 wmi_err("Invalid idx %d while num_twt_params = %d", 1762 idx, param_buf->num_twt_params); 1763 return QDF_STATUS_E_INVAL; 1764 } 1765 1766 if (!param_buf->twt_params) { 1767 wmi_err("Unable to extract additional twt parameters"); 1768 return QDF_STATUS_E_INVAL; 1769 } 1770 1771 expected_len = (sizeof(wmi_twt_add_dialog_complete_event_fixed_param) + 1772 WMI_TLV_HDR_SIZE + (param_buf->num_twt_params * 1773 sizeof(wmi_twt_add_dialog_additional_params))); 1774 1775 if (evt_buf_len != expected_len) { 1776 wmi_err("Got invalid len data from FW %d expected %d", 1777 evt_buf_len, expected_len); 1778 return QDF_STATUS_E_INVAL; 1779 } 1780 1781 flags = param_buf->twt_params[idx].flags; 1782 additional_params->twt_cmd = TWT_FLAGS_GET_CMD(flags); 1783 additional_params->bcast = TWT_FLAGS_GET_BROADCAST(flags); 1784 additional_params->trig_en = TWT_FLAGS_GET_TRIGGER(flags); 1785 additional_params->announce = TWT_FLAGS_GET_FLOW_TYPE(flags); 1786 additional_params->protection = TWT_FLAGS_GET_PROTECTION(flags); 1787 additional_params->b_twt_id0 = TWT_FLAGS_GET_BTWT_ID0(flags); 1788 additional_params->info_frame_disabled = 1789 TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flags); 1790 additional_params->wake_dur_us = param_buf->twt_params[idx].wake_dur_us; 1791 additional_params->wake_intvl_us = 1792 param_buf->twt_params[idx].wake_intvl_us; 1793 additional_params->sp_offset_us = 1794 param_buf->twt_params[idx].sp_offset_us; 1795 additional_params->sp_tsf_us_lo = 1796 param_buf->twt_params[idx].sp_tsf_us_lo; 1797 additional_params->sp_tsf_us_hi = 1798 param_buf->twt_params[idx].sp_tsf_us_hi; 1799 additional_params->pm_responder_bit_valid = 1800 TWT_FLAGS_GET_PM_RESPONDER_MODE_VALID(flags); 1801 additional_params->pm_responder_bit = 1802 TWT_FLAGS_GET_PM_RESPONDER_MODE(flags); 1803 1804 return QDF_STATUS_SUCCESS; 1805 } 1806 1807 static enum WMI_HOST_DEL_TWT_STATUS 1808 wmi_get_converted_twt_del_dialog_status(WMI_DEL_TWT_STATUS_T tgt_status) 1809 { 1810 switch (tgt_status) { 1811 case WMI_DEL_TWT_STATUS_OK: 1812 return WMI_HOST_DEL_TWT_STATUS_OK; 1813 case WMI_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1814 return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1815 case WMI_DEL_TWT_STATUS_INVALID_PARAM: 1816 return WMI_HOST_DEL_TWT_STATUS_INVALID_PARAM; 1817 case WMI_DEL_TWT_STATUS_DIALOG_ID_BUSY: 1818 return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_BUSY; 1819 case WMI_DEL_TWT_STATUS_NO_RESOURCE: 1820 return WMI_HOST_DEL_TWT_STATUS_NO_RESOURCE; 1821 case WMI_DEL_TWT_STATUS_NO_ACK: 1822 return WMI_HOST_DEL_TWT_STATUS_NO_ACK; 1823 case WMI_DEL_TWT_STATUS_UNKNOWN_ERROR: 1824 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 1825 case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN: 1826 return WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN; 1827 case WMI_DEL_TWT_STATUS_ROAMING: 1828 return WMI_HOST_DEL_TWT_STATUS_ROAMING; 1829 case WMI_DEL_TWT_STATUS_CONCURRENCY: 1830 return WMI_HOST_DEL_TWT_STATUS_CONCURRENCY; 1831 case WMI_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1832 return WMI_HOST_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1833 case WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS: 1834 return WMI_HOST_DEL_TWT_STATUS_SCAN_IN_PROGRESS; 1835 default: 1836 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 1837 } 1838 1839 return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR; 1840 } 1841 1842 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv( 1843 wmi_unified_t wmi_handle, 1844 uint8_t *evt_buf, 1845 struct wmi_twt_del_dialog_complete_event_param *params) 1846 { 1847 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1848 wmi_twt_del_dialog_complete_event_fixed_param *ev; 1849 1850 param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1851 if (!param_buf) { 1852 wmi_err("evt_buf is NULL"); 1853 return QDF_STATUS_E_INVAL; 1854 } 1855 1856 ev = param_buf->fixed_param; 1857 1858 params->vdev_id = ev->vdev_id; 1859 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1860 params->dialog_id = ev->dialog_id; 1861 params->status = wmi_get_converted_twt_del_dialog_status(ev->status); 1862 1863 return QDF_STATUS_SUCCESS; 1864 } 1865 1866 static enum WMI_HOST_PAUSE_TWT_STATUS 1867 wmi_twt_pause_status_to_host_twt_status(WMI_PAUSE_TWT_STATUS_T status) 1868 { 1869 switch (status) { 1870 case WMI_PAUSE_TWT_STATUS_OK: 1871 return WMI_HOST_PAUSE_TWT_STATUS_OK; 1872 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1873 return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1874 case WMI_PAUSE_TWT_STATUS_INVALID_PARAM: 1875 return WMI_HOST_PAUSE_TWT_STATUS_INVALID_PARAM; 1876 case WMI_PAUSE_TWT_STATUS_DIALOG_ID_BUSY: 1877 return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_BUSY; 1878 case WMI_PAUSE_TWT_STATUS_NO_RESOURCE: 1879 return WMI_HOST_PAUSE_TWT_STATUS_NO_RESOURCE; 1880 case WMI_PAUSE_TWT_STATUS_NO_ACK: 1881 return WMI_HOST_PAUSE_TWT_STATUS_NO_ACK; 1882 case WMI_PAUSE_TWT_STATUS_UNKNOWN_ERROR: 1883 return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR; 1884 case WMI_PAUSE_TWT_STATUS_ALREADY_PAUSED: 1885 return WMI_HOST_PAUSE_TWT_STATUS_ALREADY_PAUSED; 1886 case WMI_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1887 return WMI_HOST_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1888 case WMI_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS: 1889 return WMI_HOST_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS; 1890 case WMI_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS: 1891 return WMI_HOST_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS; 1892 default: 1893 return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR; 1894 } 1895 } 1896 1897 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv( 1898 wmi_unified_t wmi_handle, 1899 uint8_t *evt_buf, 1900 struct wmi_twt_pause_dialog_complete_event_param *params) 1901 { 1902 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1903 wmi_twt_pause_dialog_complete_event_fixed_param *ev; 1904 1905 param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1906 if (!param_buf) { 1907 wmi_err("evt_buf is NULL"); 1908 return QDF_STATUS_E_INVAL; 1909 } 1910 1911 ev = param_buf->fixed_param; 1912 1913 params->vdev_id = ev->vdev_id; 1914 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1915 params->status = wmi_twt_pause_status_to_host_twt_status(ev->status); 1916 params->dialog_id = ev->dialog_id; 1917 1918 return QDF_STATUS_SUCCESS; 1919 } 1920 1921 static enum WMI_HOST_NUDGE_TWT_STATUS 1922 wmi_twt_nudge_status_to_host_twt_status(WMI_TWT_NUDGE_STATUS_T status) 1923 { 1924 switch (status) { 1925 case WMI_NUDGE_TWT_STATUS_OK: 1926 return WMI_HOST_NUDGE_TWT_STATUS_OK; 1927 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1928 return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1929 case WMI_NUDGE_TWT_STATUS_INVALID_PARAM: 1930 return WMI_HOST_NUDGE_TWT_STATUS_INVALID_PARAM; 1931 case WMI_NUDGE_TWT_STATUS_DIALOG_ID_BUSY: 1932 return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_BUSY; 1933 case WMI_NUDGE_TWT_STATUS_NO_RESOURCE: 1934 return WMI_HOST_NUDGE_TWT_STATUS_NO_RESOURCE; 1935 case WMI_NUDGE_TWT_STATUS_NO_ACK: 1936 return WMI_HOST_NUDGE_TWT_STATUS_NO_ACK; 1937 case WMI_NUDGE_TWT_STATUS_UNKNOWN_ERROR: 1938 return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR; 1939 case WMI_NUDGE_TWT_STATUS_ALREADY_PAUSED: 1940 return WMI_HOST_NUDGE_TWT_STATUS_ALREADY_PAUSED; 1941 case WMI_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS: 1942 return WMI_HOST_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS; 1943 case WMI_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS: 1944 return WMI_HOST_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS; 1945 case WMI_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS: 1946 return WMI_HOST_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS; 1947 default: 1948 return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR; 1949 } 1950 } 1951 1952 static QDF_STATUS extract_twt_nudge_dialog_comp_event_tlv( 1953 wmi_unified_t wmi_handle, 1954 uint8_t *evt_buf, 1955 struct wmi_twt_nudge_dialog_complete_event_param *params) 1956 { 1957 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 1958 wmi_twt_nudge_dialog_complete_event_fixed_param *ev; 1959 1960 param_buf = (WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 1961 if (!param_buf) { 1962 wmi_err("evt_buf is NULL"); 1963 return QDF_STATUS_E_INVAL; 1964 } 1965 1966 ev = param_buf->fixed_param; 1967 1968 params->vdev_id = ev->vdev_id; 1969 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 1970 params->status = wmi_twt_nudge_status_to_host_twt_status(ev->status); 1971 params->dialog_id = ev->dialog_id; 1972 params->next_twt_tsf_us_lo = ev->sp_tsf_us_lo; 1973 params->next_twt_tsf_us_hi = ev->sp_tsf_us_hi; 1974 1975 wmi_debug("vdev_id: %d dialog_id: %d tsf hi : %x tsf lo: %x", 1976 params->vdev_id, params->dialog_id, 1977 params->next_twt_tsf_us_hi, params->next_twt_tsf_us_lo); 1978 1979 return QDF_STATUS_SUCCESS; 1980 } 1981 1982 static enum WMI_HOST_RESUME_TWT_STATUS 1983 wmi_get_converted_twt_resume_dialog_status(WMI_RESUME_TWT_STATUS_T tgt_status) 1984 { 1985 switch (tgt_status) { 1986 case WMI_RESUME_TWT_STATUS_OK: 1987 return WMI_HOST_RESUME_TWT_STATUS_OK; 1988 case WMI_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST: 1989 return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST; 1990 case WMI_RESUME_TWT_STATUS_INVALID_PARAM: 1991 return WMI_HOST_RESUME_TWT_STATUS_INVALID_PARAM; 1992 case WMI_RESUME_TWT_STATUS_DIALOG_ID_BUSY: 1993 return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_BUSY; 1994 case WMI_RESUME_TWT_STATUS_NOT_PAUSED: 1995 return WMI_HOST_RESUME_TWT_STATUS_NOT_PAUSED; 1996 case WMI_RESUME_TWT_STATUS_NO_RESOURCE: 1997 return WMI_HOST_RESUME_TWT_STATUS_NO_RESOURCE; 1998 case WMI_RESUME_TWT_STATUS_NO_ACK: 1999 return WMI_HOST_RESUME_TWT_STATUS_NO_ACK; 2000 case WMI_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS: 2001 return WMI_HOST_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS; 2002 case WMI_RESUME_TWT_STATUS_ROAM_IN_PROGRESS: 2003 return WMI_HOST_RESUME_TWT_STATUS_ROAM_IN_PROGRESS; 2004 case WMI_RESUME_TWT_STATUS_SCAN_IN_PROGRESS: 2005 return WMI_HOST_RESUME_TWT_STATUS_SCAN_IN_PROGRESS; 2006 default: 2007 return WMI_HOST_RESUME_TWT_STATUS_UNKNOWN_ERROR; 2008 } 2009 } 2010 2011 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv( 2012 wmi_unified_t wmi_handle, 2013 uint8_t *evt_buf, 2014 struct wmi_twt_resume_dialog_complete_event_param *params) 2015 { 2016 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 2017 wmi_twt_resume_dialog_complete_event_fixed_param *ev; 2018 2019 param_buf = 2020 (WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 2021 if (!param_buf) { 2022 wmi_err("evt_buf is NULL"); 2023 return QDF_STATUS_E_INVAL; 2024 } 2025 2026 ev = param_buf->fixed_param; 2027 2028 params->vdev_id = ev->vdev_id; 2029 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 2030 params->status = wmi_get_converted_twt_resume_dialog_status(ev->status); 2031 params->dialog_id = ev->dialog_id; 2032 2033 return QDF_STATUS_SUCCESS; 2034 } 2035 2036 static QDF_STATUS extract_twt_notify_event_tlv( 2037 wmi_unified_t wmi_handle, 2038 uint8_t *evt_buf, 2039 struct wmi_twt_notify_event_param *params) 2040 { 2041 WMI_TWT_NOTIFY_EVENTID_param_tlvs *param_buf; 2042 wmi_twt_notify_event_fixed_param *ev; 2043 2044 param_buf = 2045 (WMI_TWT_NOTIFY_EVENTID_param_tlvs *)evt_buf; 2046 if (!param_buf) { 2047 wmi_err("evt_buf is NULL"); 2048 return QDF_STATUS_E_INVAL; 2049 } 2050 2051 ev = param_buf->fixed_param; 2052 2053 params->vdev_id = ev->vdev_id; 2054 2055 return QDF_STATUS_SUCCESS; 2056 } 2057 2058 #ifdef WLAN_SUPPORT_BCAST_TWT 2059 static QDF_STATUS 2060 extract_twt_btwt_invite_sta_comp_event_tlv( 2061 wmi_unified_t wmi_handle, 2062 uint8_t *evt_buf, 2063 struct 2064 wmi_twt_btwt_invite_sta_complete_event_param 2065 *params) 2066 { 2067 WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 2068 wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev; 2069 2070 param_buf = 2071 (WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 2072 if (!param_buf) { 2073 wmi_err("evt_buf is NULL"); 2074 return QDF_STATUS_E_INVAL; 2075 } 2076 2077 ev = param_buf->fixed_param; 2078 2079 params->vdev_id = ev->vdev_id; 2080 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 2081 params->status = ev->status; 2082 params->dialog_id = ev->dialog_id; 2083 2084 return QDF_STATUS_SUCCESS; 2085 } 2086 2087 static QDF_STATUS 2088 extract_twt_btwt_remove_sta_comp_event_tlv( 2089 wmi_unified_t wmi_handle, 2090 uint8_t *evt_buf, 2091 struct 2092 wmi_twt_btwt_remove_sta_complete_event_param 2093 *params) 2094 { 2095 WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf; 2096 wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev; 2097 2098 param_buf = 2099 (WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf; 2100 if (!param_buf) { 2101 wmi_err("evt_buf is NULL"); 2102 return QDF_STATUS_E_INVAL; 2103 } 2104 2105 ev = param_buf->fixed_param; 2106 2107 params->vdev_id = ev->vdev_id; 2108 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr); 2109 params->status = ev->status; 2110 params->dialog_id = ev->dialog_id; 2111 2112 return QDF_STATUS_SUCCESS; 2113 } 2114 #endif 2115 2116 #ifdef WLAN_SUPPORT_BCAST_TWT 2117 static void 2118 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 2119 { 2120 ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv; 2121 ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv; 2122 ops->extract_twt_btwt_invite_sta_comp_event = 2123 extract_twt_btwt_invite_sta_comp_event_tlv; 2124 ops->extract_twt_btwt_remove_sta_comp_event = 2125 extract_twt_btwt_remove_sta_comp_event_tlv; 2126 } 2127 #else 2128 static void 2129 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) 2130 { 2131 } 2132 #endif 2133 2134 static QDF_STATUS 2135 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle, 2136 uint8_t *evt_buf, 2137 struct wmi_twt_session_stats_event_param 2138 *params) 2139 { 2140 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 2141 wmi_pdev_twt_session_stats_event_fixed_param *ev; 2142 2143 param_buf = 2144 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 2145 if (!param_buf) { 2146 wmi_err("evt_buf is NULL"); 2147 return QDF_STATUS_E_INVAL; 2148 } 2149 2150 ev = param_buf->fixed_param; 2151 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 2152 wmi_handle, 2153 ev->pdev_id); 2154 params->num_sessions = param_buf->num_twt_sessions; 2155 2156 wmi_debug("pdev_id=%d, num of TWT sessions=%d", 2157 params->pdev_id, params->num_sessions); 2158 2159 return QDF_STATUS_SUCCESS; 2160 } 2161 2162 static QDF_STATUS 2163 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, 2164 uint8_t *evt_buf, 2165 struct wmi_twt_session_stats_event_param 2166 *params, 2167 struct wmi_host_twt_session_stats_info 2168 *session, 2169 uint32_t idx) 2170 { 2171 WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; 2172 wmi_twt_session_stats_info *twt_session; 2173 uint32_t flags; 2174 wmi_mac_addr *m1; 2175 uint8_t *m2; 2176 2177 param_buf = 2178 (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; 2179 if (!param_buf) { 2180 wmi_err("evt_buf is NULL"); 2181 return QDF_STATUS_E_INVAL; 2182 } 2183 2184 if (idx >= param_buf->num_twt_sessions) { 2185 wmi_err("wrong idx, idx=%d, num_sessions=%d", 2186 idx, param_buf->num_twt_sessions); 2187 return QDF_STATUS_E_INVAL; 2188 } 2189 2190 twt_session = ¶m_buf->twt_sessions[idx]; 2191 2192 session->vdev_id = twt_session->vdev_id; 2193 m1 = &twt_session->peer_mac; 2194 m2 = session->peer_mac; 2195 WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2); 2196 session->event_type = twt_session->event_type; 2197 flags = twt_session->flow_id_flags; 2198 session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags); 2199 session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags); 2200 session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags); 2201 session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags); 2202 session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags); 2203 session->info_frame_disabled = 2204 WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags); 2205 session->pm_responder_bit = 2206 WMI_TWT_SESSION_FLAG_TWT_PM_RESPONDER_MODE_GET(flags); 2207 session->pm_responder_bit_valid = 2208 WMI_TWT_SESSION_FLAG_TWT_PM_RESPONDER_MODE_VALID_GET(flags); 2209 session->dialog_id = twt_session->dialog_id; 2210 session->wake_dura_us = twt_session->wake_dura_us; 2211 session->wake_intvl_us = twt_session->wake_intvl_us; 2212 session->sp_offset_us = twt_session->sp_offset_us; 2213 session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo; 2214 session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi; 2215 wmi_debug("type=%d id=%d bcast=%d trig=%d announ=%d diagid=%d wake_dur=%ul wake_int=%ul offset=%ul", 2216 session->event_type, session->flow_id, 2217 session->bcast, session->trig, 2218 session->announ, session->dialog_id, session->wake_dura_us, 2219 session->wake_intvl_us, session->sp_offset_us); 2220 wmi_debug("resp_pm_valid=%d resp_pm=%d", 2221 session->pm_responder_bit_valid, session->pm_responder_bit); 2222 2223 return QDF_STATUS_SUCCESS; 2224 } 2225 2226 static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( 2227 wmi_unified_t wmi_handle, uint8_t *event, 2228 struct wmi_twt_cap_bitmap_params *var) 2229 { 2230 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 2231 wmi_twt_caps_params *twt_caps; 2232 2233 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 2234 if (!param_buf) 2235 return QDF_STATUS_E_INVAL; 2236 2237 twt_caps = param_buf->twt_caps; 2238 if (!twt_caps) 2239 return QDF_STATUS_E_INVAL; 2240 2241 var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap, 2242 0, 1); 2243 2244 return QDF_STATUS_SUCCESS; 2245 } 2246 2247 static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT 2248 wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd) 2249 { 2250 switch (tgt_cmd) { 2251 case WMI_TWT_ADD_DIALOG_CMDID: 2252 return WMI_HOST_TWT_ADD_DIALOG_CMDID; 2253 case WMI_TWT_DEL_DIALOG_CMDID: 2254 return WMI_HOST_TWT_DEL_DIALOG_CMDID; 2255 case WMI_TWT_PAUSE_DIALOG_CMDID: 2256 return WMI_HOST_TWT_PAUSE_DIALOG_CMDID; 2257 case WMI_TWT_RESUME_DIALOG_CMDID: 2258 return WMI_HOST_TWT_RESUME_DIALOG_CMDID; 2259 case WMI_TWT_NUDGE_DIALOG_CMDID: 2260 return WMI_HOST_TWT_NUDGE_DIALOG_CMDID; 2261 default: 2262 return WMI_HOST_TWT_UNKNOWN_CMDID; 2263 } 2264 } 2265 2266 static QDF_STATUS 2267 extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle, 2268 uint8_t *evt_buf, 2269 struct wmi_twt_ack_complete_event_param *var) 2270 { 2271 WMI_TWT_ACK_EVENTID_param_tlvs *param_buf; 2272 wmi_twt_ack_event_fixed_param *ack_event; 2273 2274 param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf; 2275 if (!param_buf) { 2276 wmi_err("evt_buf is NULL"); 2277 return QDF_STATUS_E_INVAL; 2278 } 2279 2280 ack_event = param_buf->fixed_param; 2281 2282 var->vdev_id = ack_event->vdev_id; 2283 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr, 2284 var->peer_macaddr.bytes); 2285 var->dialog_id = ack_event->dialog_id; 2286 var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event( 2287 ack_event->twt_cmd); 2288 2289 switch (ack_event->twt_cmd) { 2290 case WMI_TWT_ADD_DIALOG_CMDID: 2291 var->status = wmi_get_converted_twt_add_dialog_status( 2292 ack_event->status); 2293 break; 2294 case WMI_TWT_DEL_DIALOG_CMDID: 2295 var->status = wmi_get_converted_twt_del_dialog_status( 2296 ack_event->status); 2297 break; 2298 case WMI_TWT_PAUSE_DIALOG_CMDID: 2299 var->status = wmi_twt_pause_status_to_host_twt_status( 2300 ack_event->status); 2301 break; 2302 case WMI_TWT_RESUME_DIALOG_CMDID: 2303 var->status = wmi_get_converted_twt_resume_dialog_status( 2304 ack_event->status); 2305 break; 2306 case WMI_TWT_NUDGE_DIALOG_CMDID: 2307 var->status = wmi_twt_nudge_status_to_host_twt_status( 2308 ack_event->status); 2309 break; 2310 default: 2311 break; 2312 } 2313 return QDF_STATUS_SUCCESS; 2314 } 2315 #endif 2316 2317 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) 2318 { 2319 struct wmi_ops *ops = wmi_handle->ops; 2320 2321 ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv; 2322 ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv; 2323 ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv; 2324 ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv; 2325 ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv; 2326 ops->send_twt_nudge_dialog_cmd = send_twt_nudge_dialog_cmd_tlv; 2327 ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv; 2328 ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv; 2329 ops->extract_twt_disable_comp_event = 2330 extract_twt_disable_comp_event_tlv; 2331 ops->extract_twt_add_dialog_comp_event = 2332 extract_twt_add_dialog_comp_event_tlv; 2333 ops->extract_twt_add_dialog_comp_additional_params = 2334 extract_twt_add_dialog_comp_additional_parameters; 2335 ops->extract_twt_del_dialog_comp_event = 2336 extract_twt_del_dialog_comp_event_tlv; 2337 ops->extract_twt_pause_dialog_comp_event = 2338 extract_twt_pause_dialog_comp_event_tlv; 2339 ops->extract_twt_nudge_dialog_comp_event = 2340 extract_twt_nudge_dialog_comp_event_tlv; 2341 ops->extract_twt_resume_dialog_comp_event = 2342 extract_twt_resume_dialog_comp_event_tlv; 2343 ops->extract_twt_session_stats_event = 2344 extract_twt_session_stats_event_tlv; 2345 ops->extract_twt_session_stats_data = 2346 extract_twt_session_stats_event_data; 2347 ops->extract_twt_notify_event = 2348 extract_twt_notify_event_tlv; 2349 ops->extract_twt_cap_service_ready_ext2 = 2350 extract_twt_cap_service_ready_ext2_tlv, 2351 ops->extract_twt_ack_comp_event = extract_twt_ack_comp_event_tlv; 2352 wmi_twt_attach_bcast_twt_tlv(ops); 2353 } 2354