1 /* 2 * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: defines nan component os interface APIs 21 */ 22 23 #include "osif_sync.h" 24 #include "qdf_str.h" 25 #include "qdf_trace.h" 26 #include "qdf_types.h" 27 #include "os_if_nan.h" 28 #include "wlan_nan_api.h" 29 #include "nan_ucfg_api.h" 30 #include "wlan_osif_priv.h" 31 #include <net/cfg80211.h> 32 #include "wlan_cfg80211.h" 33 #include "wlan_objmgr_psoc_obj.h" 34 #include "wlan_objmgr_pdev_obj.h" 35 #include "wlan_objmgr_vdev_obj.h" 36 #include "wlan_utility.h" 37 #include "wlan_osif_request_manager.h" 38 39 #define NAN_CMD_MAX_SIZE 2048 40 41 /* NLA policy */ 42 static const struct nla_policy 43 nan_attr_policy[QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX + 1] = { 44 [QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA] = { 45 .type = NLA_BINARY, 46 .len = NAN_CMD_MAX_SIZE 47 }, 48 [QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE] = { 49 .type = NLA_U32, 50 .len = sizeof(uint32_t) 51 }, 52 [QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ] = { 53 .type = NLA_U32, 54 .len = sizeof(uint32_t) 55 }, 56 [QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ] = { 57 .type = NLA_U32, 58 .len = sizeof(uint32_t) 59 }, 60 }; 61 62 /* NLA policy */ 63 static const struct nla_policy 64 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { 65 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { 66 .type = NLA_U32, 67 .len = sizeof(uint32_t) 68 }, 69 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { 70 .type = NLA_U16, 71 .len = sizeof(uint16_t) 72 }, 73 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { 74 .type = NLA_NUL_STRING, 75 .len = IFNAMSIZ - 1 76 }, 77 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { 78 .type = NLA_U32, 79 .len = sizeof(uint32_t) 80 }, 81 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { 82 .type = NLA_U32, 83 .len = sizeof(uint32_t) 84 }, 85 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { 86 .type = NLA_UNSPEC, 87 .len = QDF_MAC_ADDR_SIZE 88 }, 89 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { 90 .type = NLA_U16, 91 .len = sizeof(uint16_t) 92 }, 93 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { 94 .type = NLA_U32, 95 .len = sizeof(uint32_t) 96 }, 97 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { 98 .type = NLA_BINARY, 99 .len = NDP_APP_INFO_LEN 100 }, 101 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { 102 .type = NLA_U32, 103 .len = sizeof(uint32_t) 104 }, 105 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { 106 .type = NLA_U32, 107 .len = sizeof(uint32_t) 108 }, 109 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { 110 .type = NLA_BINARY, 111 .len = QDF_MAC_ADDR_SIZE 112 }, 113 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { 114 .type = NLA_BINARY, 115 .len = NDP_NUM_INSTANCE_ID 116 }, 117 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { 118 .type = NLA_U32, 119 .len = sizeof(uint32_t) 120 }, 121 [QCA_WLAN_VENDOR_ATTR_NDP_CSID] = { 122 .type = NLA_U32, 123 .len = sizeof(uint32_t) 124 }, 125 [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { 126 .type = NLA_BINARY, 127 .len = NDP_PMK_LEN 128 }, 129 [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { 130 .type = NLA_BINARY, 131 .len = NDP_SCID_BUF_LEN 132 }, 133 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { 134 .type = NLA_U32, 135 .len = sizeof(uint32_t) 136 }, 137 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { 138 .type = NLA_U32, 139 .len = sizeof(uint32_t) 140 }, 141 [QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = { 142 .type = NLA_BINARY, 143 .len = NAN_PASSPHRASE_MAX_LEN 144 }, 145 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = { 146 .type = NLA_BINARY, 147 .len = NAN_MAX_SERVICE_NAME_LEN 148 }, 149 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO] = { 150 .type = NLA_BINARY, 151 .len = NAN_CH_INFO_MAX_LEN 152 }, 153 [QCA_WLAN_VENDOR_ATTR_NDP_NSS] = { 154 .type = NLA_U32, 155 .len = sizeof(uint32_t) 156 }, 157 [QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR] = { 158 .type = NLA_UNSPEC, 159 .len = QDF_IPV6_ADDR_SIZE 160 }, 161 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT] = { 162 .type = NLA_U16, 163 .len = sizeof(uint16_t) 164 }, 165 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL] = { 166 .type = NLA_U8, 167 .len = sizeof(uint8_t) 168 }, 169 }; 170 171 /** 172 * os_if_get_ndi_vdev_by_ifname_cb() - callback function to return vdev object 173 * from psoc matching given interface name 174 * @psoc: psoc object 175 * @obj: object used to iterate the callback function 176 * @arg: return argument which will be filled by the function 177 * 178 * Return : NULL 179 */ 180 static void os_if_get_ndi_vdev_by_ifname_cb(struct wlan_objmgr_psoc *psoc, 181 void *obj, void *arg) 182 { 183 struct wlan_objmgr_vdev *vdev = obj; 184 struct ndi_find_vdev_filter *filter = arg; 185 struct vdev_osif_priv *osif_priv; 186 187 if (filter->found_vdev) 188 return; 189 190 wlan_vdev_obj_lock(vdev); 191 192 osif_priv = wlan_vdev_get_ospriv(vdev); 193 if (!osif_priv) { 194 wlan_vdev_obj_unlock(vdev); 195 return; 196 } 197 198 if (!osif_priv->wdev) { 199 wlan_vdev_obj_unlock(vdev); 200 return; 201 } 202 203 if (!qdf_str_cmp(osif_priv->wdev->netdev->name, filter->ifname)) 204 filter->found_vdev = vdev; 205 206 wlan_vdev_obj_unlock(vdev); 207 } 208 209 /** 210 * os_if_get_ndi_vdev_by_ifname() - function to return vdev object from psoc 211 * matching given interface name 212 * @psoc: psoc object 213 * @ifname: interface name 214 * 215 * This function returns vdev object from psoc by interface name. If found this 216 * will also take reference with given ref_id 217 * 218 * Return : vdev object if found, NULL otherwise 219 */ 220 static struct wlan_objmgr_vdev * 221 os_if_get_ndi_vdev_by_ifname(struct wlan_objmgr_psoc *psoc, char *ifname) 222 { 223 QDF_STATUS status; 224 struct ndi_find_vdev_filter filter = {0}; 225 226 filter.ifname = ifname; 227 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, 228 os_if_get_ndi_vdev_by_ifname_cb, 229 &filter, 0, WLAN_NAN_ID); 230 231 if (!filter.found_vdev) 232 return NULL; 233 234 status = wlan_objmgr_vdev_try_get_ref(filter.found_vdev, WLAN_NAN_ID); 235 if (QDF_IS_STATUS_ERROR(status)) 236 return NULL; 237 238 return filter.found_vdev; 239 } 240 241 /** 242 * os_if_ndi_get_if_name() - get vdev's interface name 243 * @vdev: VDEV object 244 * 245 * API to get vdev's interface name 246 * 247 * Return: vdev's interface name 248 */ 249 static const uint8_t *os_if_ndi_get_if_name(struct wlan_objmgr_vdev *vdev) 250 { 251 struct vdev_osif_priv *osif_priv; 252 253 wlan_vdev_obj_lock(vdev); 254 255 osif_priv = wlan_vdev_get_ospriv(vdev); 256 if (!osif_priv) { 257 wlan_vdev_obj_unlock(vdev); 258 return NULL; 259 } 260 261 if (!osif_priv->wdev) { 262 wlan_vdev_obj_unlock(vdev); 263 return NULL; 264 } 265 266 wlan_vdev_obj_unlock(vdev); 267 268 return osif_priv->wdev->netdev->name; 269 } 270 271 static int __os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, 272 char *iface_name, 273 struct nlattr **tb) 274 { 275 int ret; 276 QDF_STATUS status; 277 uint16_t transaction_id; 278 struct wlan_objmgr_vdev *nan_vdev; 279 struct nan_callbacks cb_obj; 280 281 osif_debug("enter"); 282 283 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); 284 if (nan_vdev) { 285 osif_err("NAN data interface %s is already present", 286 iface_name); 287 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); 288 return -EEXIST; 289 } 290 291 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { 292 osif_err("transaction id is unavailable"); 293 return -EINVAL; 294 } 295 transaction_id = 296 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); 297 298 status = ucfg_nan_get_callbacks(psoc, &cb_obj); 299 if (QDF_IS_STATUS_ERROR(status)) { 300 osif_err("Couldn't get ballback object"); 301 return -EINVAL; 302 } 303 304 ret = cb_obj.ndi_open(iface_name); 305 if (ret) { 306 osif_err("ndi_open failed"); 307 return ret; 308 } 309 310 return cb_obj.ndi_start(iface_name, transaction_id); 311 } 312 313 static int 314 osif_nla_str(struct nlattr **tb, size_t attr_id, char **out_str) 315 { 316 if (!tb || !tb[attr_id]) 317 return -EINVAL; 318 319 *out_str = nla_data(tb[attr_id]); 320 321 return 0; 322 } 323 324 static int 325 osif_device_from_psoc(struct wlan_objmgr_psoc *psoc, struct device **out_dev) 326 { 327 qdf_device_t qdf_dev; 328 329 if (!psoc) 330 return -EINVAL; 331 332 qdf_dev = wlan_psoc_get_qdf_dev(psoc); 333 if (!qdf_dev || !qdf_dev->dev) 334 return -EINVAL; 335 336 *out_dev = qdf_dev->dev; 337 338 return 0; 339 } 340 341 static int osif_net_dev_from_vdev(struct wlan_objmgr_vdev *vdev, 342 struct net_device **out_net_dev) 343 { 344 struct vdev_osif_priv *priv; 345 346 if (!vdev) 347 return -EINVAL; 348 349 priv = wlan_vdev_get_ospriv(vdev); 350 if (!priv || !priv->wdev || !priv->wdev->netdev) 351 return -EINVAL; 352 353 *out_net_dev = priv->wdev->netdev; 354 355 return 0; 356 } 357 358 static int osif_net_dev_from_ifname(struct wlan_objmgr_psoc *psoc, 359 char *iface_name, 360 struct net_device **out_net_dev) 361 { 362 struct wlan_objmgr_vdev *vdev; 363 struct net_device *net_dev; 364 int errno; 365 366 vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); 367 if (!vdev) 368 return -EINVAL; 369 370 errno = osif_net_dev_from_vdev(vdev, &net_dev); 371 372 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); 373 374 if (errno) 375 return errno; 376 377 *out_net_dev = net_dev; 378 379 return 0; 380 } 381 382 static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, 383 struct nlattr **tb) 384 { 385 struct device *dev; 386 struct net_device *net_dev; 387 struct osif_vdev_sync *vdev_sync; 388 char *ifname; 389 int errno; 390 391 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname); 392 if (errno) 393 return errno; 394 395 errno = osif_device_from_psoc(psoc, &dev); 396 if (errno) 397 return errno; 398 399 errno = osif_vdev_sync_create_and_trans(dev, &vdev_sync); 400 if (errno) 401 return errno; 402 403 errno = __os_if_nan_process_ndi_create(psoc, ifname, tb); 404 if (errno) 405 goto destroy_sync; 406 407 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev); 408 if (errno) 409 goto destroy_sync; 410 411 osif_vdev_sync_register(net_dev, vdev_sync); 412 osif_vdev_sync_trans_stop(vdev_sync); 413 414 return 0; 415 416 destroy_sync: 417 osif_vdev_sync_trans_stop(vdev_sync); 418 osif_vdev_sync_destroy(vdev_sync); 419 420 return errno; 421 } 422 423 static int __os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, 424 char *iface_name, 425 struct nlattr **tb) 426 { 427 uint8_t vdev_id; 428 QDF_STATUS status; 429 uint32_t num_peers; 430 uint16_t transaction_id; 431 struct nan_callbacks cb_obj; 432 struct wlan_objmgr_vdev *nan_vdev = NULL; 433 434 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { 435 osif_err("Transaction id is unavailable"); 436 return -EINVAL; 437 } 438 439 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); 440 if (!nan_vdev) { 441 osif_err("Nan datapath interface is not present"); 442 return -EINVAL; 443 } 444 445 transaction_id = 446 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); 447 vdev_id = wlan_vdev_get_id(nan_vdev); 448 num_peers = ucfg_nan_get_active_peers(nan_vdev); 449 /* 450 * os_if_get_ndi_vdev_by_ifname increments ref count 451 * decrement here since vdev returned by that api is not used any more 452 */ 453 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); 454 455 /* check if there are active peers on the adapter */ 456 if (num_peers) 457 osif_err("NDP peers active: %d, active NDPs may not be terminated", 458 num_peers); 459 460 status = ucfg_nan_get_callbacks(psoc, &cb_obj); 461 if (QDF_IS_STATUS_ERROR(status)) { 462 osif_err("Couldn't get ballback object"); 463 return -EINVAL; 464 } 465 466 return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id); 467 } 468 469 static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, 470 struct nlattr **tb) 471 { 472 struct net_device *net_dev; 473 struct osif_vdev_sync *vdev_sync; 474 char *ifname; 475 int errno; 476 477 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname); 478 if (errno) 479 return errno; 480 481 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev); 482 if (errno) 483 return errno; 484 485 errno = osif_vdev_sync_trans_start_wait(net_dev, &vdev_sync); 486 if (errno) 487 return errno; 488 489 osif_vdev_sync_unregister(net_dev); 490 osif_vdev_sync_wait_for_ops(vdev_sync); 491 492 errno = __os_if_nan_process_ndi_delete(psoc, ifname, tb); 493 if (errno) 494 goto reregister; 495 496 osif_vdev_sync_trans_stop(vdev_sync); 497 osif_vdev_sync_destroy(vdev_sync); 498 499 return 0; 500 501 reregister: 502 osif_vdev_sync_register(net_dev, vdev_sync); 503 osif_vdev_sync_trans_stop(vdev_sync); 504 505 return errno; 506 } 507 508 /** 509 * os_if_nan_parse_security_params() - parse vendor attributes for security 510 * params. 511 * @tb: parsed NL attribute list 512 * @ncs_sk_type: out parameter to populate ncs_sk_type 513 * @pmk: out parameter to populate pmk 514 * @passphrase: out parameter to populate passphrase 515 * @service_name: out parameter to populate service_name 516 * 517 * Return: 0 on success or error code on failure 518 */ 519 static int os_if_nan_parse_security_params(struct nlattr **tb, 520 uint32_t *ncs_sk_type, struct nan_datapath_pmk *pmk, 521 struct ndp_passphrase *passphrase, 522 struct ndp_service_name *service_name) 523 { 524 if (!ncs_sk_type || !pmk || !passphrase || !service_name) { 525 osif_err("out buffers for one ore more parameters is null"); 526 return -EINVAL; 527 } 528 529 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]) { 530 *ncs_sk_type = 531 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]); 532 } 533 534 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { 535 pmk->pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); 536 qdf_mem_copy(pmk->pmk, 537 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]), 538 pmk->pmk_len); 539 osif_err("pmk len: %d", pmk->pmk_len); 540 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, 541 pmk->pmk, pmk->pmk_len); 542 } 543 544 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]) { 545 passphrase->passphrase_len = 546 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]); 547 qdf_mem_copy(passphrase->passphrase, 548 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]), 549 passphrase->passphrase_len); 550 osif_err("passphrase len: %d", passphrase->passphrase_len); 551 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, 552 passphrase->passphrase, 553 passphrase->passphrase_len); 554 } 555 556 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) { 557 service_name->service_name_len = 558 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]); 559 qdf_mem_copy(service_name->service_name, 560 nla_data( 561 tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]), 562 service_name->service_name_len); 563 osif_err("service_name len: %d", 564 service_name->service_name_len); 565 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, 566 service_name->service_name, 567 service_name->service_name_len); 568 } 569 570 return 0; 571 } 572 573 /** 574 * __os_if_nan_process_ndp_initiator_req() - NDP initiator request handler 575 * @ctx: hdd context 576 * @tb: parsed NL attribute list 577 * 578 * tb will contain following vendor attributes: 579 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR 580 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID 581 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional 582 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG 583 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID 584 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR 585 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional 586 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional 587 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional 588 * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional 589 * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional 590 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional 591 * 592 * Return: 0 on success or error code on failure 593 */ 594 static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, 595 char *iface_name, 596 struct nlattr **tb) 597 { 598 int ret = 0; 599 QDF_STATUS status; 600 enum nan_datapath_state state; 601 struct wlan_objmgr_vdev *nan_vdev; 602 struct nan_datapath_initiator_req req = {0}; 603 604 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); 605 if (!nan_vdev) { 606 osif_err("NAN data interface %s not available", iface_name); 607 return -EINVAL; 608 } 609 610 if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { 611 osif_err("Interface found is not NDI"); 612 ret = -EINVAL; 613 goto initiator_req_failed; 614 } 615 616 state = ucfg_nan_get_ndi_state(nan_vdev); 617 if (state == NAN_DATA_NDI_DELETED_STATE || 618 state == NAN_DATA_NDI_DELETING_STATE || 619 state == NAN_DATA_NDI_CREATING_STATE) { 620 osif_err("Data request not allowed in NDI current state: %d", 621 state); 622 ret = -EINVAL; 623 goto initiator_req_failed; 624 } 625 626 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { 627 osif_err("Transaction ID is unavailable"); 628 ret = -EINVAL; 629 goto initiator_req_failed; 630 } 631 req.transaction_id = 632 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); 633 634 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) { 635 req.channel = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]); 636 637 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) { 638 req.channel_cfg = nla_get_u32( 639 tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]); 640 } else { 641 osif_err("Channel config is unavailable"); 642 ret = -EINVAL; 643 goto initiator_req_failed; 644 } 645 } 646 647 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) { 648 osif_err("NDP service instance ID is unavailable"); 649 ret = -EINVAL; 650 goto initiator_req_failed; 651 } 652 req.service_instance_id = 653 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]); 654 655 qdf_mem_copy(req.self_ndi_mac_addr.bytes, 656 wlan_vdev_mlme_get_macaddr(nan_vdev), QDF_MAC_ADDR_SIZE); 657 658 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) { 659 osif_err("NDI peer discovery mac addr is unavailable"); 660 ret = -EINVAL; 661 goto initiator_req_failed; 662 } 663 qdf_mem_copy(req.peer_discovery_mac_addr.bytes, 664 nla_data( 665 tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), 666 QDF_MAC_ADDR_SIZE); 667 668 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { 669 req.ndp_info.ndp_app_info_len = 670 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); 671 qdf_mem_copy(req.ndp_info.ndp_app_info, 672 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), 673 req.ndp_info.ndp_app_info_len); 674 } 675 676 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { 677 /* at present ndp config stores 4 bytes QOS info only */ 678 req.ndp_config.ndp_cfg_len = 4; 679 *((uint32_t *)req.ndp_config.ndp_cfg) = 680 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); 681 } 682 683 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) { 684 req.is_ipv6_addr_present = true; 685 qdf_mem_copy(req.ipv6_addr, 686 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]), 687 QDF_IPV6_ADDR_SIZE); 688 } 689 osif_debug("ipv6 addr present: %d, addr: %pI6", 690 req.is_ipv6_addr_present, req.ipv6_addr); 691 692 if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, 693 &req.passphrase, 694 &req.service_name)) { 695 osif_err("inconsistent security params in request."); 696 ret = -EINVAL; 697 goto initiator_req_failed; 698 } 699 700 osif_debug("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM", 701 wlan_vdev_get_id(nan_vdev), req.transaction_id, 702 req.channel, req.service_instance_id, 703 req.ndp_info.ndp_app_info_len, req.ncs_sk_type, 704 req.peer_discovery_mac_addr.bytes); 705 706 req.vdev = nan_vdev; 707 status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ); 708 ret = qdf_status_to_os_return(status); 709 initiator_req_failed: 710 if (ret) 711 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); 712 713 return ret; 714 } 715 716 static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, 717 struct nlattr **tb) 718 { 719 struct net_device *net_dev; 720 struct osif_vdev_sync *vdev_sync; 721 char *ifname; 722 int errno; 723 724 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname); 725 if (errno) 726 return errno; 727 728 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev); 729 if (errno) 730 return errno; 731 732 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 733 if (errno) 734 return errno; 735 736 errno = __os_if_nan_process_ndp_initiator_req(psoc, ifname, tb); 737 738 osif_vdev_sync_op_stop(vdev_sync); 739 740 return errno; 741 } 742 743 /** 744 * __os_if_nan_process_ndp_responder_req() - NDP responder request handler 745 * @nan_ctx: hdd context 746 * @tb: parsed NL attribute list 747 * 748 * tb includes following vendor attributes: 749 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR 750 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID 751 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID 752 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE 753 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional 754 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional 755 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional 756 * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional 757 * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional 758 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional 759 * 760 * Return: 0 on success or error code on failure 761 */ 762 static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, 763 char *iface_name, 764 struct nlattr **tb) 765 { 766 int ret = 0; 767 QDF_STATUS status; 768 enum nan_datapath_state state; 769 struct wlan_objmgr_vdev *nan_vdev = NULL; 770 struct nan_datapath_responder_req req = {0}; 771 772 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { 773 osif_err("ndp_rsp is unavailable"); 774 return -EINVAL; 775 } 776 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); 777 778 if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) { 779 /* Check for an existing NAN interface */ 780 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); 781 if (!nan_vdev) { 782 osif_err("NAN data iface %s not available", 783 iface_name); 784 return -ENODEV; 785 } 786 787 if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { 788 osif_err("Interface found is not NDI"); 789 ret = -ENODEV; 790 goto responder_req_failed; 791 } 792 } else { 793 /* 794 * If the data indication is rejected, the userspace 795 * may not send the iface name. Use the first NDI 796 * in that case 797 */ 798 osif_debug("ndp rsp rejected, using first NDI"); 799 800 nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 801 psoc, QDF_NDI_MODE, WLAN_NAN_ID); 802 if (!nan_vdev) { 803 osif_err("NAN data iface is not available"); 804 return -ENODEV; 805 } 806 } 807 808 state = ucfg_nan_get_ndi_state(nan_vdev); 809 if (state == NAN_DATA_NDI_DELETED_STATE || 810 state == NAN_DATA_NDI_DELETING_STATE || 811 state == NAN_DATA_NDI_CREATING_STATE) { 812 osif_err("Data request not allowed in current NDI state:%d", 813 state); 814 ret = -EAGAIN; 815 goto responder_req_failed; 816 } 817 818 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { 819 osif_err("Transaction ID is unavailable"); 820 ret = -EINVAL; 821 goto responder_req_failed; 822 } 823 req.transaction_id = 824 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); 825 826 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) { 827 osif_err("Instance ID is unavailable"); 828 ret = -EINVAL; 829 goto responder_req_failed; 830 } 831 req.ndp_instance_id = 832 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); 833 834 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { 835 req.ndp_info.ndp_app_info_len = 836 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); 837 qdf_mem_copy(req.ndp_info.ndp_app_info, 838 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), 839 req.ndp_info.ndp_app_info_len); 840 } else { 841 osif_debug("NDP app info is unavailable"); 842 } 843 844 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { 845 /* at present ndp config stores 4 bytes QOS info only */ 846 req.ndp_config.ndp_cfg_len = 4; 847 *((uint32_t *)req.ndp_config.ndp_cfg) = 848 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); 849 } else { 850 osif_debug("NDP config data is unavailable"); 851 } 852 853 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) { 854 req.is_ipv6_addr_present = true; 855 qdf_mem_copy(req.ipv6_addr, 856 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]), 857 QDF_IPV6_ADDR_SIZE); 858 } 859 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]) { 860 req.is_port_present = true; 861 req.port = nla_get_u16( 862 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]); 863 } 864 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]) { 865 req.is_protocol_present = true; 866 req.protocol = nla_get_u8( 867 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]); 868 } 869 osif_debug("ipv6 addr present: %d, addr: %pI6", 870 req.is_ipv6_addr_present, req.ipv6_addr); 871 osif_debug("port %d, present: %d", req.port, req.is_port_present); 872 osif_debug("protocol %d, present: %d", 873 req.protocol, req.is_protocol_present); 874 875 if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, 876 &req.passphrase, &req.service_name)) { 877 osif_err("inconsistent security params in request."); 878 ret = -EINVAL; 879 goto responder_req_failed; 880 } 881 882 osif_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d", 883 wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp, 884 req.ndp_instance_id, req.ndp_info.ndp_app_info_len, 885 req.ncs_sk_type); 886 887 req.vdev = nan_vdev; 888 status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ); 889 ret = qdf_status_to_os_return(status); 890 891 responder_req_failed: 892 if (ret) 893 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); 894 895 return ret; 896 897 } 898 899 static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, 900 struct nlattr **tb) 901 { 902 struct net_device *net_dev; 903 struct osif_vdev_sync *vdev_sync; 904 char *ifname; 905 int errno; 906 907 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname); 908 if (errno) 909 return errno; 910 911 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev); 912 if (errno) 913 return errno; 914 915 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 916 if (errno) 917 return errno; 918 919 errno = __os_if_nan_process_ndp_responder_req(psoc, ifname, tb); 920 921 osif_vdev_sync_op_stop(vdev_sync); 922 923 return errno; 924 } 925 926 /** 927 * __os_if_nan_process_ndp_end_req() - NDP end request handler 928 * @psoc: pointer to psoc object 929 * 930 * @tb: parsed NL attribute list 931 * tb includes following vendor attributes: 932 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID 933 * 934 * Return: 0 on success or error code on failure 935 */ 936 static int __os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, 937 struct nlattr **tb) 938 { 939 int ret = 0; 940 QDF_STATUS status; 941 struct wlan_objmgr_vdev *nan_vdev; 942 struct nan_datapath_end_req req = {0}; 943 944 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { 945 osif_err("Transaction ID is unavailable"); 946 return -EINVAL; 947 } 948 req.transaction_id = 949 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); 950 951 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { 952 osif_err("NDP instance ID array is unavailable"); 953 return -EINVAL; 954 } 955 956 req.num_ndp_instances = 957 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) / 958 sizeof(uint32_t); 959 if (0 >= req.num_ndp_instances) { 960 osif_err("Num NDP instances is 0"); 961 return -EINVAL; 962 } 963 qdf_mem_copy(req.ndp_ids, 964 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]), 965 req.num_ndp_instances * sizeof(uint32_t)); 966 967 osif_debug("sending ndp_end_req to SME, transaction_id: %d", 968 req.transaction_id); 969 970 nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE, 971 WLAN_NAN_ID); 972 if (!nan_vdev) { 973 osif_err("NAN data interface is not available"); 974 return -EINVAL; 975 } 976 977 req.vdev = nan_vdev; 978 status = ucfg_nan_req_processor(nan_vdev, &req, NDP_END_REQ); 979 ret = qdf_status_to_os_return(status); 980 if (ret) 981 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); 982 983 return ret; 984 } 985 986 static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, 987 struct nlattr **tb) 988 { 989 struct wlan_objmgr_vdev *vdev; 990 struct net_device *net_dev; 991 struct osif_vdev_sync *vdev_sync; 992 int errno; 993 994 vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE, 995 WLAN_NAN_ID); 996 if (!vdev) 997 return -EINVAL; 998 999 errno = osif_net_dev_from_vdev(vdev, &net_dev); 1000 1001 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); 1002 1003 if (errno) 1004 return errno; 1005 1006 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 1007 if (errno) 1008 return errno; 1009 1010 errno = __os_if_nan_process_ndp_end_req(psoc, tb); 1011 1012 osif_vdev_sync_op_stop(vdev_sync); 1013 1014 return errno; 1015 } 1016 1017 int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, 1018 const void *data, int data_len) 1019 { 1020 uint32_t ndp_cmd_type; 1021 uint16_t transaction_id; 1022 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1]; 1023 char *iface_name; 1024 1025 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, 1026 data, data_len, vendor_attr_policy)) { 1027 osif_err("Invalid NDP vendor command attributes"); 1028 return -EINVAL; 1029 } 1030 1031 /* Parse and fetch NDP Command Type*/ 1032 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) { 1033 osif_err("NAN datapath cmd type failed"); 1034 return -EINVAL; 1035 } 1036 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]); 1037 1038 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { 1039 osif_err("attr transaction id failed"); 1040 return -EINVAL; 1041 } 1042 transaction_id = nla_get_u16( 1043 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); 1044 1045 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { 1046 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); 1047 osif_err("Transaction Id: %d NDPCmd: %d iface_name: %s", 1048 transaction_id, ndp_cmd_type, iface_name); 1049 } else { 1050 osif_err("Transaction Id: %d NDPCmd: %d iface_name: unspecified", 1051 transaction_id, ndp_cmd_type); 1052 } 1053 1054 osif_debug("Received NDP cmd: %d", ndp_cmd_type); 1055 switch (ndp_cmd_type) { 1056 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: 1057 return os_if_nan_process_ndi_create(psoc, tb); 1058 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE: 1059 return os_if_nan_process_ndi_delete(psoc, tb); 1060 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST: 1061 return os_if_nan_process_ndp_initiator_req(psoc, tb); 1062 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST: 1063 return os_if_nan_process_ndp_responder_req(psoc, tb); 1064 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST: 1065 return os_if_nan_process_ndp_end_req(psoc, tb); 1066 default: 1067 osif_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); 1068 return -EINVAL; 1069 } 1070 1071 return -EINVAL; 1072 } 1073 1074 static inline uint32_t osif_ndp_get_ndp_initiator_rsp_len(void) 1075 { 1076 uint32_t data_len = NLMSG_HDRLEN; 1077 1078 data_len += nla_total_size(vendor_attr_policy[ 1079 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1080 data_len += nla_total_size(vendor_attr_policy[ 1081 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); 1082 data_len += nla_total_size(vendor_attr_policy[ 1083 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len); 1084 data_len += nla_total_size(vendor_attr_policy[ 1085 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); 1086 data_len += nla_total_size(vendor_attr_policy[ 1087 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); 1088 1089 return data_len; 1090 } 1091 1092 /** 1093 * os_if_ndp_initiator_rsp_handler() - NDP initiator response handler 1094 * @vdev: pointer to vdev object 1095 * @rsp_params: response parameters 1096 * 1097 * Following vendor event is sent to cfg80211: 1098 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1099 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes) 1100 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) 1101 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) 1102 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) 1103 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) 1104 * 1105 * Return: none 1106 */ 1107 static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev, 1108 struct nan_datapath_initiator_rsp *rsp) 1109 { 1110 uint32_t data_len; 1111 struct sk_buff *vendor_event; 1112 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1113 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1114 1115 if (!rsp) { 1116 osif_err("Invalid NDP Initator response"); 1117 return; 1118 } 1119 1120 data_len = osif_ndp_get_ndp_initiator_rsp_len(); 1121 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 1122 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1123 GFP_ATOMIC); 1124 if (!vendor_event) { 1125 osif_err("cfg80211_vendor_event_alloc failed"); 1126 return; 1127 } 1128 1129 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1130 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE)) 1131 goto ndp_initiator_rsp_nla_failed; 1132 1133 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 1134 rsp->transaction_id)) 1135 goto ndp_initiator_rsp_nla_failed; 1136 1137 if (nla_put_u32(vendor_event, 1138 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, 1139 rsp->ndp_instance_id)) 1140 goto ndp_initiator_rsp_nla_failed; 1141 1142 if (nla_put_u32(vendor_event, 1143 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 1144 rsp->status)) 1145 goto ndp_initiator_rsp_nla_failed; 1146 1147 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 1148 rsp->reason)) 1149 goto ndp_initiator_rsp_nla_failed; 1150 1151 osif_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d", 1152 rsp->transaction_id, rsp->ndp_instance_id, rsp->status, 1153 rsp->reason); 1154 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 1155 return; 1156 ndp_initiator_rsp_nla_failed: 1157 osif_err("nla_put api failed"); 1158 kfree_skb(vendor_event); 1159 } 1160 1161 static inline uint32_t osif_ndp_get_ndp_responder_rsp_len(void) 1162 { 1163 uint32_t data_len = NLMSG_HDRLEN; 1164 1165 data_len += nla_total_size(vendor_attr_policy[ 1166 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1167 data_len += nla_total_size(vendor_attr_policy[ 1168 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); 1169 data_len += nla_total_size(vendor_attr_policy[ 1170 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); 1171 data_len += nla_total_size(vendor_attr_policy[ 1172 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); 1173 1174 return data_len; 1175 } 1176 1177 /* 1178 * os_if_ndp_responder_rsp_handler() - NDP responder response handler 1179 * @vdev: pointer to vdev object 1180 * @rsp: response parameters 1181 * 1182 * Following vendor event is sent to cfg80211: 1183 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1184 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes) 1185 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) 1186 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) 1187 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) 1188 * 1189 * Return: none 1190 */ 1191 static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev, 1192 struct nan_datapath_responder_rsp *rsp) 1193 { 1194 uint16_t data_len; 1195 struct sk_buff *vendor_event; 1196 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1197 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1198 1199 if (!rsp) { 1200 osif_err("Invalid NDP Responder response"); 1201 return; 1202 } 1203 1204 osif_debug("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d", 1205 wlan_vdev_get_id(rsp->vdev), rsp->transaction_id, 1206 rsp->status, rsp->reason); 1207 data_len = osif_ndp_get_ndp_responder_rsp_len(); 1208 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 1209 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1210 GFP_ATOMIC); 1211 if (!vendor_event) { 1212 osif_err("cfg80211_vendor_event_alloc failed"); 1213 return; 1214 } 1215 1216 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1217 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE)) 1218 goto ndp_responder_rsp_nla_failed; 1219 1220 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 1221 rsp->transaction_id)) 1222 goto ndp_responder_rsp_nla_failed; 1223 1224 if (nla_put_u32(vendor_event, 1225 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 1226 rsp->status)) 1227 goto ndp_responder_rsp_nla_failed; 1228 1229 if (nla_put_u32(vendor_event, 1230 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 1231 rsp->reason)) 1232 goto ndp_responder_rsp_nla_failed; 1233 1234 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 1235 return; 1236 ndp_responder_rsp_nla_failed: 1237 osif_err("nla_put api failed"); 1238 kfree_skb(vendor_event); 1239 } 1240 1241 static inline uint32_t osif_ndp_get_ndp_req_ind_len( 1242 struct nan_datapath_indication_event *event) 1243 { 1244 uint32_t data_len = NLMSG_HDRLEN; 1245 1246 data_len += nla_total_size(vendor_attr_policy[ 1247 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1248 data_len += nla_total_size(vendor_attr_policy[ 1249 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID].len); 1250 data_len += nla_total_size(vendor_attr_policy[ 1251 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len); 1252 data_len += nla_total_size(vendor_attr_policy[ 1253 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS].len); 1254 data_len += nla_total_size(vendor_attr_policy[ 1255 QCA_WLAN_VENDOR_ATTR_NDP_CSID].len); 1256 /* allocate space including NULL terminator */ 1257 data_len += nla_total_size(vendor_attr_policy[ 1258 QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1); 1259 data_len += nla_total_size(vendor_attr_policy[ 1260 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len); 1261 data_len += nla_total_size(vendor_attr_policy[ 1262 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len); 1263 if (event->is_ipv6_addr_present) 1264 data_len += nla_total_size(vendor_attr_policy[ 1265 QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len); 1266 if (event->scid.scid_len) 1267 data_len += nla_total_size(event->scid.scid_len); 1268 if (event->ndp_info.ndp_app_info_len) 1269 data_len += nla_total_size(event->ndp_info.ndp_app_info_len); 1270 1271 return data_len; 1272 } 1273 1274 /** 1275 * os_if_ndp_indication_handler() - NDP indication handler 1276 * @vdev: pointer to vdev object 1277 * @ind_params: indication parameters 1278 * 1279 * Following vendor event is sent to cfg80211: 1280 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1281 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes) 1282 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ) 1283 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes) 1284 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes) 1285 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes) 1286 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) 1287 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) 1288 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes) 1289 * QCA_WLAN_VENDOR_ATTR_NDP_CSID(4 bytes) 1290 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size) 1291 * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes) 1292 * 1293 * Return: none 1294 */ 1295 static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, 1296 struct nan_datapath_indication_event *event) 1297 { 1298 const uint8_t *ifname; 1299 uint16_t data_len; 1300 qdf_size_t ifname_len; 1301 uint32_t ndp_qos_config; 1302 struct sk_buff *vendor_event; 1303 enum nan_datapath_state state; 1304 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1305 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1306 1307 if (!event) { 1308 osif_err("Invalid NDP Indication"); 1309 return; 1310 } 1311 1312 osif_debug("NDP Indication, policy: %d", event->policy); 1313 state = ucfg_nan_get_ndi_state(vdev); 1314 /* check if we are in middle of deleting/creating the interface */ 1315 1316 if (state == NAN_DATA_NDI_DELETED_STATE || 1317 state == NAN_DATA_NDI_DELETING_STATE || 1318 state == NAN_DATA_NDI_CREATING_STATE) { 1319 osif_err("Data request not allowed in current NDI state: %d", 1320 state); 1321 return; 1322 } 1323 1324 ifname = os_if_ndi_get_if_name(vdev); 1325 if (!ifname) { 1326 osif_err("ifname is null"); 1327 return; 1328 } 1329 ifname_len = qdf_str_len(ifname); 1330 if (ifname_len > IFNAMSIZ) { 1331 osif_err("ifname(%zu) too long", ifname_len); 1332 return; 1333 } 1334 1335 data_len = osif_ndp_get_ndp_req_ind_len(event); 1336 /* notify response to the upper layer */ 1337 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, 1338 NULL, data_len, 1339 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1340 GFP_ATOMIC); 1341 if (!vendor_event) { 1342 osif_err("cfg80211_vendor_event_alloc failed"); 1343 return; 1344 } 1345 1346 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1347 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND)) 1348 goto ndp_indication_nla_failed; 1349 1350 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, 1351 ifname_len, ifname)) 1352 goto ndp_indication_nla_failed; 1353 1354 if (nla_put_u32(vendor_event, 1355 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, 1356 event->service_instance_id)) 1357 goto ndp_indication_nla_failed; 1358 1359 if (nla_put(vendor_event, 1360 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, 1361 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes)) 1362 goto ndp_indication_nla_failed; 1363 1364 if (nla_put(vendor_event, 1365 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, 1366 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes)) 1367 goto ndp_indication_nla_failed; 1368 1369 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, 1370 event->ndp_instance_id)) 1371 goto ndp_indication_nla_failed; 1372 1373 if (event->ndp_info.ndp_app_info_len) 1374 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, 1375 event->ndp_info.ndp_app_info_len, 1376 event->ndp_info.ndp_app_info)) 1377 goto ndp_indication_nla_failed; 1378 1379 if (event->ndp_config.ndp_cfg_len) { 1380 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg); 1381 /* at present ndp config stores 4 bytes QOS info only */ 1382 if (nla_put_u32(vendor_event, 1383 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, 1384 ndp_qos_config)) 1385 goto ndp_indication_nla_failed; 1386 } 1387 1388 if (event->scid.scid_len) { 1389 if (nla_put_u32(vendor_event, 1390 QCA_WLAN_VENDOR_ATTR_NDP_CSID, 1391 event->ncs_sk_type)) 1392 goto ndp_indication_nla_failed; 1393 1394 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID, 1395 event->scid.scid_len, 1396 event->scid.scid)) 1397 goto ndp_indication_nla_failed; 1398 1399 osif_debug("csid: %d, scid_len: %d", 1400 event->ncs_sk_type, event->scid.scid_len); 1401 1402 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, 1403 event->scid.scid, event->scid.scid_len); 1404 } 1405 1406 if (event->is_ipv6_addr_present) { 1407 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR, 1408 QDF_IPV6_ADDR_SIZE, event->ipv6_addr)) 1409 goto ndp_indication_nla_failed; 1410 } 1411 osif_debug("ipv6 addr present: %d, addr: %pI6", 1412 event->is_ipv6_addr_present, event->ipv6_addr); 1413 1414 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 1415 return; 1416 ndp_indication_nla_failed: 1417 osif_err("nla_put api failed"); 1418 kfree_skb(vendor_event); 1419 } 1420 1421 static inline uint32_t osif_ndp_get_ndp_confirm_ind_len( 1422 struct nan_datapath_confirm_event *ndp_confirm) 1423 { 1424 uint32_t ch_info_len = 0; 1425 uint32_t data_len = NLMSG_HDRLEN; 1426 1427 data_len += nla_total_size(vendor_attr_policy[ 1428 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1429 data_len += nla_total_size(vendor_attr_policy[ 1430 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len); 1431 data_len += nla_total_size(vendor_attr_policy[ 1432 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len); 1433 /* allocate space including NULL terminator */ 1434 data_len += nla_total_size(vendor_attr_policy[ 1435 QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1); 1436 data_len += nla_total_size(vendor_attr_policy[ 1437 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE].len); 1438 data_len += nla_total_size(vendor_attr_policy[ 1439 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); 1440 if (ndp_confirm->ndp_info.ndp_app_info_len) 1441 data_len += 1442 nla_total_size(ndp_confirm->ndp_info.ndp_app_info_len); 1443 1444 if (ndp_confirm->is_ipv6_addr_present) 1445 data_len += nla_total_size(vendor_attr_policy[ 1446 QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len); 1447 if (ndp_confirm->is_port_present) 1448 data_len += nla_total_size(vendor_attr_policy[ 1449 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT].len); 1450 if (ndp_confirm->is_protocol_present) 1451 data_len += nla_total_size(vendor_attr_policy[ 1452 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL].len); 1453 1454 /* ch_info is a nested array of following attributes */ 1455 ch_info_len += nla_total_size( 1456 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len); 1457 ch_info_len += nla_total_size( 1458 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len); 1459 ch_info_len += nla_total_size( 1460 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len); 1461 1462 if (ndp_confirm->num_channels) 1463 data_len += ndp_confirm->num_channels * 1464 nla_total_size(ch_info_len); 1465 1466 return data_len; 1467 } 1468 1469 static QDF_STATUS os_if_ndp_confirm_pack_ch_info(struct sk_buff *event, 1470 struct nan_datapath_confirm_event *ndp_confirm) 1471 { 1472 int idx = 0; 1473 struct nlattr *ch_array, *ch_element; 1474 1475 osif_debug("num_ch: %d", ndp_confirm->num_channels); 1476 if (!ndp_confirm->num_channels) 1477 return QDF_STATUS_SUCCESS; 1478 1479 ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO); 1480 if (!ch_array) 1481 return QDF_STATUS_E_FAULT; 1482 1483 for (idx = 0; idx < ndp_confirm->num_channels; idx++) { 1484 osif_debug("Freq[%d]: freq: %d, width: %d, nss: %d", 1485 idx, ndp_confirm->ch[idx].freq, 1486 ndp_confirm->ch[idx].ch_width, 1487 ndp_confirm->ch[idx].nss); 1488 ch_element = nla_nest_start(event, idx); 1489 if (!ch_element) 1490 return QDF_STATUS_E_FAULT; 1491 1492 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, 1493 ndp_confirm->ch[idx].freq)) 1494 return QDF_STATUS_E_FAULT; 1495 1496 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH, 1497 ndp_confirm->ch[idx].ch_width)) 1498 return QDF_STATUS_E_FAULT; 1499 1500 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS, 1501 ndp_confirm->ch[idx].nss)) 1502 return QDF_STATUS_E_FAULT; 1503 nla_nest_end(event, ch_element); 1504 } 1505 nla_nest_end(event, ch_array); 1506 1507 return QDF_STATUS_SUCCESS; 1508 } 1509 1510 /** 1511 * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler 1512 * @vdev: pointer to vdev object 1513 * @ind_params: indication parameters 1514 * 1515 * Following vendor event is sent to cfg80211: 1516 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1517 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes) 1518 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) 1519 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes) 1520 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ) 1521 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) 1522 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes) 1523 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) 1524 * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes) 1525 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT (2 bytes) 1526 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL (1 byte) 1527 * 1528 * Return: none 1529 */ 1530 static void 1531 os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, 1532 struct nan_datapath_confirm_event *ndp_confirm) 1533 { 1534 const uint8_t *ifname; 1535 uint32_t data_len; 1536 QDF_STATUS status; 1537 qdf_size_t ifname_len; 1538 struct sk_buff *vendor_event; 1539 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1540 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1541 1542 if (!ndp_confirm) { 1543 osif_err("Invalid NDP Initator response"); 1544 return; 1545 } 1546 1547 ifname = os_if_ndi_get_if_name(vdev); 1548 if (!ifname) { 1549 osif_err("ifname is null"); 1550 return; 1551 } 1552 ifname_len = qdf_str_len(ifname); 1553 if (ifname_len > IFNAMSIZ) { 1554 osif_err("ifname(%zu) too long", ifname_len); 1555 return; 1556 } 1557 1558 data_len = osif_ndp_get_ndp_confirm_ind_len(ndp_confirm); 1559 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 1560 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1561 GFP_ATOMIC); 1562 if (!vendor_event) { 1563 osif_err("cfg80211_vendor_event_alloc failed"); 1564 return; 1565 } 1566 1567 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1568 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND)) 1569 goto ndp_confirm_nla_failed; 1570 1571 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, 1572 ndp_confirm->ndp_instance_id)) 1573 goto ndp_confirm_nla_failed; 1574 1575 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, 1576 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes)) 1577 goto ndp_confirm_nla_failed; 1578 1579 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, 1580 ifname_len, ifname)) 1581 goto ndp_confirm_nla_failed; 1582 1583 if (ndp_confirm->ndp_info.ndp_app_info_len && 1584 nla_put(vendor_event, 1585 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, 1586 ndp_confirm->ndp_info.ndp_app_info_len, 1587 ndp_confirm->ndp_info.ndp_app_info)) 1588 goto ndp_confirm_nla_failed; 1589 1590 if (nla_put_u32(vendor_event, 1591 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, 1592 ndp_confirm->rsp_code)) 1593 goto ndp_confirm_nla_failed; 1594 1595 if (nla_put_u32(vendor_event, 1596 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 1597 ndp_confirm->reason_code)) 1598 goto ndp_confirm_nla_failed; 1599 1600 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS, 1601 ndp_confirm->num_channels)) 1602 goto ndp_confirm_nla_failed; 1603 1604 status = os_if_ndp_confirm_pack_ch_info(vendor_event, ndp_confirm); 1605 if (QDF_IS_STATUS_ERROR(status)) 1606 goto ndp_confirm_nla_failed; 1607 1608 if (ndp_confirm->is_ipv6_addr_present) { 1609 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR, 1610 QDF_IPV6_ADDR_SIZE, ndp_confirm->ipv6_addr)) 1611 goto ndp_confirm_nla_failed; 1612 } 1613 if (ndp_confirm->is_port_present) 1614 if (nla_put_u16(vendor_event, 1615 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT, 1616 ndp_confirm->port)) 1617 goto ndp_confirm_nla_failed; 1618 if (ndp_confirm->is_protocol_present) 1619 if (nla_put_u8(vendor_event, 1620 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL, 1621 ndp_confirm->protocol)) 1622 goto ndp_confirm_nla_failed; 1623 osif_debug("ipv6 addr present: %d, addr: %pI6", 1624 ndp_confirm->is_ipv6_addr_present, 1625 ndp_confirm->ipv6_addr); 1626 osif_debug("port %d, present: %d", 1627 ndp_confirm->port, ndp_confirm->is_port_present); 1628 osif_debug("protocol %d, present: %d", 1629 ndp_confirm->protocol, ndp_confirm->is_protocol_present); 1630 1631 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 1632 osif_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM rsp_code: %d, reason_code: %d", 1633 ndp_confirm->ndp_instance_id, 1634 ndp_confirm->peer_ndi_mac_addr.bytes, 1635 ndp_confirm->rsp_code, ndp_confirm->reason_code); 1636 1637 osif_debug("NDP confim, ndp app info dump"); 1638 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, 1639 ndp_confirm->ndp_info.ndp_app_info, 1640 ndp_confirm->ndp_info.ndp_app_info_len); 1641 return; 1642 ndp_confirm_nla_failed: 1643 osif_err("nla_put api failed"); 1644 kfree_skb(vendor_event); 1645 } 1646 1647 static inline uint32_t osif_ndp_get_ndp_end_rsp_len(void) 1648 { 1649 uint32_t data_len = NLMSG_HDRLEN; 1650 1651 data_len += nla_total_size(vendor_attr_policy[ 1652 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1653 data_len += nla_total_size(vendor_attr_policy[ 1654 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); 1655 data_len += nla_total_size(vendor_attr_policy[ 1656 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); 1657 data_len += nla_total_size(vendor_attr_policy[ 1658 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); 1659 1660 return data_len; 1661 } 1662 1663 /** 1664 * os_if_ndp_end_rsp_handler() - NDP end response handler 1665 * @vdev: pointer to vdev object 1666 * @rsp_params: response parameters 1667 * 1668 * Following vendor event is sent to cfg80211: 1669 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1670 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest) 1671 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) 1672 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) 1673 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) 1674 * 1675 * Return: none 1676 */ 1677 static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev, 1678 struct nan_datapath_end_rsp_event *rsp) 1679 { 1680 uint32_t data_len; 1681 struct sk_buff *vendor_event; 1682 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1683 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1684 1685 if (!rsp) { 1686 osif_err("Invalid ndp end response"); 1687 return; 1688 } 1689 1690 data_len = osif_ndp_get_ndp_end_rsp_len(); 1691 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 1692 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1693 GFP_ATOMIC); 1694 if (!vendor_event) { 1695 osif_err("cfg80211_vendor_event_alloc failed"); 1696 return; 1697 } 1698 1699 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1700 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE)) 1701 goto ndp_end_rsp_nla_failed; 1702 1703 if (nla_put_u32(vendor_event, 1704 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 1705 rsp->status)) 1706 goto ndp_end_rsp_nla_failed; 1707 1708 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 1709 rsp->reason)) 1710 goto ndp_end_rsp_nla_failed; 1711 1712 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 1713 rsp->transaction_id)) 1714 goto ndp_end_rsp_nla_failed; 1715 1716 osif_debug("NDP End rsp sent, transaction id: %d, status: %d, reason: %d", 1717 rsp->transaction_id, rsp->status, rsp->reason); 1718 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 1719 return; 1720 1721 ndp_end_rsp_nla_failed: 1722 osif_err("nla_put api failed"); 1723 kfree_skb(vendor_event); 1724 } 1725 1726 static inline uint32_t osif_ndp_get_ndp_end_ind_len( 1727 struct nan_datapath_end_indication_event *end_ind) 1728 { 1729 uint32_t data_len = NLMSG_HDRLEN; 1730 1731 data_len += nla_total_size(vendor_attr_policy[ 1732 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1733 if (end_ind->num_ndp_ids) 1734 data_len += nla_total_size(end_ind->num_ndp_ids * 1735 sizeof(uint32_t)); 1736 1737 return data_len; 1738 } 1739 1740 /** 1741 * os_if_ndp_end_ind_handler() - NDP end indication handler 1742 * @vdev: pointer to vdev object 1743 * @ind_params: indication parameters 1744 * 1745 * Following vendor event is sent to cfg80211: 1746 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1747 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes) 1748 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances) 1749 * 1750 * Return: none 1751 */ 1752 static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, 1753 struct nan_datapath_end_indication_event *end_ind) 1754 { 1755 uint32_t data_len, i; 1756 uint32_t *ndp_instance_array; 1757 struct sk_buff *vendor_event; 1758 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1759 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1760 1761 if (!end_ind) { 1762 osif_err("Invalid ndp end indication"); 1763 return; 1764 } 1765 1766 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids * 1767 sizeof(*ndp_instance_array)); 1768 if (!ndp_instance_array) { 1769 osif_err("Failed to allocate ndp_instance_array"); 1770 return; 1771 } 1772 for (i = 0; i < end_ind->num_ndp_ids; i++) 1773 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id; 1774 1775 data_len = osif_ndp_get_ndp_end_ind_len(end_ind); 1776 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 1777 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1778 GFP_ATOMIC); 1779 if (!vendor_event) { 1780 osif_err("cfg80211_vendor_event_alloc failed"); 1781 return; 1782 } 1783 1784 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1785 QCA_WLAN_VENDOR_ATTR_NDP_END_IND)) 1786 goto ndp_end_ind_nla_failed; 1787 1788 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, 1789 end_ind->num_ndp_ids * sizeof(*ndp_instance_array), 1790 ndp_instance_array)) 1791 goto ndp_end_ind_nla_failed; 1792 1793 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 1794 qdf_mem_free(ndp_instance_array); 1795 return; 1796 1797 ndp_end_ind_nla_failed: 1798 osif_err("nla_put api failed"); 1799 kfree_skb(vendor_event); 1800 qdf_mem_free(ndp_instance_array); 1801 } 1802 1803 /** 1804 * os_if_new_peer_ind_handler() - NDP new peer indication handler 1805 * @adapter: pointer to adapter context 1806 * @ind_params: indication parameters 1807 * 1808 * Return: none 1809 */ 1810 static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev, 1811 struct nan_datapath_peer_ind *peer_ind) 1812 { 1813 int ret; 1814 QDF_STATUS status; 1815 uint8_t vdev_id = wlan_vdev_get_id(vdev); 1816 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 1817 uint32_t active_peers = ucfg_nan_get_active_peers(vdev); 1818 struct nan_callbacks cb_obj; 1819 1820 if (!peer_ind) { 1821 osif_err("Invalid new NDP peer params"); 1822 return; 1823 } 1824 1825 status = ucfg_nan_get_callbacks(psoc, &cb_obj); 1826 if (QDF_IS_STATUS_ERROR(status)) { 1827 osif_err("failed to get callbacks"); 1828 return; 1829 } 1830 1831 osif_debug("vdev_id: %d, peer_mac: %pM, sta_id: %d", 1832 vdev_id, peer_ind->peer_mac_addr.bytes, 1833 peer_ind->sta_id); 1834 ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id, 1835 &peer_ind->peer_mac_addr, 1836 (active_peers == 0 ? true : false)); 1837 if (ret) { 1838 osif_err("new peer handling at HDD failed %d", ret); 1839 return; 1840 } 1841 1842 active_peers++; 1843 ucfg_nan_set_active_peers(vdev, active_peers); 1844 osif_debug("vdev_id: %d, num_peers: %d", vdev_id, active_peers); 1845 } 1846 1847 /** 1848 * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication 1849 * @adapter: pointer to adapter context 1850 * @ind_params: indication parameters 1851 * 1852 * Return: none 1853 */ 1854 static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev, 1855 struct nan_datapath_peer_ind *peer_ind) 1856 { 1857 QDF_STATUS status; 1858 struct nan_callbacks cb_obj; 1859 uint8_t vdev_id = wlan_vdev_get_id(vdev); 1860 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 1861 uint32_t active_peers = ucfg_nan_get_active_peers(vdev); 1862 1863 status = ucfg_nan_get_callbacks(psoc, &cb_obj); 1864 if (QDF_IS_STATUS_ERROR(status)) { 1865 osif_err("failed to get callbacks"); 1866 return; 1867 } 1868 1869 if (!peer_ind) { 1870 osif_err("Invalid new NDP peer params"); 1871 return; 1872 } 1873 osif_debug("vdev_id: %d, peer_mac: %pM, sta_id: %d", 1874 vdev_id, peer_ind->peer_mac_addr.bytes, 1875 peer_ind->sta_id); 1876 active_peers--; 1877 ucfg_nan_set_active_peers(vdev, active_peers); 1878 cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id, 1879 &peer_ind->peer_mac_addr, 1880 (active_peers == 0 ? true : false)); 1881 } 1882 1883 static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void) 1884 { 1885 uint32_t data_len = NLMSG_HDRLEN; 1886 1887 data_len += nla_total_size(vendor_attr_policy[ 1888 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 1889 data_len += nla_total_size(vendor_attr_policy[ 1890 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); 1891 data_len += nla_total_size(vendor_attr_policy[ 1892 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); 1893 data_len += nla_total_size(vendor_attr_policy[ 1894 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); 1895 1896 return data_len; 1897 } 1898 1899 /** 1900 * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler 1901 * @adapter: pointer to adapter context 1902 * @rsp_params: response parameters 1903 * 1904 * The function is expected to send a response back to the user space 1905 * even if the creation of BSS has failed 1906 * 1907 * Following vendor event is sent to cfg80211: 1908 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = 1909 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes) 1910 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) 1911 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) 1912 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE 1913 * 1914 * Return: none 1915 */ 1916 static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, 1917 struct wlan_objmgr_vdev *vdev, 1918 void *rsp_params) 1919 { 1920 uint32_t data_len; 1921 QDF_STATUS status; 1922 bool create_fail = false; 1923 struct nan_callbacks cb_obj; 1924 struct sk_buff *vendor_event; 1925 uint16_t create_transaction_id; 1926 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1927 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 1928 uint32_t create_status = NAN_DATAPATH_RSP_STATUS_ERROR; 1929 uint32_t create_reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED; 1930 struct nan_datapath_inf_create_rsp *ndi_rsp = 1931 (struct nan_datapath_inf_create_rsp *)rsp_params; 1932 1933 status = ucfg_nan_get_callbacks(psoc, &cb_obj); 1934 if (QDF_IS_STATUS_ERROR(status)) { 1935 osif_err("Couldn't get ballback object"); 1936 return; 1937 } 1938 1939 if (ndi_rsp) { 1940 create_status = ndi_rsp->status; 1941 create_reason = ndi_rsp->reason; 1942 } else { 1943 osif_err("Invalid ndi create response"); 1944 create_fail = true; 1945 } 1946 1947 create_transaction_id = ucfg_nan_get_ndp_create_transaction_id(vdev); 1948 data_len = osif_ndp_get_ndi_create_rsp_len(); 1949 /* notify response to the upper layer */ 1950 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, 1951 NULL, 1952 data_len, 1953 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 1954 GFP_KERNEL); 1955 if (!vendor_event) { 1956 osif_err("cfg80211_vendor_event_alloc failed"); 1957 create_fail = true; 1958 goto close_ndi; 1959 } 1960 1961 /* Sub vendor command */ 1962 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 1963 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) { 1964 osif_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"); 1965 goto nla_put_failure; 1966 } 1967 1968 /* Transaction id */ 1969 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 1970 create_transaction_id)) { 1971 osif_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); 1972 goto nla_put_failure; 1973 } 1974 1975 /* Status code */ 1976 if (nla_put_u32(vendor_event, 1977 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 1978 create_status)) { 1979 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"); 1980 goto nla_put_failure; 1981 } 1982 1983 /* Status return value */ 1984 if (nla_put_u32(vendor_event, 1985 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 1986 create_reason)) { 1987 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); 1988 goto nla_put_failure; 1989 } 1990 1991 osif_debug("sub command: %d, value: %d", 1992 QCA_NL80211_VENDOR_SUBCMD_NDP, 1993 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE); 1994 osif_debug("create transaction id: %d, value: %d", 1995 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 1996 create_transaction_id); 1997 osif_debug("status code: %d, value: %d", 1998 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 1999 create_status); 2000 osif_debug("Return value: %d, value: %d", 2001 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 2002 create_reason); 2003 2004 cfg80211_vendor_event(vendor_event, GFP_KERNEL); 2005 2006 if (!create_fail) { 2007 /* update txrx queues and register self sta */ 2008 cb_obj.drv_ndi_create_rsp_handler(wlan_vdev_get_id(vdev), 2009 ndi_rsp); 2010 } else { 2011 osif_err("NDI interface creation failed with reason %d", 2012 create_reason); 2013 goto close_ndi; 2014 } 2015 2016 return; 2017 2018 nla_put_failure: 2019 kfree_skb(vendor_event); 2020 close_ndi: 2021 cb_obj.ndi_close(wlan_vdev_get_id(vdev)); 2022 return; 2023 } 2024 2025 /** 2026 * os_if_ndp_iface_delete_rsp_handler() - NDP iface delete response handler 2027 * @adapter: pointer to adapter context 2028 * @rsp_params: response parameters 2029 * 2030 * Return: none 2031 */ 2032 static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc, 2033 struct wlan_objmgr_vdev *vdev, 2034 void *rsp_params) 2035 { 2036 QDF_STATUS status; 2037 uint8_t vdev_id = wlan_vdev_get_id(vdev); 2038 struct nan_datapath_inf_delete_rsp *ndi_rsp = rsp_params; 2039 struct nan_callbacks cb_obj; 2040 2041 if (!ndi_rsp) { 2042 osif_err("Invalid ndi delete response"); 2043 return; 2044 } 2045 2046 status = ucfg_nan_get_callbacks(psoc, &cb_obj); 2047 if (QDF_IS_STATUS_ERROR(status)) { 2048 osif_err("Couldn't get ballback object"); 2049 return; 2050 } 2051 2052 if (ndi_rsp->status == NAN_DATAPATH_RSP_STATUS_SUCCESS) 2053 osif_debug("NDI BSS successfully stopped"); 2054 else 2055 osif_debug("NDI BSS stop failed with reason %d", 2056 ndi_rsp->reason); 2057 2058 ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason); 2059 ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status); 2060 cb_obj.drv_ndi_delete_rsp_handler(vdev_id); 2061 } 2062 2063 static inline uint32_t osif_ndp_get_ndp_sch_update_ind_len( 2064 struct nan_datapath_sch_update_event *sch_update) 2065 { 2066 uint32_t ch_info_len = 0; 2067 uint32_t data_len = NLMSG_HDRLEN; 2068 2069 data_len += nla_total_size(vendor_attr_policy[ 2070 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 2071 data_len += nla_total_size(vendor_attr_policy[ 2072 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len); 2073 if (sch_update->num_ndp_instances) 2074 data_len += nla_total_size(sch_update->num_ndp_instances * 2075 sizeof(uint32_t)); 2076 data_len += nla_total_size(vendor_attr_policy[ 2077 QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON].len); 2078 data_len += nla_total_size(vendor_attr_policy[ 2079 QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS].len); 2080 /* ch_info is a nested array of following attributes */ 2081 ch_info_len += nla_total_size( 2082 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len); 2083 ch_info_len += nla_total_size( 2084 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len); 2085 ch_info_len += nla_total_size( 2086 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len); 2087 2088 if (sch_update->num_ndp_instances) 2089 data_len += sch_update->num_ndp_instances * 2090 nla_total_size(ch_info_len); 2091 2092 return data_len; 2093 } 2094 2095 static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event, 2096 struct nan_datapath_sch_update_event *sch_update) 2097 { 2098 int idx = 0; 2099 struct nlattr *ch_array, *ch_element; 2100 2101 osif_debug("num_ch: %d", sch_update->num_channels); 2102 if (!sch_update->num_channels) 2103 return QDF_STATUS_SUCCESS; 2104 2105 ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO); 2106 if (!ch_array) 2107 return QDF_STATUS_E_FAULT; 2108 2109 for (idx = 0; idx < sch_update->num_channels; idx++) { 2110 osif_debug("ch[%d]: freq: %d, width: %d, nss: %d", 2111 idx, sch_update->ch[idx].freq, 2112 sch_update->ch[idx].ch_width, 2113 sch_update->ch[idx].nss); 2114 ch_element = nla_nest_start(event, idx); 2115 if (!ch_element) 2116 return QDF_STATUS_E_FAULT; 2117 2118 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, 2119 sch_update->ch[idx].freq)) 2120 return QDF_STATUS_E_FAULT; 2121 2122 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH, 2123 sch_update->ch[idx].ch_width)) 2124 return QDF_STATUS_E_FAULT; 2125 2126 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS, 2127 sch_update->ch[idx].nss)) 2128 return QDF_STATUS_E_FAULT; 2129 nla_nest_end(event, ch_element); 2130 } 2131 nla_nest_end(event, ch_array); 2132 2133 return QDF_STATUS_SUCCESS; 2134 } 2135 2136 /** 2137 * os_if_ndp_sch_update_ind_handler() - NDP schedule update handler 2138 * @vdev: vdev object pointer 2139 * @ind: sch update pointer 2140 * 2141 * Following vendor event is sent to cfg80211: 2142 * 2143 * Return: none 2144 */ 2145 static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev, 2146 void *ind) 2147 { 2148 int idx = 0; 2149 const uint8_t *ifname; 2150 QDF_STATUS status; 2151 uint32_t data_len; 2152 uint8_t ifname_len; 2153 struct sk_buff *vendor_event; 2154 struct nan_datapath_sch_update_event *sch_update = ind; 2155 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 2156 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 2157 2158 if (!sch_update) { 2159 osif_err("Invalid sch update params"); 2160 return; 2161 } 2162 2163 ifname = os_if_ndi_get_if_name(vdev); 2164 if (!ifname) { 2165 osif_err("ifname is null"); 2166 return; 2167 } 2168 ifname_len = qdf_str_len(ifname); 2169 if (ifname_len > IFNAMSIZ) { 2170 osif_err("ifname(%d) too long", ifname_len); 2171 return; 2172 } 2173 2174 data_len = osif_ndp_get_ndp_sch_update_ind_len(sch_update); 2175 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 2176 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 2177 GFP_ATOMIC); 2178 if (!vendor_event) { 2179 osif_err("cfg80211_vendor_event_alloc failed"); 2180 return; 2181 } 2182 2183 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 2184 QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND)) 2185 goto ndp_sch_ind_nla_failed; 2186 2187 if (nla_put(vendor_event, 2188 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, 2189 QDF_MAC_ADDR_SIZE, sch_update->peer_addr.bytes)) 2190 goto ndp_sch_ind_nla_failed; 2191 2192 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, 2193 sch_update->num_ndp_instances * sizeof(uint32_t), 2194 sch_update->ndp_instances)) 2195 goto ndp_sch_ind_nla_failed; 2196 2197 if (nla_put_u32(vendor_event, 2198 QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON, 2199 sch_update->flags)) 2200 goto ndp_sch_ind_nla_failed; 2201 2202 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS, 2203 sch_update->num_channels)) 2204 goto ndp_sch_ind_nla_failed; 2205 2206 status = os_if_ndp_sch_update_pack_ch_info(vendor_event, sch_update); 2207 if (QDF_IS_STATUS_ERROR(status)) 2208 goto ndp_sch_ind_nla_failed; 2209 2210 osif_debug("Flags: %d, num_instance_id: %d", sch_update->flags, 2211 sch_update->num_ndp_instances); 2212 2213 for (idx = 0; idx < sch_update->num_ndp_instances; idx++) 2214 osif_debug("ndp_instance[%d]: %d", idx, 2215 sch_update->ndp_instances[idx]); 2216 2217 cfg80211_vendor_event(vendor_event, GFP_ATOMIC); 2218 return; 2219 2220 ndp_sch_ind_nla_failed: 2221 osif_err("nla_put api failed"); 2222 kfree_skb(vendor_event); 2223 } 2224 2225 /** 2226 * os_if_ndp_host_update_handler() - NDP Host update handler 2227 * @vdev: vdev object pointer 2228 * @evt: pointer to host update event 2229 * 2230 * Return: none 2231 */ 2232 static void os_if_ndp_host_update_handler(struct wlan_objmgr_vdev *vdev, 2233 void *evt) 2234 { 2235 struct nan_vdev_priv_obj *vdev_nan_obj; 2236 struct nan_datapath_host_event *event; 2237 struct osif_request *request; 2238 2239 vdev_nan_obj = nan_get_vdev_priv_obj(vdev); 2240 if (!vdev_nan_obj) { 2241 osif_err("vdev_nan_obj is NULL"); 2242 return; 2243 } 2244 2245 request = osif_request_get(vdev_nan_obj->disable_context); 2246 if (!request) { 2247 osif_debug("Obsolete request"); 2248 return; 2249 } 2250 2251 event = osif_request_priv(request); 2252 qdf_mem_copy(event, evt, sizeof(*event)); 2253 2254 osif_request_complete(request); 2255 osif_request_put(request); 2256 } 2257 2258 static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc, 2259 struct wlan_objmgr_vdev *vdev, 2260 uint32_t type, void *msg) 2261 { 2262 switch (type) { 2263 case NAN_DATAPATH_INF_CREATE_RSP: 2264 os_if_ndp_iface_create_rsp_handler(psoc, vdev, msg); 2265 break; 2266 case NAN_DATAPATH_INF_DELETE_RSP: 2267 os_if_ndp_iface_delete_rsp_handler(psoc, vdev, msg); 2268 break; 2269 case NDP_CONFIRM: 2270 os_if_ndp_confirm_ind_handler(vdev, msg); 2271 break; 2272 case NDP_INITIATOR_RSP: 2273 os_if_ndp_initiator_rsp_handler(vdev, msg); 2274 break; 2275 case NDP_INDICATION: 2276 os_if_ndp_indication_handler(vdev, msg); 2277 break; 2278 case NDP_NEW_PEER: 2279 os_if_new_peer_ind_handler(vdev, msg); 2280 break; 2281 case NDP_RESPONDER_RSP: 2282 os_if_ndp_responder_rsp_handler(vdev, msg); 2283 break; 2284 case NDP_END_RSP: 2285 os_if_ndp_end_rsp_handler(vdev, msg); 2286 break; 2287 case NDP_END_IND: 2288 os_if_ndp_end_ind_handler(vdev, msg); 2289 break; 2290 case NDP_PEER_DEPARTED: 2291 os_if_peer_departed_ind_handler(vdev, msg); 2292 break; 2293 case NDP_SCHEDULE_UPDATE: 2294 os_if_ndp_sch_update_ind_handler(vdev, msg); 2295 break; 2296 case NDP_HOST_UPDATE: 2297 os_if_ndp_host_update_handler(vdev, msg); 2298 break; 2299 default: 2300 break; 2301 } 2302 } 2303 2304 int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc, 2305 struct nan_callbacks *cb_obj) 2306 { 2307 return ucfg_nan_register_lim_callbacks(psoc, cb_obj); 2308 } 2309 2310 void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, 2311 uint8_t vdev_id, bool success) 2312 { 2313 struct nan_datapath_inf_create_rsp rsp = {0}; 2314 struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 2315 psoc, vdev_id, WLAN_NAN_ID); 2316 2317 if (!vdev) { 2318 osif_err("vdev is null"); 2319 return; 2320 } 2321 2322 if (success) { 2323 rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; 2324 rsp.reason = 0; 2325 os_if_nan_datapath_event_handler(psoc, vdev, 2326 NAN_DATAPATH_INF_CREATE_RSP, 2327 &rsp); 2328 } else { 2329 rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR; 2330 rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED; 2331 os_if_nan_datapath_event_handler(psoc, vdev, 2332 NAN_DATAPATH_INF_CREATE_RSP, 2333 &rsp); 2334 } 2335 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); 2336 } 2337 2338 void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, 2339 uint8_t vdev_id, bool success) 2340 { 2341 struct nan_datapath_inf_delete_rsp rsp = {0}; 2342 struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 2343 psoc, vdev_id, WLAN_NAN_ID); 2344 if (!vdev) { 2345 osif_err("vdev is null"); 2346 return; 2347 } 2348 2349 if (success) { 2350 rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; 2351 rsp.reason = 0; 2352 os_if_nan_datapath_event_handler(psoc, vdev, 2353 NAN_DATAPATH_INF_DELETE_RSP, 2354 &rsp); 2355 } else { 2356 rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR; 2357 rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_DELETE_FAILED; 2358 os_if_nan_datapath_event_handler(psoc, vdev, 2359 NAN_DATAPATH_INF_DELETE_RSP, 2360 &rsp); 2361 } 2362 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); 2363 } 2364 2365 static inline uint32_t osif_ndp_get_ndi_delete_rsp_len(void) 2366 { 2367 uint32_t data_len = NLMSG_HDRLEN; 2368 2369 data_len += nla_total_size(vendor_attr_policy[ 2370 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); 2371 data_len += nla_total_size(vendor_attr_policy[ 2372 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); 2373 data_len += nla_total_size(vendor_attr_policy[ 2374 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); 2375 data_len += nla_total_size(vendor_attr_policy[ 2376 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); 2377 2378 return data_len; 2379 } 2380 2381 void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) 2382 { 2383 uint32_t data_len; 2384 struct sk_buff *vendor_event; 2385 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 2386 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); 2387 2388 /* 2389 * The virtual adapters are stopped and closed even during 2390 * driver unload or stop, the service layer is not required 2391 * to be informed in that case (response is not expected) 2392 */ 2393 if (NAN_DATA_NDI_DELETING_STATE != ucfg_nan_get_ndi_state(vdev)) { 2394 osif_err("NDI interface deleted"); 2395 return; 2396 } 2397 2398 data_len = osif_ndp_get_ndi_delete_rsp_len(); 2399 /* notify response to the upper layer */ 2400 vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 2401 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, 2402 GFP_KERNEL); 2403 2404 if (!vendor_event) { 2405 osif_err("cfg80211_vendor_event_alloc failed"); 2406 return; 2407 } 2408 2409 /* Sub vendor command goes first */ 2410 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 2411 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) { 2412 osif_err("VENDOR_ATTR_NDP_SUBCMD put fail"); 2413 goto failure; 2414 } 2415 2416 /* Transaction id */ 2417 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 2418 ucfg_nan_get_ndp_delete_transaction_id(vdev))) { 2419 osif_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); 2420 goto failure; 2421 } 2422 2423 /* Status code */ 2424 if (nla_put_u32(vendor_event, 2425 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 2426 ucfg_nan_get_ndi_delete_rsp_status(vdev))) { 2427 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"); 2428 goto failure; 2429 } 2430 2431 /* Status return value */ 2432 if (nla_put_u32(vendor_event, 2433 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 2434 ucfg_nan_get_ndi_delete_rsp_reason(vdev))) { 2435 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); 2436 goto failure; 2437 } 2438 2439 osif_debug("sub command: %d, value: %d", 2440 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, 2441 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE); 2442 osif_debug("delete transaction id: %d, value: %d", 2443 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, 2444 ucfg_nan_get_ndp_delete_transaction_id(vdev)); 2445 osif_debug("status code: %d, value: %d", 2446 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, 2447 ucfg_nan_get_ndi_delete_rsp_status(vdev)); 2448 osif_debug("Return value: %d, value: %d", 2449 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 2450 ucfg_nan_get_ndi_delete_rsp_reason(vdev)); 2451 2452 ucfg_nan_set_ndp_delete_transaction_id(vdev, 0); 2453 ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE); 2454 cfg80211_vendor_event(vendor_event, GFP_KERNEL); 2455 2456 return; 2457 failure: 2458 kfree_skb(vendor_event); 2459 } 2460 2461 /** 2462 * os_if_nan_discovery_event_handler() - NAN Discovery Interface event handler 2463 * @nan_evt: NAN Event parameters 2464 * 2465 * Module sends a NAN related vendor event to the upper layer 2466 * 2467 * Return: none 2468 */ 2469 static void os_if_nan_discovery_event_handler(struct nan_event_params *nan_evt) 2470 { 2471 struct sk_buff *vendor_event; 2472 struct wlan_objmgr_pdev *pdev; 2473 struct pdev_osif_priv *os_priv; 2474 2475 /* 2476 * Since Partial Offload chipsets have only one pdev per psoc, the first 2477 * pdev from the pdev list is used. 2478 */ 2479 pdev = wlan_objmgr_get_pdev_by_id(nan_evt->psoc, 0, WLAN_NAN_ID); 2480 if (!pdev) { 2481 osif_err("null pdev"); 2482 return; 2483 } 2484 os_priv = wlan_pdev_get_ospriv(pdev); 2485 2486 vendor_event = 2487 cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, 2488 nan_evt->buf_len + NLMSG_HDRLEN, 2489 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX, 2490 GFP_KERNEL); 2491 2492 if (!vendor_event) { 2493 osif_err("cfg80211_vendor_event_alloc failed"); 2494 goto fail; 2495 } 2496 2497 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN, nan_evt->buf_len, 2498 nan_evt->buf)) { 2499 osif_err("QCA_WLAN_VENDOR_ATTR_NAN put failed"); 2500 goto fail; 2501 } 2502 2503 cfg80211_vendor_event(vendor_event, GFP_KERNEL); 2504 fail: 2505 wlan_objmgr_pdev_release_ref(pdev, WLAN_NAN_ID); 2506 } 2507 2508 int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, 2509 struct nan_callbacks *cb_obj) 2510 { 2511 cb_obj->os_if_ndp_event_handler = os_if_nan_datapath_event_handler; 2512 cb_obj->os_if_nan_event_handler = os_if_nan_discovery_event_handler; 2513 return ucfg_nan_register_hdd_callbacks(psoc, cb_obj); 2514 } 2515 2516 static int os_if_nan_generic_req(struct wlan_objmgr_psoc *psoc, 2517 struct nlattr **tb) 2518 { 2519 struct nan_generic_req *nan_req; 2520 uint32_t buf_len; 2521 QDF_STATUS status; 2522 2523 buf_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]); 2524 2525 nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len); 2526 if (!nan_req) { 2527 osif_err("Request allocation failure"); 2528 return -ENOMEM; 2529 } 2530 2531 nan_req->psoc = psoc; 2532 nan_req->params.request_data_len = buf_len; 2533 nla_memcpy(nan_req->params.request_data, 2534 tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA], buf_len); 2535 2536 osif_debug("sending NAN Req"); 2537 status = ucfg_nan_discovery_req(nan_req, NAN_GENERIC_REQ); 2538 2539 if (QDF_IS_STATUS_SUCCESS(status)) 2540 osif_debug("Successfully sent a NAN request"); 2541 else 2542 osif_err("Unable to send a NAN request"); 2543 2544 qdf_mem_free(nan_req); 2545 return qdf_status_to_os_return(status); 2546 } 2547 2548 int os_if_nan_legacy_req(struct wlan_objmgr_psoc *psoc, const void *data, 2549 int data_len) 2550 { 2551 struct nan_generic_req *nan_req; 2552 QDF_STATUS status; 2553 2554 if (data_len > NAN_CMD_MAX_SIZE) { 2555 osif_err("NAN request exceeding max allowed size"); 2556 return -EINVAL; 2557 } 2558 2559 nan_req = qdf_mem_malloc(sizeof(*nan_req) + data_len); 2560 if (!nan_req) 2561 return -ENOMEM; 2562 2563 nan_req->psoc = psoc; 2564 nan_req->params.request_data_len = data_len; 2565 qdf_mem_copy(nan_req->params.request_data, data, data_len); 2566 2567 /* 2568 * Send legacy NAN requests with type GENERIC, these will be treated as 2569 * passthrough by the driver. These will not affect the NAN state 2570 * machine or policy manager. 2571 */ 2572 status = ucfg_nan_discovery_req(nan_req, NAN_GENERIC_REQ); 2573 2574 if (QDF_IS_STATUS_ERROR(status)) 2575 osif_err("Failed to post NAN request"); 2576 2577 qdf_mem_free(nan_req); 2578 2579 return qdf_status_to_os_return(status); 2580 } 2581 2582 static int os_if_process_nan_disable_req(struct wlan_objmgr_psoc *psoc, 2583 struct nlattr **tb) 2584 { 2585 struct nan_disable_req *nan_req; 2586 uint32_t buf_len; 2587 QDF_STATUS status; 2588 2589 buf_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]); 2590 2591 nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len); 2592 if (!nan_req) { 2593 osif_err("Request allocation failure"); 2594 return -ENOMEM; 2595 } 2596 2597 nan_req->psoc = psoc; 2598 nan_req->disable_2g_discovery = true; 2599 nan_req->disable_5g_discovery = true; 2600 nan_req->params.request_data_len = buf_len; 2601 nla_memcpy(nan_req->params.request_data, 2602 tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA], buf_len); 2603 2604 osif_debug("sending NAN Disable Req"); 2605 status = ucfg_nan_discovery_req(nan_req, NAN_DISABLE_REQ); 2606 2607 if (QDF_IS_STATUS_SUCCESS(status)) 2608 osif_debug("Successfully sent NAN Disable request"); 2609 else 2610 osif_err("Unable to send NAN Disable request"); 2611 2612 qdf_mem_free(nan_req); 2613 return qdf_status_to_os_return(status); 2614 } 2615 2616 static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc, 2617 struct nlattr **tb) 2618 { 2619 uint32_t chan_freq_2g, chan_freq_5g = 0; 2620 uint8_t nan_chan_2g; 2621 uint32_t buf_len; 2622 QDF_STATUS status; 2623 struct nan_enable_req *nan_req; 2624 2625 if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ]) { 2626 osif_err("NAN Social channel for 2.4Gz is unavailable!"); 2627 return -EINVAL; 2628 } 2629 chan_freq_2g = 2630 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ]); 2631 2632 if (tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ]) 2633 chan_freq_5g = 2634 nla_get_u32(tb[ 2635 QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ]); 2636 2637 nan_chan_2g = wlan_freq_to_chan(chan_freq_2g); 2638 if (!ucfg_is_nan_enable_allowed(psoc, nan_chan_2g)) { 2639 osif_err("NAN Enable not allowed at this moment for channel %d", 2640 nan_chan_2g); 2641 return -EINVAL; 2642 } 2643 2644 buf_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]); 2645 2646 nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len); 2647 2648 if (!nan_req) { 2649 osif_err("Request allocation failure"); 2650 return -ENOMEM; 2651 } 2652 nan_req->social_chan_2g = wlan_freq_to_chan(chan_freq_2g); 2653 if (chan_freq_5g) 2654 nan_req->social_chan_5g = wlan_freq_to_chan(chan_freq_5g); 2655 nan_req->psoc = psoc; 2656 nan_req->params.request_data_len = buf_len; 2657 2658 nla_memcpy(nan_req->params.request_data, 2659 tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA], buf_len); 2660 2661 osif_debug("Sending NAN Enable Req. NAN Ch: %d %d", 2662 nan_req->social_chan_2g, nan_req->social_chan_5g); 2663 status = ucfg_nan_discovery_req(nan_req, NAN_ENABLE_REQ); 2664 2665 if (QDF_IS_STATUS_SUCCESS(status)) 2666 osif_debug("Successfully sent NAN Enable request"); 2667 else 2668 osif_err("Unable to send NAN Enable request"); 2669 2670 qdf_mem_free(nan_req); 2671 return qdf_status_to_os_return(status); 2672 } 2673 2674 int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, 2675 const void *data, int data_len) 2676 { 2677 uint32_t nan_subcmd; 2678 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX + 1]; 2679 2680 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX, 2681 data, data_len, nan_attr_policy)) { 2682 osif_err("Invalid NAN vendor command attributes"); 2683 return -EINVAL; 2684 } 2685 2686 if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]) { 2687 osif_err("NAN cmd data missing!"); 2688 return -EINVAL; 2689 } 2690 2691 /* 2692 * If target does not support NAN DBS, send request with type GENERIC. 2693 * These will be treated as passthrough by the driver. This is to make 2694 * sure that HW mode is not set to DBS by NAN Enable request. NAN state 2695 * machine will remain unaffected in this case. 2696 */ 2697 if (!ucfg_is_nan_dbs_supported(psoc)) 2698 return os_if_nan_generic_req(psoc, tb); 2699 2700 /* 2701 * Send all requests other than Enable/Disable as type GENERIC. 2702 * These will be treated as passthrough by the driver. 2703 */ 2704 if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE]) 2705 return os_if_nan_generic_req(psoc, tb); 2706 2707 nan_subcmd = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE]); 2708 2709 switch (nan_subcmd) { 2710 case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ: 2711 return os_if_process_nan_enable_req(psoc, tb); 2712 case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ: 2713 return os_if_process_nan_disable_req(psoc, tb); 2714 default: 2715 osif_err("Unrecognized NAN subcmd type(%d)", nan_subcmd); 2716 return -EINVAL; 2717 } 2718 } 2719