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