1 2 /* 3 * Copyright (c) 2013-2019 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 <nan_public_structs.h> 24 #include <wmi_unified_nan_api.h> 25 #include <wlan_nan_msg_common_v2.h> 26 27 static QDF_STATUS 28 extract_nan_event_rsp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 29 struct nan_event_params *evt_params, 30 uint8_t **msg_buf) 31 { 32 WMI_NAN_EVENTID_param_tlvs *event; 33 wmi_nan_event_hdr *nan_rsp_event_hdr; 34 nan_msg_header_t *nan_msg_hdr; 35 wmi_nan_event_info *nan_evt_info; 36 37 /* 38 * This is how received evt looks like 39 * 40 * <-------------------- evt_buf -----------------------------------> 41 * 42 * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data --------> 43 * 44 * +-----------+---------+-----------------------+--------------------+- 45 * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data | 46 * +-----------+---------+-----------------------+--------------------+- 47 * 48 * (Only for NAN Enable Resp) 49 * <--wmi_nan_event_info--> 50 * +-----------+-----------+ 51 * | tlv_header| event_info| 52 * +-----------+-----------+ 53 * 54 */ 55 56 event = (WMI_NAN_EVENTID_param_tlvs *)evt_buf; 57 nan_rsp_event_hdr = event->fixed_param; 58 59 /* Actual data may include some padding, so data_len <= num_data */ 60 if (nan_rsp_event_hdr->data_len > event->num_data) { 61 WMI_LOGE("%s: Provided NAN event length(%d) exceeding actual length(%d)!", 62 __func__, nan_rsp_event_hdr->data_len, 63 event->num_data); 64 return QDF_STATUS_E_INVAL; 65 } 66 evt_params->buf_len = nan_rsp_event_hdr->data_len; 67 *msg_buf = event->data; 68 69 if (nan_rsp_event_hdr->data_len < sizeof(nan_msg_header_t) || 70 nan_rsp_event_hdr->data_len > (WMI_SVC_MSG_MAX_SIZE - 71 WMI_TLV_HDR_SIZE)) { 72 WMI_LOGE("%s: Invalid NAN event data length(%d)!", __func__, 73 nan_rsp_event_hdr->data_len); 74 return QDF_STATUS_E_INVAL; 75 } 76 nan_msg_hdr = (nan_msg_header_t *)event->data; 77 78 if (!wmi_service_enabled(wmi_handle, wmi_service_nan_dbs_support)) { 79 evt_params->evt_type = nan_event_id_generic_rsp; 80 return QDF_STATUS_SUCCESS; 81 } 82 83 switch (nan_msg_hdr->msg_id) { 84 case NAN_MSG_ID_ENABLE_RSP: 85 nan_evt_info = event->event_info; 86 evt_params->evt_type = nan_event_id_enable_rsp; 87 evt_params->mac_id = nan_evt_info->mac_id; 88 evt_params->is_nan_enable_success = (nan_evt_info->status == 0); 89 break; 90 case NAN_MSG_ID_DISABLE_IND: 91 evt_params->evt_type = nan_event_id_disable_ind; 92 break; 93 case NAN_MSG_ID_ERROR_RSP: 94 evt_params->evt_type = nan_event_id_error_rsp; 95 break; 96 default: 97 evt_params->evt_type = nan_event_id_generic_rsp; 98 break; 99 } 100 101 return QDF_STATUS_SUCCESS; 102 } 103 104 /** 105 * send_nan_disable_req_cmd_tlv() - to send nan disable request to target 106 * @wmi_handle: wmi handle 107 * @nan_msg: request data which will be non-null 108 * 109 * Return: CDF status 110 */ 111 static QDF_STATUS send_nan_disable_req_cmd_tlv(wmi_unified_t wmi_handle, 112 struct nan_disable_req *nan_msg) 113 { 114 QDF_STATUS ret; 115 wmi_nan_cmd_param *cmd; 116 wmi_nan_host_config_param *cfg; 117 wmi_buf_t buf; 118 /* Initialize with minimum length required, which is Scenario 2*/ 119 uint16_t len = sizeof(*cmd) + sizeof(*cfg) + 2 * WMI_TLV_HDR_SIZE; 120 uint16_t nan_data_len, nan_data_len_aligned = 0; 121 uint8_t *buf_ptr; 122 123 /* 124 * Scenario 1: NAN Disable with NAN msg data from upper layers 125 * 126 * <-----nan cmd param-----><-- WMI_TLV_HDR_SIZE --><--- data ----> 127 * +------------+----------+-----------------------+--------------+ 128 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_msg_data | 129 * +------------+----------+-----------------------+--------------+ 130 * 131 * <-- WMI_TLV_HDR_SIZE --><------nan host config params-----> 132 * -+-----------------------+---------------------------------+ 133 * | WMITLV_TAG_ARRAY_STRUC| tlv_header | 2g/5g disable flags| 134 * -+-----------------------+---------------------------------+ 135 * 136 * Scenario 2: NAN Disable without any NAN msg data from upper layers 137 * 138 * <------nan cmd param------><--WMI_TLV_HDR_SIZE--><--WMI_TLV_HDR_SI 139 * +------------+------------+----------------------+---------------- 140 * | tlv_header | data_len=0 | WMITLV_TAG_ARRAY_BYTE| WMITLV_TAG_ARRA 141 * +------------+------------+----------------------+---------------- 142 * 143 * ZE----><------nan host config params-----> 144 * -------+---------------------------------+ 145 * Y_STRUC| tlv_header | 2g/5g disable flags| 146 * -------+---------------------------------+ 147 */ 148 149 if (!nan_msg) { 150 WMI_LOGE("%s:nan req is not valid", __func__); 151 return QDF_STATUS_E_FAILURE; 152 } 153 154 nan_data_len = nan_msg->params.request_data_len; 155 156 if (nan_data_len) { 157 nan_data_len_aligned = roundup(nan_data_len, sizeof(uint32_t)); 158 if (nan_data_len_aligned < nan_data_len) { 159 WMI_LOGE("%s: Int overflow while rounding up data_len", 160 __func__); 161 return QDF_STATUS_E_FAILURE; 162 } 163 164 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE 165 - WMI_TLV_HDR_SIZE) { 166 WMI_LOGE("%s: nan_data_len exceeding wmi_max_msg_size", 167 __func__); 168 return QDF_STATUS_E_FAILURE; 169 } 170 171 len += nan_data_len_aligned; 172 } 173 174 buf = wmi_buf_alloc(wmi_handle, len); 175 if (!buf) 176 return QDF_STATUS_E_NOMEM; 177 178 buf_ptr = (uint8_t *)wmi_buf_data(buf); 179 cmd = (wmi_nan_cmd_param *)buf_ptr; 180 WMITLV_SET_HDR(&cmd->tlv_header, 181 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 182 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 183 184 cmd->data_len = nan_data_len; 185 WMI_LOGD("%s: nan data len value is %u", __func__, nan_data_len); 186 buf_ptr += sizeof(wmi_nan_cmd_param); 187 188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 189 buf_ptr += WMI_TLV_HDR_SIZE; 190 191 if (nan_data_len) { 192 qdf_mem_copy(buf_ptr, nan_msg->params.request_data, 193 cmd->data_len); 194 buf_ptr += nan_data_len_aligned; 195 } 196 197 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 198 sizeof(wmi_nan_host_config_param)); 199 buf_ptr += WMI_TLV_HDR_SIZE; 200 201 cfg = (wmi_nan_host_config_param *)buf_ptr; 202 WMITLV_SET_HDR(&cfg->tlv_header, 203 WMITLV_TAG_STRUC_wmi_nan_host_config_param, 204 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_host_config_param)); 205 cfg->nan_2g_disc_disable = nan_msg->disable_2g_discovery; 206 cfg->nan_5g_disc_disable = nan_msg->disable_5g_discovery; 207 208 wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0); 209 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 210 WMI_NAN_CMDID); 211 if (QDF_IS_STATUS_ERROR(ret)) { 212 WMI_LOGE("%s Failed to send set param command ret = %d", 213 __func__, ret); 214 wmi_buf_free(buf); 215 } 216 217 return ret; 218 } 219 220 /** 221 * send_nan_req_cmd_tlv() - to send nan request to target 222 * @wmi_handle: wmi handle 223 * @nan_msg: request data which will be non-null 224 * 225 * Return: CDF status 226 */ 227 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 228 struct nan_msg_params *nan_msg) 229 { 230 QDF_STATUS ret; 231 wmi_nan_cmd_param *cmd; 232 wmi_buf_t buf; 233 uint16_t len = sizeof(*cmd); 234 uint16_t nan_data_len, nan_data_len_aligned; 235 uint8_t *buf_ptr; 236 237 /* 238 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 239 * +------------+----------+-----------------------+--------------+ 240 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_msg_data | 241 * +------------+----------+-----------------------+--------------+ 242 */ 243 if (!nan_msg) { 244 WMI_LOGE("%s:nan req is not valid", __func__); 245 return QDF_STATUS_E_FAILURE; 246 } 247 nan_data_len = nan_msg->request_data_len; 248 nan_data_len_aligned = roundup(nan_msg->request_data_len, 249 sizeof(uint32_t)); 250 if (nan_data_len_aligned < nan_msg->request_data_len) { 251 WMI_LOGE("%s: integer overflow while rounding up data_len", 252 __func__); 253 return QDF_STATUS_E_FAILURE; 254 } 255 256 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 257 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 258 __func__); 259 return QDF_STATUS_E_FAILURE; 260 } 261 262 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 263 buf = wmi_buf_alloc(wmi_handle, len); 264 if (!buf) 265 return QDF_STATUS_E_NOMEM; 266 267 buf_ptr = (uint8_t *)wmi_buf_data(buf); 268 cmd = (wmi_nan_cmd_param *)buf_ptr; 269 WMITLV_SET_HDR(&cmd->tlv_header, 270 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 271 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 272 cmd->data_len = nan_msg->request_data_len; 273 WMI_LOGD("%s: The data len value is %u", __func__, 274 nan_msg->request_data_len); 275 buf_ptr += sizeof(wmi_nan_cmd_param); 276 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 277 buf_ptr += WMI_TLV_HDR_SIZE; 278 qdf_mem_copy(buf_ptr, nan_msg->request_data, cmd->data_len); 279 280 wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0); 281 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 282 WMI_NAN_CMDID); 283 if (QDF_IS_STATUS_ERROR(ret)) { 284 WMI_LOGE("%s Failed to send set param command ret = %d", 285 __func__, ret); 286 wmi_buf_free(buf); 287 } 288 289 return ret; 290 } 291 292 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 293 struct nan_datapath_initiator_req *ndp_req) 294 { 295 uint16_t len; 296 wmi_buf_t buf; 297 uint8_t *tlv_ptr; 298 QDF_STATUS status; 299 wmi_channel *ch_tlv; 300 wmi_ndp_initiator_req_fixed_param *cmd; 301 uint32_t passphrase_len, service_name_len; 302 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 303 wmi_ndp_transport_ip_param *tcp_ip_param; 304 305 /* 306 * WMI command expects 4 byte alligned len: 307 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 308 */ 309 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 310 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 311 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 312 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 313 service_name_len = 314 qdf_roundup(ndp_req->service_name.service_name_len, 4); 315 /* allocated memory for fixed params as well as variable size data */ 316 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 317 + ndp_cfg_len + ndp_app_info_len + pmk_len 318 + passphrase_len + service_name_len; 319 320 if (ndp_req->is_ipv6_addr_present) 321 len += sizeof(*tcp_ip_param); 322 323 buf = wmi_buf_alloc(wmi_handle, len); 324 if (!buf) { 325 return QDF_STATUS_E_NOMEM; 326 } 327 328 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 329 WMITLV_SET_HDR(&cmd->tlv_header, 330 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 331 WMITLV_GET_STRUCT_TLVLEN( 332 wmi_ndp_initiator_req_fixed_param)); 333 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 334 cmd->transaction_id = ndp_req->transaction_id; 335 cmd->service_instance_id = ndp_req->service_instance_id; 336 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 337 &cmd->peer_discovery_mac_addr); 338 339 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 340 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 341 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 342 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 343 cmd->nan_csid = ndp_req->ncs_sk_type; 344 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 345 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 346 347 ch_tlv = (wmi_channel *)&cmd[1]; 348 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 349 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 350 ch_tlv->mhz = ndp_req->channel; 351 tlv_ptr = (uint8_t *)&ch_tlv[1]; 352 353 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 354 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 355 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 356 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 357 358 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 359 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 360 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 361 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 362 363 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 364 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 365 cmd->nan_pmk_len); 366 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 367 368 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 369 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 370 cmd->nan_passphrase_len); 371 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 372 373 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 374 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 375 ndp_req->service_name.service_name, 376 cmd->nan_servicename_len); 377 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 378 379 if (ndp_req->is_ipv6_addr_present) { 380 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 381 WMITLV_SET_HDR(tcp_ip_param, 382 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 383 WMITLV_GET_STRUCT_TLVLEN( 384 wmi_ndp_transport_ip_param)); 385 tcp_ip_param->ipv6_addr_present = true; 386 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 387 ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 388 } 389 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 390 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr); 391 392 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 393 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 394 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 395 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 396 cmd->peer_discovery_mac_addr.mac_addr31to0, 397 cmd->peer_discovery_mac_addr.mac_addr47to32); 398 399 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 400 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 401 ndp_req->ndp_config.ndp_cfg, 402 ndp_req->ndp_config.ndp_cfg_len); 403 404 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 405 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 406 ndp_req->ndp_info.ndp_app_info, 407 ndp_req->ndp_info.ndp_app_info_len); 408 409 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 410 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 411 ndp_req->pmk.pmk, cmd->nan_pmk_len); 412 413 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 414 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 415 ndp_req->passphrase.passphrase, 416 cmd->nan_passphrase_len); 417 418 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 419 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 420 ndp_req->service_name.service_name, 421 cmd->nan_servicename_len); 422 423 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 424 WMI_NDP_INITIATOR_REQ_CMDID); 425 426 wmi_mtrace(WMI_NDP_INITIATOR_REQ_CMDID, cmd->vdev_id, 0); 427 status = wmi_unified_cmd_send(wmi_handle, buf, len, 428 WMI_NDP_INITIATOR_REQ_CMDID); 429 if (QDF_IS_STATUS_ERROR(status)) { 430 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 431 wmi_buf_free(buf); 432 } 433 434 return status; 435 } 436 437 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 438 struct nan_datapath_responder_req *req) 439 { 440 uint16_t len; 441 wmi_buf_t buf; 442 uint8_t *tlv_ptr; 443 QDF_STATUS status; 444 wmi_ndp_responder_req_fixed_param *cmd; 445 wmi_ndp_transport_ip_param *tcp_ip_param; 446 uint32_t passphrase_len, service_name_len; 447 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 448 449 vdev_id = wlan_vdev_get_id(req->vdev); 450 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 451 vdev_id, req->transaction_id, 452 req->ndp_rsp, 453 req->ndp_instance_id, 454 req->ndp_info.ndp_app_info_len); 455 456 /* 457 * WMI command expects 4 byte alligned len: 458 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 459 */ 460 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 461 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 462 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 463 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 464 service_name_len = 465 qdf_roundup(req->service_name.service_name_len, 4); 466 467 /* allocated memory for fixed params as well as variable size data */ 468 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 469 + pmk_len + passphrase_len + service_name_len; 470 471 if (req->is_ipv6_addr_present || req->is_port_present || 472 req->is_protocol_present) 473 len += sizeof(*tcp_ip_param); 474 475 buf = wmi_buf_alloc(wmi_handle, len); 476 if (!buf) { 477 return QDF_STATUS_E_NOMEM; 478 } 479 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 480 WMITLV_SET_HDR(&cmd->tlv_header, 481 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 482 WMITLV_GET_STRUCT_TLVLEN( 483 wmi_ndp_responder_req_fixed_param)); 484 cmd->vdev_id = vdev_id; 485 cmd->transaction_id = req->transaction_id; 486 cmd->ndp_instance_id = req->ndp_instance_id; 487 cmd->rsp_code = req->ndp_rsp; 488 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 489 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 490 cmd->nan_pmk_len = req->pmk.pmk_len; 491 cmd->nan_csid = req->ncs_sk_type; 492 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 493 cmd->nan_servicename_len = req->service_name.service_name_len; 494 495 tlv_ptr = (uint8_t *)&cmd[1]; 496 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 497 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 498 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 499 500 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 501 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 502 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 503 req->ndp_info.ndp_app_info, 504 req->ndp_info.ndp_app_info_len); 505 506 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 507 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 508 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 509 cmd->nan_pmk_len); 510 511 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 512 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 513 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 514 req->passphrase.passphrase, 515 cmd->nan_passphrase_len); 516 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 517 518 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 519 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 520 req->service_name.service_name, 521 cmd->nan_servicename_len); 522 523 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 524 525 if (req->is_ipv6_addr_present || req->is_port_present || 526 req->is_protocol_present) { 527 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 528 WMITLV_SET_HDR(tcp_ip_param, 529 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 530 WMITLV_GET_STRUCT_TLVLEN( 531 wmi_ndp_transport_ip_param)); 532 tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present; 533 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 534 req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 535 536 tcp_ip_param->trans_port_present = req->is_port_present; 537 tcp_ip_param->transport_port = req->port; 538 539 tcp_ip_param->trans_proto_present = req->is_protocol_present; 540 tcp_ip_param->transport_protocol = req->protocol; 541 } 542 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 543 req->is_ipv6_addr_present, req->ipv6_addr); 544 WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port); 545 WMI_LOGD(FL("protocol: %d present: %d"), 546 req->is_protocol_present, req->protocol); 547 548 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 549 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 550 551 WMI_LOGD("ndp_config len: %d", 552 req->ndp_config.ndp_cfg_len); 553 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 554 req->ndp_config.ndp_cfg, 555 req->ndp_config.ndp_cfg_len); 556 557 WMI_LOGD("ndp_app_info len: %d", 558 req->ndp_info.ndp_app_info_len); 559 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 560 req->ndp_info.ndp_app_info, 561 req->ndp_info.ndp_app_info_len); 562 563 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 564 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 565 req->pmk.pmk, cmd->nan_pmk_len); 566 567 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 568 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 569 req->passphrase.passphrase, 570 cmd->nan_passphrase_len); 571 572 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 573 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 574 req->service_name.service_name, 575 cmd->nan_servicename_len); 576 577 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 578 WMI_NDP_RESPONDER_REQ_CMDID); 579 wmi_mtrace(WMI_NDP_RESPONDER_REQ_CMDID, cmd->vdev_id, 0); 580 status = wmi_unified_cmd_send(wmi_handle, buf, len, 581 WMI_NDP_RESPONDER_REQ_CMDID); 582 if (QDF_IS_STATUS_ERROR(status)) { 583 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 584 wmi_buf_free(buf); 585 } 586 return status; 587 } 588 589 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 590 struct nan_datapath_end_req *req) 591 { 592 uint16_t len; 593 wmi_buf_t buf; 594 QDF_STATUS status; 595 uint32_t ndp_end_req_len, i; 596 wmi_ndp_end_req *ndp_end_req_lst; 597 wmi_ndp_end_req_fixed_param *cmd; 598 599 /* len of tlv following fixed param */ 600 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 601 /* above comes out to 4 byte alligned already, no need of padding */ 602 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 603 buf = wmi_buf_alloc(wmi_handle, len); 604 if (!buf) { 605 return QDF_STATUS_E_NOMEM; 606 } 607 608 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 609 WMITLV_SET_HDR(&cmd->tlv_header, 610 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 611 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 612 613 cmd->transaction_id = req->transaction_id; 614 615 /* set tlv pointer to end of fixed param */ 616 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 617 ndp_end_req_len); 618 619 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 620 WMI_TLV_HDR_SIZE); 621 for (i = 0; i < req->num_ndp_instances; i++) { 622 WMITLV_SET_HDR(&ndp_end_req_lst[i], 623 WMITLV_TAG_ARRAY_FIXED_STRUC, 624 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 625 626 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 627 } 628 629 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 630 wmi_mtrace(WMI_NDP_END_REQ_CMDID, NO_SESSION, 0); 631 status = wmi_unified_cmd_send(wmi_handle, buf, len, 632 WMI_NDP_END_REQ_CMDID); 633 if (QDF_IS_STATUS_ERROR(status)) { 634 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 635 wmi_buf_free(buf); 636 } 637 638 return status; 639 } 640 641 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 642 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 643 { 644 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 645 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 646 647 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 648 fixed_params = event->fixed_param; 649 650 rsp->vdev = 651 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 652 fixed_params->vdev_id, 653 WLAN_NAN_ID); 654 if (!rsp->vdev) { 655 WMI_LOGE("vdev is null"); 656 return QDF_STATUS_E_INVAL; 657 } 658 659 rsp->transaction_id = fixed_params->transaction_id; 660 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 661 rsp->status = fixed_params->rsp_status; 662 rsp->reason = fixed_params->reason_code; 663 664 return QDF_STATUS_SUCCESS; 665 } 666 667 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 668 uint8_t *data, struct nan_datapath_indication_event *rsp) 669 { 670 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 671 wmi_ndp_indication_event_fixed_param *fixed_params; 672 size_t total_array_len; 673 674 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 675 fixed_params = 676 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 677 678 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 679 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 680 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 681 return QDF_STATUS_E_INVAL; 682 } 683 684 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 685 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 686 fixed_params->ndp_app_info_len, 687 event->num_ndp_app_info); 688 return QDF_STATUS_E_INVAL; 689 } 690 691 if (fixed_params->ndp_cfg_len > 692 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 693 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 694 __func__, fixed_params->ndp_cfg_len); 695 return QDF_STATUS_E_INVAL; 696 } 697 698 total_array_len = fixed_params->ndp_cfg_len + 699 sizeof(*fixed_params); 700 701 if (fixed_params->ndp_app_info_len > 702 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 703 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 704 __func__, fixed_params->ndp_app_info_len); 705 return QDF_STATUS_E_INVAL; 706 } 707 total_array_len += fixed_params->ndp_app_info_len; 708 709 if (fixed_params->nan_scid_len > 710 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 711 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 712 __func__, fixed_params->nan_scid_len); 713 return QDF_STATUS_E_INVAL; 714 } 715 716 rsp->vdev = 717 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 718 fixed_params->vdev_id, 719 WLAN_NAN_ID); 720 if (!rsp->vdev) { 721 WMI_LOGE("vdev is null"); 722 return QDF_STATUS_E_INVAL; 723 } 724 rsp->service_instance_id = fixed_params->service_instance_id; 725 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 726 rsp->role = fixed_params->self_ndp_role; 727 rsp->policy = fixed_params->accept_policy; 728 729 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 730 rsp->peer_mac_addr.bytes); 731 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 732 rsp->peer_discovery_mac_addr.bytes); 733 734 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 735 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 736 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 737 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 738 fixed_params->service_instance_id, 739 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 740 fixed_params->accept_policy, 741 fixed_params->nan_csid, fixed_params->nan_scid_len, 742 rsp->peer_mac_addr.bytes, 743 rsp->peer_discovery_mac_addr.bytes); 744 745 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 746 747 WMI_LOGD("ndp_app_info - %d bytes", 748 fixed_params->ndp_app_info_len); 749 750 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 751 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 752 rsp->ncs_sk_type = fixed_params->nan_csid; 753 rsp->scid.scid_len = fixed_params->nan_scid_len; 754 755 if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN) 756 rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN; 757 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 758 rsp->ndp_config.ndp_cfg_len); 759 760 if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN) 761 rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN; 762 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 763 rsp->ndp_info.ndp_app_info_len); 764 765 if (rsp->scid.scid_len > NDP_SCID_BUF_LEN) 766 rsp->scid.scid_len = NDP_SCID_BUF_LEN; 767 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 768 769 if (event->ndp_transport_ip_param && 770 event->num_ndp_transport_ip_param) { 771 if (event->ndp_transport_ip_param->ipv6_addr_present) { 772 rsp->is_ipv6_addr_present = true; 773 qdf_mem_copy(rsp->ipv6_addr, 774 event->ndp_transport_ip_param->ipv6_intf_addr, 775 WMI_NDP_IPV6_INTF_ADDR_LEN); 776 } 777 } 778 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 779 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 780 781 return QDF_STATUS_SUCCESS; 782 } 783 784 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 785 uint8_t *data, struct nan_datapath_confirm_event *rsp) 786 { 787 uint8_t i; 788 WMI_HOST_WLAN_PHY_MODE ch_mode; 789 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 790 wmi_ndp_confirm_event_fixed_param *fixed_params; 791 size_t total_array_len; 792 793 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 794 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 795 WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) received. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d", 796 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 797 fixed_params->ndp_instance_id, fixed_params->rsp_code, 798 fixed_params->reason_code, 799 fixed_params->num_active_ndps_on_peer); 800 WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels); 801 802 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 803 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 804 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 805 return QDF_STATUS_E_INVAL; 806 } 807 808 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 809 810 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 811 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 812 fixed_params->ndp_app_info_len, 813 event->num_ndp_app_info); 814 return QDF_STATUS_E_INVAL; 815 } 816 817 WMI_LOGD("ndp_app_info - %d bytes", 818 fixed_params->ndp_app_info_len); 819 820 if (fixed_params->ndp_cfg_len > 821 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 822 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 823 __func__, fixed_params->ndp_cfg_len); 824 return QDF_STATUS_E_INVAL; 825 } 826 827 total_array_len = fixed_params->ndp_cfg_len + 828 sizeof(*fixed_params); 829 830 if (fixed_params->ndp_app_info_len > 831 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 832 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 833 __func__, fixed_params->ndp_app_info_len); 834 return QDF_STATUS_E_INVAL; 835 } 836 837 if (fixed_params->num_ndp_channels > event->num_ndp_channel_list || 838 fixed_params->num_ndp_channels > event->num_nss_list) { 839 WMI_LOGE(FL("NDP Ch count %d greater than NDP Ch TLV len (%d) or NSS TLV len (%d)"), 840 fixed_params->num_ndp_channels, 841 event->num_ndp_channel_list, 842 event->num_nss_list); 843 return QDF_STATUS_E_INVAL; 844 } 845 846 rsp->vdev = 847 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 848 fixed_params->vdev_id, 849 WLAN_NAN_ID); 850 if (!rsp->vdev) { 851 WMI_LOGE("vdev is null"); 852 return QDF_STATUS_E_INVAL; 853 } 854 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 855 rsp->rsp_code = fixed_params->rsp_code; 856 rsp->reason_code = fixed_params->reason_code; 857 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 858 rsp->num_channels = fixed_params->num_ndp_channels; 859 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 860 rsp->peer_ndi_mac_addr.bytes); 861 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 862 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 863 rsp->ndp_info.ndp_app_info_len); 864 865 if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 866 WMI_LOGE(FL("too many channels")); 867 rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS; 868 } 869 870 for (i = 0; i < rsp->num_channels; i++) { 871 rsp->ch[i].channel = event->ndp_channel_list[i].mhz; 872 rsp->ch[i].nss = event->nss_list[i]; 873 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]); 874 rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 875 ch_mode); 876 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 877 rsp->ch[i].channel, 878 rsp->ch[i].ch_width, 879 rsp->ch[i].nss); 880 } 881 882 if (event->ndp_transport_ip_param && 883 event->num_ndp_transport_ip_param) { 884 if (event->ndp_transport_ip_param->ipv6_addr_present) { 885 rsp->is_ipv6_addr_present = true; 886 qdf_mem_copy(rsp->ipv6_addr, 887 event->ndp_transport_ip_param->ipv6_intf_addr, 888 WMI_NDP_IPV6_INTF_ADDR_LEN); 889 } 890 891 if (event->ndp_transport_ip_param->trans_port_present) { 892 rsp->is_port_present = true; 893 rsp->port = 894 event->ndp_transport_ip_param->transport_port; 895 } 896 897 if (event->ndp_transport_ip_param->trans_proto_present) { 898 rsp->is_protocol_present = true; 899 rsp->protocol = 900 event->ndp_transport_ip_param->transport_protocol; 901 } 902 } 903 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 904 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 905 WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present); 906 WMI_LOGD(FL("protocol: %d present: %d"), 907 rsp->protocol, rsp->is_protocol_present); 908 909 return QDF_STATUS_SUCCESS; 910 } 911 912 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 913 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 914 { 915 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 916 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 917 918 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 919 fixed_params = event->fixed_param; 920 921 WMI_LOGD("WMI_NDP_RESPONDER_RSP_EVENTID(0x%X) received. vdev_id: %d, peer_mac_addr: %pM,transaction_id: %d, status_code %d, reason_code: %d, create_peer: %d", 922 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 923 rsp->peer_mac_addr.bytes, rsp->transaction_id, 924 rsp->status, rsp->reason, rsp->create_peer); 925 926 rsp->vdev = 927 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 928 fixed_params->vdev_id, 929 WLAN_NAN_ID); 930 if (!rsp->vdev) { 931 WMI_LOGE("vdev is null"); 932 return QDF_STATUS_E_INVAL; 933 } 934 rsp->transaction_id = fixed_params->transaction_id; 935 rsp->reason = fixed_params->reason_code; 936 rsp->status = fixed_params->rsp_status; 937 rsp->create_peer = fixed_params->create_peer; 938 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 939 rsp->peer_mac_addr.bytes); 940 941 return QDF_STATUS_SUCCESS; 942 } 943 944 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 945 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 946 { 947 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 948 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 949 950 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 951 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 952 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 953 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 954 fixed_params->rsp_status, fixed_params->reason_code); 955 956 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 957 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 958 if (!rsp->vdev) { 959 WMI_LOGE("vdev is null"); 960 return QDF_STATUS_E_INVAL; 961 } 962 rsp->transaction_id = fixed_params->transaction_id; 963 rsp->reason = fixed_params->reason_code; 964 rsp->status = fixed_params->rsp_status; 965 966 return QDF_STATUS_SUCCESS; 967 } 968 969 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 970 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 971 { 972 uint32_t i, buf_size; 973 wmi_ndp_end_indication *ind; 974 struct qdf_mac_addr peer_addr; 975 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 976 977 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 978 ind = event->ndp_end_indication_list; 979 980 if (event->num_ndp_end_indication_list == 0) { 981 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 982 return QDF_STATUS_E_INVAL; 983 } 984 985 WMI_LOGD("number of ndp instances = %d", 986 event->num_ndp_end_indication_list); 987 988 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 989 sizeof((*rsp)->ndp_map[0]))) { 990 WMI_LOGE("num_ndp_end_ind_list %d too large", 991 event->num_ndp_end_indication_list); 992 return QDF_STATUS_E_INVAL; 993 } 994 995 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 996 sizeof((*rsp)->ndp_map[0]); 997 *rsp = qdf_mem_malloc(buf_size); 998 if (!(*rsp)) { 999 WMI_LOGE("Failed to allocate memory"); 1000 return QDF_STATUS_E_NOMEM; 1001 } 1002 1003 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 1004 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 1005 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 1006 peer_addr.bytes); 1007 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 1008 i, ind[i].type, ind[i].reason_code, 1009 ind[i].ndp_instance_id, 1010 ind[i].num_active_ndps_on_peer); 1011 /* Add each instance entry to the list */ 1012 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 1013 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 1014 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 1015 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 1016 (*rsp)->ndp_map[i].num_active_ndp_sessions = 1017 ind[i].num_active_ndps_on_peer; 1018 (*rsp)->ndp_map[i].type = ind[i].type; 1019 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 1020 } 1021 1022 return QDF_STATUS_SUCCESS; 1023 } 1024 1025 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle, 1026 uint8_t *data, struct nan_datapath_sch_update_event *ind) 1027 { 1028 uint8_t i; 1029 WMI_HOST_WLAN_PHY_MODE ch_mode; 1030 WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event; 1031 wmi_ndl_schedule_update_fixed_param *fixed_params; 1032 1033 event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data; 1034 fixed_params = event->fixed_param; 1035 1036 WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"), 1037 fixed_params->flags, fixed_params->num_channels, 1038 fixed_params->num_ndp_instances); 1039 1040 if (fixed_params->num_channels > event->num_ndl_channel_list || 1041 fixed_params->num_channels > event->num_nss_list) { 1042 WMI_LOGE(FL("Channel count %d greater than NDP Ch list TLV len (%d) or NSS list TLV len (%d)"), 1043 fixed_params->num_channels, 1044 event->num_ndl_channel_list, 1045 event->num_nss_list); 1046 return QDF_STATUS_E_INVAL; 1047 } 1048 if (fixed_params->num_ndp_instances > event->num_ndp_instance_list) { 1049 WMI_LOGE(FL("NDP Instance count %d greater than NDP Instancei TLV len %d"), 1050 fixed_params->num_ndp_instances, 1051 event->num_ndp_instance_list); 1052 return QDF_STATUS_E_INVAL; 1053 } 1054 1055 ind->vdev = 1056 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 1057 fixed_params->vdev_id, 1058 WLAN_NAN_ID); 1059 if (!ind->vdev) { 1060 WMI_LOGE("vdev is null"); 1061 return QDF_STATUS_E_INVAL; 1062 } 1063 1064 ind->flags = fixed_params->flags; 1065 ind->num_channels = fixed_params->num_channels; 1066 ind->num_ndp_instances = fixed_params->num_ndp_instances; 1067 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr, 1068 ind->peer_addr.bytes); 1069 1070 if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) { 1071 WMI_LOGE(FL("uint32 overflow")); 1072 wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID); 1073 return QDF_STATUS_E_INVAL; 1074 } 1075 1076 qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list, 1077 sizeof(uint32_t) * ind->num_ndp_instances); 1078 1079 if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 1080 WMI_LOGE(FL("too many channels")); 1081 ind->num_channels = NAN_CH_INFO_MAX_CHANNELS; 1082 } 1083 1084 for (i = 0; i < ind->num_channels; i++) { 1085 ind->ch[i].channel = event->ndl_channel_list[i].mhz; 1086 ind->ch[i].nss = event->nss_list[i]; 1087 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]); 1088 ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 1089 ch_mode); 1090 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 1091 ind->ch[i].channel, 1092 ind->ch[i].ch_width, 1093 ind->ch[i].nss); 1094 } 1095 1096 for (i = 0; i < fixed_params->num_ndp_instances; i++) 1097 WMI_LOGD(FL("instance_id[%d]: %d"), 1098 i, event->ndp_instance_list[i]); 1099 1100 return QDF_STATUS_SUCCESS; 1101 } 1102 1103 void wmi_nan_attach_tlv(wmi_unified_t wmi_handle) 1104 { 1105 struct wmi_ops *ops = wmi_handle->ops; 1106 1107 ops->send_nan_req_cmd = send_nan_req_cmd_tlv; 1108 ops->send_nan_disable_req_cmd = send_nan_disable_req_cmd_tlv; 1109 ops->extract_nan_event_rsp = extract_nan_event_rsp_tlv; 1110 ops->send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv; 1111 ops->send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv; 1112 ops->send_ndp_end_req_cmd = nan_ndp_end_req_tlv; 1113 ops->extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv; 1114 ops->extract_ndp_ind = extract_ndp_ind_tlv; 1115 ops->extract_ndp_confirm = extract_ndp_confirm_tlv; 1116 ops->extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv; 1117 ops->extract_ndp_end_rsp = extract_ndp_end_rsp_tlv; 1118 ops->extract_ndp_end_ind = extract_ndp_end_ind_tlv; 1119 ops->extract_ndp_sch_update = extract_ndp_sch_update_tlv; 1120 } 1121