1 2 /* 3 * Copyright (c) 2018 The Linux Foundation. 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 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle, 27 struct wmi_twt_enable_param *params) 28 { 29 wmi_twt_enable_cmd_fixed_param *cmd; 30 wmi_buf_t buf; 31 QDF_STATUS status; 32 33 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 34 if (!buf) { 35 WMI_LOGE("Failed to allocate memory"); 36 return QDF_STATUS_E_FAILURE; 37 } 38 39 cmd = (wmi_twt_enable_cmd_fixed_param *) wmi_buf_data(buf); 40 WMITLV_SET_HDR(&cmd->tlv_header, 41 WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param, 42 WMITLV_GET_STRUCT_TLVLEN 43 (wmi_twt_enable_cmd_fixed_param)); 44 45 cmd->pdev_id = 46 wmi_handle->ops->convert_pdev_id_host_to_target( 47 params->pdev_id); 48 cmd->sta_cong_timer_ms = params->sta_cong_timer_ms; 49 cmd->mbss_support = params->mbss_support; 50 cmd->default_slot_size = params->default_slot_size; 51 cmd->congestion_thresh_setup = params->congestion_thresh_setup; 52 cmd->congestion_thresh_teardown = params->congestion_thresh_teardown; 53 cmd->congestion_thresh_critical = params->congestion_thresh_critical; 54 cmd->interference_thresh_teardown = 55 params->interference_thresh_teardown; 56 cmd->interference_thresh_setup = params->interference_thresh_setup; 57 cmd->min_no_sta_setup = params->min_no_sta_setup; 58 cmd->min_no_sta_teardown = params->min_no_sta_teardown; 59 cmd->no_of_bcast_mcast_slots = params->no_of_bcast_mcast_slots; 60 cmd->min_no_twt_slots = params->min_no_twt_slots; 61 cmd->max_no_sta_twt = params->max_no_sta_twt; 62 cmd->mode_check_interval = params->mode_check_interval; 63 cmd->add_sta_slot_interval = params->add_sta_slot_interval; 64 cmd->remove_sta_slot_interval = params->remove_sta_slot_interval; 65 66 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 67 WMI_TWT_ENABLE_CMDID); 68 if (QDF_IS_STATUS_ERROR(status)) { 69 WMI_LOGE("Failed to send WMI_TWT_ENABLE_CMDID"); 70 wmi_buf_free(buf); 71 } 72 73 return status; 74 } 75 76 77 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle, 78 struct wmi_twt_disable_param *params) 79 { 80 wmi_twt_disable_cmd_fixed_param *cmd; 81 wmi_buf_t buf; 82 QDF_STATUS status; 83 84 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 85 if (!buf) { 86 WMI_LOGE("Failed to allocate memory"); 87 return QDF_STATUS_E_FAILURE; 88 } 89 90 cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf); 91 WMITLV_SET_HDR(&cmd->tlv_header, 92 WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param, 93 WMITLV_GET_STRUCT_TLVLEN 94 (wmi_twt_disable_cmd_fixed_param)); 95 96 cmd->pdev_id = 97 wmi_handle->ops->convert_pdev_id_host_to_target( 98 params->pdev_id); 99 100 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 101 WMI_TWT_DISABLE_CMDID); 102 if (QDF_IS_STATUS_ERROR(status)) { 103 WMI_LOGE("Failed to send WMI_TWT_DISABLE_CMDID"); 104 wmi_buf_free(buf); 105 } 106 107 return status; 108 } 109 110 static QDF_STATUS send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle, 111 struct wmi_twt_add_dialog_param *params) 112 { 113 wmi_twt_add_dialog_cmd_fixed_param *cmd; 114 wmi_buf_t buf; 115 QDF_STATUS status; 116 117 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 118 if (!buf) { 119 WMI_LOGE("Failed to allocate memory"); 120 return QDF_STATUS_E_FAILURE; 121 } 122 123 cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf); 124 WMITLV_SET_HDR(&cmd->tlv_header, 125 WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param, 126 WMITLV_GET_STRUCT_TLVLEN 127 (wmi_twt_add_dialog_cmd_fixed_param)); 128 129 cmd->vdev_id = params->vdev_id; 130 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 131 cmd->dialog_id = params->dialog_id; 132 cmd->wake_intvl_us = params->wake_intvl_us; 133 cmd->wake_intvl_mantis = params->wake_intvl_mantis; 134 cmd->wake_dura_us = params->wake_dura_us; 135 cmd->sp_offset_us = params->sp_offset_us; 136 TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd); 137 TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast); 138 TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger); 139 TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type); 140 TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection); 141 142 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 143 WMI_TWT_ADD_DIALOG_CMDID); 144 if (QDF_IS_STATUS_ERROR(status)) { 145 WMI_LOGE("Failed to send WMI_TWT_ADD_DIALOG_CMDID"); 146 wmi_buf_free(buf); 147 } 148 149 return status; 150 } 151 152 static QDF_STATUS send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle, 153 struct wmi_twt_del_dialog_param *params) 154 { 155 wmi_twt_del_dialog_cmd_fixed_param *cmd; 156 wmi_buf_t buf; 157 QDF_STATUS status; 158 159 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 160 if (!buf) { 161 WMI_LOGE("Failed to allocate memory"); 162 return QDF_STATUS_E_FAILURE; 163 } 164 165 cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf); 166 WMITLV_SET_HDR(&cmd->tlv_header, 167 WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param, 168 WMITLV_GET_STRUCT_TLVLEN 169 (wmi_twt_del_dialog_cmd_fixed_param)); 170 171 cmd->vdev_id = params->vdev_id; 172 cmd->dialog_id = params->dialog_id; 173 174 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 175 WMI_TWT_DEL_DIALOG_CMDID); 176 if (QDF_IS_STATUS_ERROR(status)) { 177 WMI_LOGE("Failed to send WMI_TWT_DEL_DIALOG_CMDID"); 178 wmi_buf_free(buf); 179 } 180 181 return status; 182 } 183 184 static QDF_STATUS send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle, 185 struct wmi_twt_pause_dialog_cmd_param *params) 186 { 187 wmi_twt_pause_dialog_cmd_fixed_param *cmd; 188 wmi_buf_t buf; 189 QDF_STATUS status; 190 191 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 192 if (!buf) { 193 WMI_LOGE("Failed to allocate memory"); 194 return QDF_STATUS_E_FAILURE; 195 } 196 197 cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf); 198 WMITLV_SET_HDR(&cmd->tlv_header, 199 WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param, 200 WMITLV_GET_STRUCT_TLVLEN 201 (wmi_twt_pause_dialog_cmd_fixed_param)); 202 203 cmd->vdev_id = params->vdev_id; 204 cmd->dialog_id = params->dialog_id; 205 206 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 207 WMI_TWT_PAUSE_DIALOG_CMDID); 208 if (QDF_IS_STATUS_ERROR(status)) { 209 WMI_LOGE("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID"); 210 wmi_buf_free(buf); 211 } 212 213 return status; 214 } 215 216 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle, 217 struct wmi_twt_resume_dialog_cmd_param *params) 218 { 219 wmi_twt_resume_dialog_cmd_fixed_param *cmd; 220 wmi_buf_t buf; 221 QDF_STATUS status; 222 223 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 224 if (!buf) { 225 WMI_LOGE("Failed to allocate memory"); 226 return QDF_STATUS_E_FAILURE; 227 } 228 229 cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf); 230 WMITLV_SET_HDR(&cmd->tlv_header, 231 WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param, 232 WMITLV_GET_STRUCT_TLVLEN 233 (wmi_twt_resume_dialog_cmd_fixed_param)); 234 235 cmd->vdev_id = params->vdev_id; 236 cmd->dialog_id = params->dialog_id; 237 cmd->sp_offset_us = params->sp_offset_us; 238 239 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 240 WMI_TWT_RESUME_DIALOG_CMDID); 241 if (QDF_IS_STATUS_ERROR(status)) { 242 WMI_LOGE("Failed to send WMI_TWT_RESUME_DIALOG_CMDID"); 243 wmi_buf_free(buf); 244 } 245 246 return status; 247 } 248 249 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle, 250 uint8_t *evt_buf, 251 struct wmi_twt_enable_complete_event_param *params) 252 { 253 WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 254 wmi_twt_enable_complete_event_fixed_param *ev; 255 256 param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 257 if (!param_buf) { 258 WMI_LOGE("evt_buf is NULL"); 259 return QDF_STATUS_E_INVAL; 260 } 261 262 ev = param_buf->fixed_param; 263 264 params->pdev_id = 265 wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id); 266 params->status = ev->status; 267 268 return QDF_STATUS_SUCCESS; 269 } 270 271 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle, 272 uint8_t *evt_buf, 273 struct wmi_twt_disable_complete_event *params) 274 { 275 WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 276 wmi_twt_disable_complete_event_fixed_param *ev; 277 278 param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 279 if (!param_buf) { 280 WMI_LOGE("evt_buf is NULL"); 281 return QDF_STATUS_E_INVAL; 282 } 283 284 ev = param_buf->fixed_param; 285 286 #if 0 287 params->pdev_id = 288 wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id); 289 params->status = ev->status; 290 #endif 291 292 return QDF_STATUS_SUCCESS; 293 } 294 295 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv( 296 wmi_unified_t wmi_handle, 297 uint8_t *evt_buf, 298 struct wmi_twt_add_dialog_complete_event_param *params) 299 { 300 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 301 wmi_twt_add_dialog_complete_event_fixed_param *ev; 302 303 param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 304 if (!param_buf) { 305 WMI_LOGE("evt_buf is NULL"); 306 return QDF_STATUS_E_INVAL; 307 } 308 309 ev = param_buf->fixed_param; 310 311 params->vdev_id = ev->vdev_id; 312 params->status = ev->status; 313 params->dialog_id = ev->dialog_id; 314 315 return QDF_STATUS_SUCCESS; 316 } 317 318 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv( 319 wmi_unified_t wmi_handle, 320 uint8_t *evt_buf, 321 struct wmi_twt_del_dialog_complete_event_param *params) 322 { 323 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 324 wmi_twt_del_dialog_complete_event_fixed_param *ev; 325 326 param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 327 if (!param_buf) { 328 WMI_LOGE("evt_buf is NULL"); 329 return QDF_STATUS_E_INVAL; 330 } 331 332 ev = param_buf->fixed_param; 333 334 params->vdev_id = ev->vdev_id; 335 params->dialog_id = ev->dialog_id; 336 337 return QDF_STATUS_SUCCESS; 338 } 339 340 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv( 341 wmi_unified_t wmi_handle, 342 uint8_t *evt_buf, 343 struct wmi_twt_pause_dialog_complete_event_param *params) 344 { 345 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 346 wmi_twt_pause_dialog_complete_event_fixed_param *ev; 347 348 param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 349 if (!param_buf) { 350 WMI_LOGE("evt_buf is NULL"); 351 return QDF_STATUS_E_INVAL; 352 } 353 354 ev = param_buf->fixed_param; 355 356 params->vdev_id = ev->vdev_id; 357 params->status = ev->status; 358 params->dialog_id = ev->dialog_id; 359 360 return QDF_STATUS_SUCCESS; 361 } 362 363 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv( 364 wmi_unified_t wmi_handle, 365 uint8_t *evt_buf, 366 struct wmi_twt_resume_dialog_complete_event_param *params) 367 { 368 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf; 369 wmi_twt_resume_dialog_complete_event_fixed_param *ev; 370 371 param_buf = 372 (WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf; 373 if (!param_buf) { 374 WMI_LOGE("evt_buf is NULL"); 375 return QDF_STATUS_E_INVAL; 376 } 377 378 ev = param_buf->fixed_param; 379 380 params->vdev_id = ev->vdev_id; 381 params->status = ev->status; 382 params->dialog_id = ev->dialog_id; 383 384 return QDF_STATUS_SUCCESS; 385 } 386 387 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) 388 { 389 struct wmi_ops *ops = wmi_handle->ops; 390 391 ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv; 392 ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv; 393 ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv; 394 ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv; 395 ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv; 396 ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv; 397 ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv; 398 ops->extract_twt_disable_comp_event = 399 extract_twt_disable_comp_event_tlv; 400 ops->extract_twt_add_dialog_comp_event = 401 extract_twt_add_dialog_comp_event_tlv; 402 ops->extract_twt_del_dialog_comp_event = 403 extract_twt_del_dialog_comp_event_tlv; 404 ops->extract_twt_pause_dialog_comp_event = 405 extract_twt_pause_dialog_comp_event_tlv; 406 ops->extract_twt_resume_dialog_comp_event = 407 extract_twt_resume_dialog_comp_event_tlv; 408 } 409