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