1 /* 2 * Copyright (c) 2012-2018 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: wlan_hdd_hostapd.c 21 * 22 * WLAN Host Device Driver implementation 23 */ 24 25 /* Include Files */ 26 27 #include <linux/version.h> 28 #include <linux/module.h> 29 #include <linux/kernel.h> 30 #include <linux/init.h> 31 #include <linux/wireless.h> 32 #include <linux/semaphore.h> 33 #include <linux/compat.h> 34 #include <cdp_txrx_stats.h> 35 #include <cdp_txrx_cmn.h> 36 #include <cds_api.h> 37 #include <cds_sched.h> 38 #include <linux/etherdevice.h> 39 #include <wlan_hdd_includes.h> 40 #include <qc_sap_ioctl.h> 41 #include <wlan_hdd_hostapd.h> 42 #include <wlan_hdd_green_ap.h> 43 #include <sap_api.h> 44 #include <sap_internal.h> 45 #include <wlan_hdd_softap_tx_rx.h> 46 #include <wlan_hdd_main.h> 47 #include <wlan_hdd_ioctl.h> 48 #include <wlan_hdd_stats.h> 49 #include <linux/netdevice.h> 50 #include <linux/rtnetlink.h> 51 #include <linux/mmc/sdio_func.h> 52 #include "wlan_hdd_p2p.h" 53 #include <wlan_hdd_ipa.h> 54 #include "cfg_api.h" 55 #include "wni_cfg.h" 56 #include "wlan_hdd_misc.h" 57 #include <cds_utils.h> 58 #include "pld_common.h" 59 60 #include "wma.h" 61 #ifdef WLAN_DEBUG 62 #include "wma_api.h" 63 #endif 64 #include "wlan_hdd_trace.h" 65 #include "qdf_str.h" 66 #include "qdf_types.h" 67 #include "qdf_trace.h" 68 #include "wlan_hdd_cfg.h" 69 #include "wlan_policy_mgr_api.h" 70 #include "wlan_hdd_tsf.h" 71 #include <cdp_txrx_misc.h> 72 #include "wlan_hdd_power.h" 73 #include "wlan_hdd_object_manager.h" 74 #include <qca_vendor.h> 75 #include <cds_api.h> 76 #include <cdp_txrx_stats.h> 77 #include "wlan_hdd_he.h" 78 #include "wlan_dfs_tgt_api.h" 79 #include "wlan_dfs_utils_api.h" 80 #include <wlan_reg_ucfg_api.h> 81 #include "wlan_utility.h" 82 #include <wlan_p2p_ucfg_api.h> 83 #include "sir_api.h" 84 #include "sme_api.h" 85 #include "wlan_hdd_regulatory.h" 86 #include <wlan_ipa_ucfg_api.h> 87 #include <wlan_cfg80211_mc_cp_stats.h> 88 #include <wlan_cp_stats_mc_ucfg_api.h> 89 90 #define IS_UP(_dev) \ 91 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) 92 #define IS_UP_AUTO(_ic) \ 93 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO) 94 #define WE_WLAN_VERSION 1 95 #define WE_GET_STA_INFO_SIZE 30 96 /* WEXT limitation: MAX allowed buf len for any * 97 * IW_PRIV_TYPE_CHAR is 2Kbytes * 98 */ 99 #define WE_SAP_MAX_STA_INFO 0x7FF 100 101 #define RC_2_RATE_IDX(_rc) ((_rc) & 0x7) 102 #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 103 #define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf) 104 #define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1) 105 106 #define SAP_24GHZ_CH_COUNT (14) 107 #define ACS_SCAN_EXPIRY_TIMEOUT_S 4 108 109 /* 110 * 11B, 11G Rate table include Basic rate and Extended rate 111 * The IDX field is the rate index 112 * The HI field is the rate when RSSI is strong or being ignored 113 * (in this case we report actual rate) 114 * The MID field is the rate when RSSI is moderate 115 * (in this case we cap 11b rates at 5.5 and 11g rates at 24) 116 * The LO field is the rate when RSSI is low 117 * (in this case we don't report rates, actual current rate used) 118 */ 119 static const struct index_data_rate_type supported_data_rate[] = { 120 /* IDX HI HM LM LO (RSSI-based index */ 121 {2, { 10, 10, 10, 0} }, 122 {4, { 20, 20, 10, 0} }, 123 {11, { 55, 20, 10, 0} }, 124 {12, { 60, 55, 20, 0} }, 125 {18, { 90, 55, 20, 0} }, 126 {22, {110, 55, 20, 0} }, 127 {24, {120, 90, 60, 0} }, 128 {36, {180, 120, 60, 0} }, 129 {44, {220, 180, 60, 0} }, 130 {48, {240, 180, 90, 0} }, 131 {66, {330, 180, 90, 0} }, 132 {72, {360, 240, 90, 0} }, 133 {96, {480, 240, 120, 0} }, 134 {108, {540, 240, 120, 0} } 135 }; 136 137 /* MCS Based rate table */ 138 /* HT MCS parameters with Nss = 1 */ 139 static const struct index_data_rate_type supported_mcs_rate_nss1[] = { 140 /* MCS L20 L40 S20 S40 */ 141 {0, { 65, 135, 72, 150} }, 142 {1, { 130, 270, 144, 300} }, 143 {2, { 195, 405, 217, 450} }, 144 {3, { 260, 540, 289, 600} }, 145 {4, { 390, 810, 433, 900} }, 146 {5, { 520, 1080, 578, 1200} }, 147 {6, { 585, 1215, 650, 1350} }, 148 {7, { 650, 1350, 722, 1500} } 149 }; 150 151 /* HT MCS parameters with Nss = 2 */ 152 static const struct index_data_rate_type supported_mcs_rate_nss2[] = { 153 /* MCS L20 L40 S20 S40 */ 154 {0, {130, 270, 144, 300} }, 155 {1, {260, 540, 289, 600} }, 156 {2, {390, 810, 433, 900} }, 157 {3, {520, 1080, 578, 1200} }, 158 {4, {780, 1620, 867, 1800} }, 159 {5, {1040, 2160, 1156, 2400} }, 160 {6, {1170, 2430, 1300, 2700} }, 161 {7, {1300, 2700, 1444, 3000} } 162 }; 163 164 /* MCS Based VHT rate table */ 165 /* MCS parameters with Nss = 1*/ 166 static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = { 167 /* MCS L80 S80 L40 S40 L20 S40*/ 168 {0, {293, 325}, {135, 150}, {65, 72} }, 169 {1, {585, 650}, {270, 300}, {130, 144} }, 170 {2, {878, 975}, {405, 450}, {195, 217} }, 171 {3, {1170, 1300}, {540, 600}, {260, 289} }, 172 {4, {1755, 1950}, {810, 900}, {390, 433} }, 173 {5, {2340, 2600}, {1080, 1200}, {520, 578} }, 174 {6, {2633, 2925}, {1215, 1350}, {585, 650} }, 175 {7, {2925, 3250}, {1350, 1500}, {650, 722} }, 176 {8, {3510, 3900}, {1620, 1800}, {780, 867} }, 177 {9, {3900, 4333}, {1800, 2000}, {780, 867} } 178 }; 179 180 /*MCS parameters with Nss = 2*/ 181 static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = { 182 /* MCS L80 S80 L40 S40 L20 S40*/ 183 {0, {585, 650}, {270, 300}, {130, 144} }, 184 {1, {1170, 1300}, {540, 600}, {260, 289} }, 185 {2, {1755, 1950}, {810, 900}, {390, 433} }, 186 {3, {2340, 2600}, {1080, 1200}, {520, 578} }, 187 {4, {3510, 3900}, {1620, 1800}, {780, 867} }, 188 {5, {4680, 5200}, {2160, 2400}, {1040, 1156} }, 189 {6, {5265, 5850}, {2430, 2700}, {1170, 1300} }, 190 {7, {5850, 6500}, {2700, 3000}, {1300, 1444} }, 191 {8, {7020, 7800}, {3240, 3600}, {1560, 1733} }, 192 {9, {7800, 8667}, {3600, 4000}, {1560, 1733} } 193 }; 194 195 /* Function definitions */ 196 197 /** 198 * hdd_sap_context_init() - Initialize SAP context. 199 * @hdd_ctx: HDD context. 200 * 201 * Initialize SAP context. 202 * 203 * Return: 0 on success. 204 */ 205 int hdd_sap_context_init(struct hdd_context *hdd_ctx) 206 { 207 qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock"); 208 atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0); 209 210 mutex_init(&hdd_ctx->sap_lock); 211 qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); 212 qdf_spinlock_create(&hdd_ctx->sap_update_info_lock); 213 214 return 0; 215 } 216 217 /** 218 * hdd_hostapd_init_sap_session() - To init the sap session completely 219 * @adapter: SAP/GO adapter 220 * 221 * This API will do 222 * 1) sap_init_ctx() 223 * 224 * Return: 0 if success else non-zero value. 225 */ 226 static struct sap_context * 227 hdd_hostapd_init_sap_session(struct hdd_adapter *adapter) 228 { 229 struct sap_context *sap_ctx; 230 QDF_STATUS status; 231 232 if (!adapter) { 233 hdd_err("invalid adapter"); 234 return NULL; 235 } 236 237 sap_ctx = adapter->session.ap.sap_context; 238 239 if (!sap_ctx) { 240 hdd_err("can't allocate the sap_ctx"); 241 return NULL; 242 } 243 status = sap_init_ctx(sap_ctx, adapter->device_mode, 244 adapter->mac_addr.bytes, 245 adapter->session_id); 246 if (QDF_IS_STATUS_ERROR(status)) { 247 hdd_err("wlansap_start failed!! status: %d", status); 248 adapter->session.ap.sap_context = NULL; 249 goto error; 250 } 251 return sap_ctx; 252 error: 253 wlansap_context_put(sap_ctx); 254 hdd_err("releasing the sap context for session-id:%d", 255 adapter->session_id); 256 257 return NULL; 258 } 259 260 /** 261 * hdd_hostapd_deinit_sap_session() - To de-init the sap session completely 262 * @adapter: SAP/GO adapter 263 * 264 * This API will do 265 * 1) sap_init_ctx() 266 * 2) sap_destroy_ctx() 267 * 268 * Return: 0 if success else non-zero value. 269 */ 270 static int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter) 271 { 272 struct sap_context *sap_ctx; 273 int status = 0; 274 275 if (!adapter) { 276 hdd_err("invalid adapter"); 277 return -EINVAL; 278 } 279 280 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); 281 if (!sap_ctx) { 282 hdd_debug("sap context already released, nothing to be done"); 283 return 0; 284 } 285 286 if (!QDF_IS_STATUS_SUCCESS(sap_deinit_ctx(sap_ctx))) { 287 hdd_err("Error stopping the sap session"); 288 status = -EINVAL; 289 } 290 291 if (!QDF_IS_STATUS_SUCCESS(sap_destroy_ctx(sap_ctx))) { 292 hdd_err("Error closing the sap session"); 293 status = -EINVAL; 294 } 295 adapter->session.ap.sap_context = NULL; 296 297 if (!QDF_IS_STATUS_SUCCESS(status)) 298 hdd_debug("sap has issue closing the session"); 299 else 300 hdd_debug("sap has been closed successfully"); 301 302 303 return status; 304 } 305 306 /** 307 * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel. 308 * Called when, 1. bss stopped, 2. channel switch 309 * 310 * @adapter: pointer to hdd adapter 311 * @channel: current channel 312 * 313 * Return: None 314 */ 315 static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter, 316 uint8_t channel) 317 { 318 319 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 320 struct hdd_hostapd_state *hostapd_state = 321 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 322 323 hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d", 324 hostapd_state->bss_state, channel, 325 atomic_read(&hdd_ctx->sap_dfs_ref_cnt)); 326 327 /* Return if BSS is already stopped */ 328 if (hostapd_state->bss_state == BSS_STOP) 329 return; 330 331 if (CHANNEL_STATE_DFS != wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, 332 channel)) 333 return; 334 335 /* Release wakelock when no more DFS channels are used */ 336 if (atomic_dec_and_test(&hdd_ctx->sap_dfs_ref_cnt)) { 337 hdd_err("DFS: allowing suspend (chan: %d)", channel); 338 qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock, 339 WIFI_POWER_EVENT_WAKELOCK_DFS); 340 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.dfs); 341 342 } 343 } 344 345 /** 346 * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel. 347 * Called when, 1. bss started, 2. channel switch 348 * 349 * @adapter: pointer to hdd adapter 350 * @channel: current channel 351 * 352 * Return - None 353 */ 354 static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter, 355 uint8_t channel) 356 { 357 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 358 struct hdd_hostapd_state *hostapd_state = 359 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 360 361 hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d", 362 hostapd_state->bss_state, channel, 363 atomic_read(&hdd_ctx->sap_dfs_ref_cnt)); 364 365 /* Return if BSS is already started && wakelock is acquired */ 366 if ((hostapd_state->bss_state == BSS_START) && 367 (atomic_read(&hdd_ctx->sap_dfs_ref_cnt) >= 1)) 368 return; 369 370 if (CHANNEL_STATE_DFS != wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, 371 channel)) 372 return; 373 374 /* Acquire wakelock if we have at least one DFS channel in use */ 375 if (atomic_inc_return(&hdd_ctx->sap_dfs_ref_cnt) == 1) { 376 hdd_err("DFS: preventing suspend (chan: %d)", channel); 377 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.dfs); 378 qdf_wake_lock_acquire(&hdd_ctx->sap_dfs_wakelock, 379 WIFI_POWER_EVENT_WAKELOCK_DFS); 380 } 381 } 382 383 /** 384 * hdd_sap_context_destroy() - Destroy SAP context 385 * 386 * @hdd_ctx: HDD context. 387 * 388 * Destroy SAP context. 389 * 390 * Return: None 391 */ 392 void hdd_sap_context_destroy(struct hdd_context *hdd_ctx) 393 { 394 if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) { 395 qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock, 396 WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT); 397 398 atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0); 399 hdd_debug("DFS: Allowing suspend"); 400 } 401 402 qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock); 403 404 mutex_destroy(&hdd_ctx->sap_lock); 405 qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock); 406 407 qdf_spinlock_destroy(&hdd_ctx->sap_update_info_lock); 408 409 } 410 411 /** 412 * __hdd_hostapd_open() - hdd open function for hostapd interface 413 * This is called in response to ifconfig up 414 * @dev: pointer to net_device structure 415 * 416 * Return - 0 for success non-zero for failure 417 */ 418 static int __hdd_hostapd_open(struct net_device *dev) 419 { 420 struct hdd_adapter *adapter = netdev_priv(dev); 421 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 422 int ret; 423 424 hdd_enter_dev(dev); 425 426 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, 427 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0)); 428 /* Nothing to be done if device is unloading */ 429 if (cds_is_driver_unloading()) { 430 hdd_err("Driver is unloading can not open the hdd"); 431 return -EBUSY; 432 } 433 434 if (cds_is_driver_recovering()) { 435 hdd_err("WLAN is currently recovering; Please try again."); 436 return -EBUSY; 437 } 438 439 ret = wlan_hdd_validate_context(hdd_ctx); 440 if (ret) 441 return ret; 442 /* 443 * Check statemachine state and also stop iface change timer if running 444 */ 445 ret = hdd_wlan_start_modules(hdd_ctx, false); 446 447 if (ret) { 448 hdd_err("Failed to start WLAN modules return"); 449 return ret; 450 } 451 452 ret = hdd_start_adapter(adapter); 453 if (ret) { 454 hdd_err("Error Initializing the AP mode: %d", ret); 455 return ret; 456 } 457 458 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 459 460 /* Enable all Tx queues */ 461 hdd_debug("Enabling queues"); 462 wlan_hdd_netif_queue_control(adapter, 463 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, 464 WLAN_CONTROL_PATH); 465 hdd_exit(); 466 return 0; 467 } 468 469 /** 470 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open 471 * @dev: pointer to net device 472 * 473 * Return: 0 on success, error number otherwise 474 */ 475 static int hdd_hostapd_open(struct net_device *dev) 476 { 477 int ret; 478 479 cds_ssr_protect(__func__); 480 ret = __hdd_hostapd_open(dev); 481 cds_ssr_unprotect(__func__); 482 483 return ret; 484 } 485 486 /** 487 * __hdd_hostapd_stop() - hdd stop function for hostapd interface 488 * This is called in response to ifconfig down 489 * 490 * @dev: pointer to net_device structure 491 * 492 * Return - 0 for success non-zero for failure 493 */ 494 static int __hdd_hostapd_stop(struct net_device *dev) 495 { 496 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 497 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 498 int ret; 499 500 hdd_enter_dev(dev); 501 ret = wlan_hdd_validate_context(hdd_ctx); 502 if (ret) 503 return ret; 504 505 /* 506 * Some tests requires to do "ifconfig down" only to bring 507 * down the SAP/GO without killing hostapd/wpa_supplicant. 508 * In such case, user will do "ifconfig up" to bring-back 509 * the SAP/GO session. to fulfill this requirement, driver 510 * needs to de-init the sap session here and re-init when 511 * __hdd_hostapd_open() API 512 */ 513 hdd_stop_adapter(hdd_ctx, adapter); 514 hdd_deinit_adapter(hdd_ctx, adapter, true); 515 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 516 517 if (!hdd_is_cli_iface_up(hdd_ctx)) 518 sme_scan_flush_result(hdd_ctx->hHal); 519 520 /* Stop all tx queues */ 521 hdd_debug("Disabling queues"); 522 wlan_hdd_netif_queue_control(adapter, 523 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 524 WLAN_CONTROL_PATH); 525 526 hdd_exit(); 527 return 0; 528 } 529 530 /** 531 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop 532 * @dev: pointer to net_device 533 * 534 * This is called in response to ifconfig down 535 * 536 * Return: 0 on success, error number otherwise 537 */ 538 int hdd_hostapd_stop(struct net_device *dev) 539 { 540 int ret; 541 542 cds_ssr_protect(__func__); 543 ret = __hdd_hostapd_stop(dev); 544 cds_ssr_unprotect(__func__); 545 546 return ret; 547 } 548 549 /** 550 * __hdd_hostapd_uninit() - hdd uninit function 551 * This is called during the netdev unregister to uninitialize all data 552 * associated with the device. 553 * 554 * @dev: pointer to net_device structure 555 * 556 * Return: None 557 */ 558 static void __hdd_hostapd_uninit(struct net_device *dev) 559 { 560 struct hdd_adapter *adapter = netdev_priv(dev); 561 struct hdd_context *hdd_ctx; 562 563 hdd_enter_dev(dev); 564 565 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 566 hdd_err("Invalid magic"); 567 return; 568 } 569 570 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 571 if (NULL == hdd_ctx) { 572 hdd_err("NULL hdd_ctx"); 573 return; 574 } 575 576 hdd_deinit_adapter(hdd_ctx, adapter, true); 577 578 /* after uninit our adapter structure will no longer be valid */ 579 adapter->dev = NULL; 580 adapter->magic = 0; 581 582 hdd_exit(); 583 } 584 585 /** 586 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit 587 * @dev: pointer to net_device 588 * 589 * Return: 0 on success, error number otherwise 590 */ 591 static void hdd_hostapd_uninit(struct net_device *dev) 592 { 593 cds_ssr_protect(__func__); 594 __hdd_hostapd_uninit(dev); 595 cds_ssr_unprotect(__func__); 596 } 597 598 /** 599 * __hdd_hostapd_change_mtu() - change mtu 600 * @dev: pointer to net_device 601 * @new_mtu: new mtu 602 * 603 * Return: 0 on success, error number otherwise 604 */ 605 static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu) 606 { 607 hdd_enter_dev(dev); 608 609 return 0; 610 } 611 612 /** 613 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu 614 * @dev: pointer to net_device 615 * @new_mtu: new mtu 616 * 617 * Return: 0 on success, error number otherwise 618 */ 619 static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu) 620 { 621 int ret; 622 623 cds_ssr_protect(__func__); 624 ret = __hdd_hostapd_change_mtu(dev, new_mtu); 625 cds_ssr_unprotect(__func__); 626 627 return ret; 628 } 629 630 #ifdef QCA_HT_2040_COEX 631 QDF_STATUS hdd_set_sap_ht2040_mode(struct hdd_adapter *adapter, 632 uint8_t channel_type) 633 { 634 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 635 void *hHal = NULL; 636 637 hdd_debug("change HT20/40 mode"); 638 639 if (QDF_SAP_MODE == adapter->device_mode) { 640 hHal = WLAN_HDD_GET_HAL_CTX(adapter); 641 if (NULL == hHal) { 642 hdd_err("Hal ctx is null"); 643 return QDF_STATUS_E_FAULT; 644 } 645 qdf_ret_status = 646 sme_set_ht2040_mode(hHal, adapter->session_id, 647 channel_type, true); 648 if (qdf_ret_status == QDF_STATUS_E_FAILURE) { 649 hdd_err("Failed to change HT20/40 mode"); 650 return QDF_STATUS_E_FAILURE; 651 } 652 } 653 return QDF_STATUS_SUCCESS; 654 } 655 #endif 656 657 /** 658 * __hdd_hostapd_set_mac_address() - 659 * This function sets the user specified mac address using 660 * the command ifconfig wlanX hw ether <mac address>. 661 * 662 * @dev: pointer to the net device. 663 * @addr: pointer to the sockaddr. 664 * 665 * Return: 0 for success, non zero for failure 666 */ 667 static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) 668 { 669 struct sockaddr *psta_mac_addr = addr; 670 struct hdd_adapter *adapter; 671 struct hdd_context *hdd_ctx; 672 int ret = 0; 673 struct qdf_mac_addr mac_addr; 674 675 hdd_enter_dev(dev); 676 677 adapter = WLAN_HDD_GET_PRIV_PTR(dev); 678 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 679 ret = wlan_hdd_validate_context(hdd_ctx); 680 if (0 != ret) 681 return ret; 682 683 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr)); 684 685 if (hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes)) { 686 hdd_err("adapter exist with same mac address " MAC_ADDRESS_STR, 687 MAC_ADDR_ARRAY(mac_addr.bytes)); 688 return -EINVAL; 689 } 690 691 if (qdf_is_macaddr_zero(&mac_addr)) { 692 hdd_err("MAC is all zero"); 693 return -EINVAL; 694 } 695 696 if (qdf_is_macaddr_broadcast(&mac_addr)) { 697 hdd_err("MAC is Broadcast"); 698 return -EINVAL; 699 } 700 701 if (ETHER_IS_MULTICAST(psta_mac_addr->sa_data)) { 702 hdd_err("MAC is Multicast"); 703 return -EINVAL; 704 } 705 706 hdd_info("Changing MAC to " MAC_ADDRESS_STR " of interface %s ", 707 MAC_ADDR_ARRAY(mac_addr.bytes), 708 dev->name); 709 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); 710 hdd_exit(); 711 return 0; 712 } 713 714 /** 715 * hdd_hostapd_set_mac_address() - set mac address 716 * @dev: pointer to net_device 717 * @addr: mac address 718 * 719 * Return: 0 on success, error number otherwise 720 */ 721 static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) 722 { 723 int ret; 724 725 cds_ssr_protect(__func__); 726 ret = __hdd_hostapd_set_mac_address(dev, addr); 727 cds_ssr_unprotect(__func__); 728 729 return ret; 730 } 731 732 static void hdd_clear_sta(struct hdd_adapter *adapter, uint8_t sta_id) 733 { 734 struct hdd_ap_ctx *ap_ctx; 735 struct hdd_station_info *sta_info; 736 struct csr_del_sta_params del_sta_params; 737 738 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); 739 740 if (sta_id == ap_ctx->broadcast_sta_id) 741 return; 742 743 sta_info = &adapter->sta_info[sta_id]; 744 if (!sta_info->in_use) 745 return; 746 747 wlansap_populate_del_sta_params(sta_info->sta_mac.bytes, 748 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, 749 (SIR_MAC_MGMT_DISASSOC >> 4), 750 &del_sta_params); 751 752 hdd_softap_sta_disassoc(adapter, &del_sta_params); 753 } 754 755 static void hdd_clear_all_sta(struct hdd_adapter *adapter) 756 { 757 uint8_t sta_id; 758 759 hdd_enter_dev(adapter->dev); 760 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) 761 hdd_clear_sta(adapter, sta_id); 762 } 763 764 static int hdd_stop_bss_link(struct hdd_adapter *adapter) 765 { 766 struct hdd_context *hdd_ctx; 767 int errno; 768 QDF_STATUS status; 769 770 hdd_enter(); 771 772 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 773 errno = wlan_hdd_validate_context(hdd_ctx); 774 if (errno) 775 return errno; 776 777 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 778 status = wlansap_stop_bss( 779 WLAN_HDD_GET_SAP_CTX_PTR(adapter)); 780 if (QDF_IS_STATUS_SUCCESS(status)) 781 hdd_debug("Deleting SAP/P2P link!!!!!!"); 782 783 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); 784 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc, 785 adapter->device_mode, 786 adapter->session_id); 787 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 788 false); 789 errno = (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY; 790 } 791 hdd_exit(); 792 return errno; 793 } 794 795 /** 796 * hdd_chan_change_notify() - Function to notify hostapd about channel change 797 * @hostapd_adapter: hostapd adapter 798 * @dev: Net device structure 799 * @chan_change: New channel change parameters 800 * @legacy_phymode: is the phymode legacy 801 * 802 * This function is used to notify hostapd about the channel change 803 * 804 * Return: Success on intimating userspace 805 * 806 */ 807 QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter, 808 struct net_device *dev, 809 struct hdd_chan_change_params chan_change, 810 bool legacy_phymode) 811 { 812 struct ieee80211_channel *chan; 813 struct cfg80211_chan_def chandef; 814 enum nl80211_channel_type channel_type; 815 uint32_t freq; 816 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter); 817 818 if (NULL == hal) { 819 hdd_err("hal is NULL"); 820 return QDF_STATUS_E_FAILURE; 821 } 822 823 hdd_debug("chan:%d width:%d sec_ch_offset:%d seg0:%d seg1:%d", 824 chan_change.chan, chan_change.chan_params.ch_width, 825 chan_change.chan_params.sec_ch_offset, 826 chan_change.chan_params.center_freq_seg0, 827 chan_change.chan_params.center_freq_seg1); 828 829 freq = cds_chan_to_freq(chan_change.chan); 830 831 chan = ieee80211_get_channel(adapter->wdev.wiphy, freq); 832 833 if (!chan) { 834 hdd_err("Invalid input frequency for channel conversion"); 835 return QDF_STATUS_E_FAILURE; 836 } 837 838 if (legacy_phymode) { 839 channel_type = NL80211_CHAN_NO_HT; 840 } else { 841 switch (chan_change.chan_params.sec_ch_offset) { 842 case PHY_SINGLE_CHANNEL_CENTERED: 843 channel_type = NL80211_CHAN_HT20; 844 break; 845 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 846 channel_type = NL80211_CHAN_HT40MINUS; 847 break; 848 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 849 channel_type = NL80211_CHAN_HT40PLUS; 850 break; 851 default: 852 channel_type = NL80211_CHAN_NO_HT; 853 break; 854 } 855 } 856 857 cfg80211_chandef_create(&chandef, chan, channel_type); 858 859 /* cfg80211_chandef_create() does update of width and center_freq1 860 * only for NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS 861 * and NL80211_CHAN_HT40MINUS. 862 */ 863 if (chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) 864 chandef.width = NL80211_CHAN_WIDTH_80; 865 else if (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) 866 chandef.width = NL80211_CHAN_WIDTH_80P80; 867 else if (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ) 868 chandef.width = NL80211_CHAN_WIDTH_160; 869 870 if ((chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) || 871 (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) || 872 (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)) { 873 if (chan_change.chan_params.center_freq_seg0) 874 chandef.center_freq1 = cds_chan_to_freq( 875 chan_change.chan_params.center_freq_seg0); 876 877 if (chan_change.chan_params.center_freq_seg1) 878 chandef.center_freq2 = cds_chan_to_freq( 879 chan_change.chan_params.center_freq_seg1); 880 } 881 882 hdd_debug("notify: chan:%d width:%d freq1:%d freq2:%d", 883 chandef.chan->center_freq, chandef.width, chandef.center_freq1, 884 chandef.center_freq2); 885 886 cfg80211_ch_switch_notify(dev, &chandef); 887 888 return QDF_STATUS_SUCCESS; 889 } 890 891 /** 892 * hdd_send_radar_event() - Function to send radar events to user space 893 * @hdd_context: HDD context 894 * @event: Type of radar event 895 * @dfs_info: Structure containing DFS channel and country 896 * @wdev: Wireless device structure 897 * 898 * This function is used to send radar events such as CAC start, CAC 899 * end etc., to userspace 900 * 901 * Return: Success on sending notifying userspace 902 * 903 */ 904 static QDF_STATUS hdd_send_radar_event(struct hdd_context *hdd_context, 905 eSapHddEvent event, 906 struct wlan_dfs_info dfs_info, 907 struct wireless_dev *wdev) 908 { 909 910 struct sk_buff *vendor_event; 911 enum qca_nl80211_vendor_subcmds_index index; 912 uint32_t freq, ret; 913 uint32_t data_size; 914 915 if (!hdd_context) { 916 hdd_err("HDD context is NULL"); 917 return QDF_STATUS_E_FAILURE; 918 } 919 920 freq = cds_chan_to_freq(dfs_info.channel); 921 922 switch (event) { 923 case eSAP_DFS_CAC_START: 924 index = 925 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX; 926 data_size = sizeof(uint32_t); 927 break; 928 case eSAP_DFS_CAC_END: 929 index = 930 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX; 931 data_size = sizeof(uint32_t); 932 break; 933 case eSAP_DFS_RADAR_DETECT: 934 index = 935 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX; 936 data_size = sizeof(uint32_t); 937 break; 938 default: 939 return QDF_STATUS_E_FAILURE; 940 } 941 942 vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy, 943 wdev, 944 data_size + NLMSG_HDRLEN, 945 index, 946 GFP_KERNEL); 947 if (!vendor_event) { 948 hdd_err("cfg80211_vendor_event_alloc failed for %d", index); 949 return QDF_STATUS_E_FAILURE; 950 } 951 952 ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq); 953 954 if (ret) { 955 hdd_err("NL80211_ATTR_WIPHY_FREQ put fail"); 956 kfree_skb(vendor_event); 957 return QDF_STATUS_E_FAILURE; 958 } 959 960 cfg80211_vendor_event(vendor_event, GFP_KERNEL); 961 return QDF_STATUS_SUCCESS; 962 } 963 964 /** 965 * hdd_send_conditional_chan_switch_status() - Send conditional channel switch 966 * status 967 * @hdd_ctx: HDD context 968 * @wdev: Wireless device structure 969 * @status: Status of conditional channel switch 970 * (0: Success, Non-zero: Failure) 971 * 972 * Sends the status of conditional channel switch to user space. This is named 973 * conditional channel switch because the SAP will move to the provided channel 974 * after some condition (pre-cac) is met. 975 * 976 * Return: None 977 */ 978 static void hdd_send_conditional_chan_switch_status(struct hdd_context *hdd_ctx, 979 struct wireless_dev *wdev, 980 bool status) 981 { 982 struct sk_buff *event; 983 984 hdd_enter_dev(wdev->netdev); 985 986 if (!hdd_ctx) { 987 hdd_err("Invalid HDD context pointer"); 988 return; 989 } 990 991 event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, 992 wdev, sizeof(uint32_t) + NLMSG_HDRLEN, 993 QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX, 994 GFP_KERNEL); 995 if (!event) { 996 hdd_err("cfg80211_vendor_event_alloc failed"); 997 return; 998 } 999 1000 if (nla_put_u32(event, 1001 QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS, 1002 status)) { 1003 hdd_err("nla put failed"); 1004 kfree_skb(event); 1005 return; 1006 } 1007 1008 cfg80211_vendor_event(event, GFP_KERNEL); 1009 } 1010 1011 /** 1012 * wlan_hdd_set_pre_cac_complete_status() - Set pre cac complete status 1013 * @ap_adapter: AP adapter 1014 * @status: Status which can be true or false 1015 * 1016 * Sets the status of pre cac i.e., whether it is complete or not 1017 * 1018 * Return: Zero on success, non-zero on failure 1019 */ 1020 static int wlan_hdd_set_pre_cac_complete_status(struct hdd_adapter *ap_adapter, 1021 bool status) 1022 { 1023 QDF_STATUS ret; 1024 1025 ret = wlan_sap_set_pre_cac_complete_status( 1026 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), status); 1027 if (QDF_IS_STATUS_ERROR(ret)) 1028 return -EINVAL; 1029 1030 return 0; 1031 } 1032 1033 /** 1034 * hdd_check_adapter() - check adapter existing or not 1035 * @adapter: adapter 1036 * 1037 * Check adapter in the hdd global list or not 1038 * 1039 * Return: true if adapter exists. 1040 */ 1041 static bool hdd_check_adapter(struct hdd_adapter *adapter) 1042 { 1043 struct hdd_adapter *temp; 1044 struct hdd_context *hdd_ctx; 1045 1046 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 1047 if (!hdd_ctx) { 1048 hdd_err("HDD context is null"); 1049 return false; 1050 } 1051 hdd_for_each_adapter(hdd_ctx, temp) { 1052 if (temp == adapter) 1053 return true; 1054 } 1055 1056 return false; 1057 } 1058 1059 /** 1060 * __wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure 1061 * @data: AP adapter 1062 * 1063 * Deletes the pre cac adapter 1064 * 1065 * Return: None 1066 */ 1067 static void __wlan_hdd_sap_pre_cac_failure(void *data) 1068 { 1069 struct hdd_adapter *adapter; 1070 struct hdd_context *hdd_ctx; 1071 1072 hdd_enter(); 1073 1074 adapter = (struct hdd_adapter *) data; 1075 if (!adapter || !hdd_check_adapter(adapter) || 1076 adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 1077 hdd_err("SAP Pre CAC adapter invalid"); 1078 return; 1079 } 1080 1081 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1082 if (wlan_hdd_validate_context(hdd_ctx)) { 1083 hdd_err("HDD context is null"); 1084 return; 1085 } 1086 1087 wlan_hdd_release_intf_addr(hdd_ctx, 1088 adapter->mac_addr.bytes); 1089 hdd_stop_adapter_ext(hdd_ctx, adapter, HDD_IN_CAC_WORK_TH_CONTEXT); 1090 hdd_close_adapter(hdd_ctx, adapter, false); 1091 } 1092 1093 /** 1094 * wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure 1095 * @data: AP adapter 1096 * 1097 * Deletes the pre cac adapter 1098 * 1099 * Return: None 1100 */ 1101 void wlan_hdd_sap_pre_cac_failure(void *data) 1102 { 1103 cds_ssr_protect(__func__); 1104 __wlan_hdd_sap_pre_cac_failure(data); 1105 cds_ssr_unprotect(__func__); 1106 } 1107 1108 /** 1109 * wlan_hdd_sap_pre_cac_success() - Process the pre cac result 1110 * @data: AP adapter 1111 * 1112 * Deletes the pre cac adapter and moves the existing SAP to the pre cac 1113 * channel 1114 * 1115 * Return: None 1116 */ 1117 static void wlan_hdd_sap_pre_cac_success(void *data) 1118 { 1119 struct hdd_adapter *adapter, *ap_adapter; 1120 int i; 1121 struct hdd_context *hdd_ctx; 1122 1123 hdd_enter(); 1124 1125 adapter = (struct hdd_adapter *) data; 1126 if (!adapter || !hdd_check_adapter(adapter) || 1127 adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 1128 hdd_err("SAP Pre CAC adapter invalid"); 1129 return; 1130 } 1131 1132 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1133 if (!hdd_ctx) { 1134 hdd_err("HDD context is null"); 1135 return; 1136 } 1137 1138 cds_ssr_protect(__func__); 1139 wlan_hdd_release_intf_addr(hdd_ctx, 1140 adapter->mac_addr.bytes); 1141 hdd_stop_adapter_ext(hdd_ctx, adapter, HDD_IN_CAC_WORK_TH_CONTEXT); 1142 hdd_close_adapter(hdd_ctx, adapter, false); 1143 cds_ssr_unprotect(__func__); 1144 1145 /* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */ 1146 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE); 1147 if (!ap_adapter) { 1148 hdd_err("failed to get SAP adapter, no restart on pre CAC channel"); 1149 return; 1150 } 1151 1152 /* 1153 * Setting of the pre cac complete status will ensure that on channel 1154 * switch to the pre CAC DFS channel, there is no CAC again. 1155 */ 1156 wlan_hdd_set_pre_cac_complete_status(ap_adapter, true); 1157 i = hdd_softap_set_channel_change(ap_adapter->dev, 1158 ap_adapter->pre_cac_chan, 1159 CH_WIDTH_MAX, false); 1160 if (0 != i) { 1161 hdd_err("failed to change channel"); 1162 wlan_hdd_set_pre_cac_complete_status(ap_adapter, false); 1163 } 1164 } 1165 1166 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1167 /** 1168 * hdd_handle_acs_scan_event() - handle acs scan event for SAP 1169 * @sap_event: tpSap_Event 1170 * @adapter: struct hdd_adapter for SAP 1171 * 1172 * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event. 1173 * It will update scan result to cfg80211 and start a timer to flush the 1174 * cached acs scan result. 1175 * 1176 * Return: QDF_STATUS_SUCCESS on success, 1177 * other value on failure 1178 */ 1179 static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event, 1180 struct hdd_adapter *adapter) 1181 { 1182 struct hdd_context *hdd_ctx; 1183 struct sap_acs_scan_complete_event *comp_evt; 1184 QDF_STATUS qdf_status; 1185 int chan_list_size; 1186 1187 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1188 if (!hdd_ctx) { 1189 hdd_err("HDD context is null"); 1190 return QDF_STATUS_E_FAILURE; 1191 } 1192 comp_evt = &sap_event->sapevt.sap_acs_scan_comp; 1193 hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN; 1194 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 1195 qdf_mem_free(hdd_ctx->last_acs_channel_list); 1196 hdd_ctx->last_acs_channel_list = NULL; 1197 hdd_ctx->num_of_channels = 0; 1198 /* cache the previous ACS scan channel list . 1199 * If the following OBSS scan chan list is covered by ACS chan list, 1200 * we can skip OBSS Scan to save SAP starting total time. 1201 */ 1202 if (comp_evt->num_of_channels && comp_evt->channellist) { 1203 chan_list_size = comp_evt->num_of_channels * 1204 sizeof(comp_evt->channellist[0]); 1205 hdd_ctx->last_acs_channel_list = qdf_mem_malloc( 1206 chan_list_size); 1207 if (hdd_ctx->last_acs_channel_list) { 1208 qdf_mem_copy(hdd_ctx->last_acs_channel_list, 1209 comp_evt->channellist, 1210 chan_list_size); 1211 hdd_ctx->num_of_channels = comp_evt->num_of_channels; 1212 } 1213 } 1214 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 1215 1216 hdd_debug("Reusing Last ACS scan result for %d sec", 1217 ACS_SCAN_EXPIRY_TIMEOUT_S); 1218 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer); 1219 qdf_status = qdf_mc_timer_start(&hdd_ctx->skip_acs_scan_timer, 1220 ACS_SCAN_EXPIRY_TIMEOUT_S * 1000); 1221 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1222 hdd_err("Failed to start ACS scan expiry timer"); 1223 return QDF_STATUS_SUCCESS; 1224 } 1225 #else 1226 static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event, 1227 struct hdd_adapter *adapter) 1228 { 1229 return QDF_STATUS_SUCCESS; 1230 } 1231 #endif 1232 1233 /** 1234 * get_max_rate_vht() - calculate max rate for VHT mode 1235 * @nss: num of streams 1236 * @ch_width: channel width 1237 * @sgi: short gi 1238 * @vht_mcs_map: vht mcs map 1239 * 1240 * This function calculate max rate for VHT mode 1241 * 1242 * Return: max rate 1243 */ 1244 static int get_max_rate_vht(int nss, int ch_width, int sgi, int vht_mcs_map) 1245 { 1246 const struct index_vht_data_rate_type *supported_vht_mcs_rate; 1247 enum data_rate_11ac_max_mcs vht_max_mcs; 1248 int maxrate = 0; 1249 int maxidx; 1250 1251 if (nss == 1) { 1252 supported_vht_mcs_rate = supported_vht_mcs_rate_nss1; 1253 } else if (nss == 2) { 1254 supported_vht_mcs_rate = supported_vht_mcs_rate_nss2; 1255 } else { 1256 /* Not Supported */ 1257 hdd_err("nss %d not supported", nss); 1258 return maxrate; 1259 } 1260 1261 vht_max_mcs = 1262 (enum data_rate_11ac_max_mcs) 1263 (vht_mcs_map & DATA_RATE_11AC_MCS_MASK); 1264 1265 if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_7) { 1266 maxidx = 7; 1267 } else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_8) { 1268 maxidx = 8; 1269 } else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_9) { 1270 if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) 1271 /* MCS9 is not valid for VHT20 when nss=1,2 */ 1272 maxidx = 8; 1273 else 1274 maxidx = 9; 1275 } else { 1276 hdd_err("vht mcs map %x not supported", 1277 vht_mcs_map & DATA_RATE_11AC_MCS_MASK); 1278 return maxrate; 1279 } 1280 1281 if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) { 1282 maxrate = 1283 supported_vht_mcs_rate[maxidx].supported_VHT20_rate[sgi]; 1284 } else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) { 1285 maxrate = 1286 supported_vht_mcs_rate[maxidx].supported_VHT40_rate[sgi]; 1287 } else if (ch_width == eHT_CHANNEL_WIDTH_80MHZ) { 1288 maxrate = 1289 supported_vht_mcs_rate[maxidx].supported_VHT80_rate[sgi]; 1290 } else { 1291 hdd_err("ch_width %d not supported", ch_width); 1292 return maxrate; 1293 } 1294 1295 return maxrate; 1296 } 1297 1298 /** 1299 * calculate_max_phy_rate() - calcuate maximum phy rate (100kbps) 1300 * @mode: phymode: Legacy, 11a/b/g, HT, VHT 1301 * @nss: num of stream (maximum num is 2) 1302 * @ch_width: channel width 1303 * @sgi: short gi enabled or not 1304 * @supp_idx: max supported idx 1305 * @ext_idx: max extended idx 1306 * @ht_mcs_idx: max mcs index for HT 1307 * @vht_mcs_map: mcs map for VHT 1308 * 1309 * return: maximum phy rate in 100kbps 1310 */ 1311 static int calcuate_max_phy_rate(int mode, int nss, int ch_width, 1312 int sgi, int supp_idx, int ext_idx, 1313 int ht_mcs_idx, int vht_mcs_map) 1314 { 1315 const struct index_data_rate_type *supported_mcs_rate; 1316 int maxidx = 12; /*default 6M mode*/ 1317 int maxrate = 0, tmprate; 1318 int i; 1319 1320 /* check supported rates */ 1321 if (supp_idx != 0xff && maxidx < supp_idx) 1322 maxidx = supp_idx; 1323 1324 /* check extended rates */ 1325 if (ext_idx != 0xff && maxidx < ext_idx) 1326 maxidx = ext_idx; 1327 1328 for (i = 0; i < QDF_ARRAY_SIZE(supported_data_rate); i++) { 1329 if (supported_data_rate[i].beacon_rate_index == maxidx) 1330 maxrate = supported_data_rate[i].supported_rate[0]; 1331 } 1332 1333 if (mode == SIR_SME_PHY_MODE_HT) { 1334 /* check for HT Mode */ 1335 maxidx = ht_mcs_idx; 1336 if (nss == 1) { 1337 supported_mcs_rate = supported_mcs_rate_nss1; 1338 } else if (nss == 2) { 1339 supported_mcs_rate = supported_mcs_rate_nss2; 1340 } else { 1341 /* Not Supported */ 1342 hdd_err("nss %d not supported", nss); 1343 return maxrate; 1344 } 1345 1346 if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) { 1347 tmprate = sgi ? 1348 supported_mcs_rate[maxidx].supported_rate[2] : 1349 supported_mcs_rate[maxidx].supported_rate[0]; 1350 } else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) { 1351 tmprate = sgi ? 1352 supported_mcs_rate[maxidx].supported_rate[3] : 1353 supported_mcs_rate[maxidx].supported_rate[1]; 1354 } else { 1355 hdd_err("invalid mode %d ch_width %d", 1356 mode, ch_width); 1357 return maxrate; 1358 } 1359 1360 if (maxrate < tmprate) 1361 maxrate = tmprate; 1362 } 1363 1364 if (mode == SIR_SME_PHY_MODE_VHT) { 1365 /* check for VHT Mode */ 1366 tmprate = get_max_rate_vht(nss, ch_width, sgi, vht_mcs_map); 1367 if (maxrate < tmprate) 1368 maxrate = tmprate; 1369 } 1370 1371 return maxrate; 1372 } 1373 1374 /** 1375 * hdd_convert_dot11mode_from_phymode() - get dot11 mode from phymode 1376 * @phymode: phymode of sta associated to SAP 1377 * 1378 * The function is to convert the phymode to corresponding dot11 mode 1379 * 1380 * Return: dot11mode. 1381 */ 1382 1383 1384 static int hdd_convert_dot11mode_from_phymode(int phymode) 1385 { 1386 1387 switch (phymode) { 1388 1389 case MODE_11A: 1390 return QCA_WLAN_802_11_MODE_11A; 1391 1392 case MODE_11B: 1393 return QCA_WLAN_802_11_MODE_11B; 1394 1395 case MODE_11G: 1396 case MODE_11GONLY: 1397 return QCA_WLAN_802_11_MODE_11G; 1398 1399 case MODE_11NA_HT20: 1400 case MODE_11NG_HT20: 1401 case MODE_11NA_HT40: 1402 case MODE_11NG_HT40: 1403 return QCA_WLAN_802_11_MODE_11N; 1404 1405 case MODE_11AC_VHT20: 1406 case MODE_11AC_VHT40: 1407 case MODE_11AC_VHT80: 1408 case MODE_11AC_VHT20_2G: 1409 case MODE_11AC_VHT40_2G: 1410 case MODE_11AC_VHT80_2G: 1411 #ifdef CONFIG_160MHZ_SUPPORT 1412 case MODE_11AC_VHT80_80: 1413 case MODE_11AC_VHT160: 1414 #endif 1415 return QCA_WLAN_802_11_MODE_11AC; 1416 1417 default: 1418 return QCA_WLAN_802_11_MODE_INVALID; 1419 } 1420 1421 } 1422 1423 /** 1424 * hdd_fill_station_info() - fill stainfo once connected 1425 * @stainfo: peer stainfo associate to SAP 1426 * @event: associate/reassociate event received 1427 * 1428 * The function is to update rate stats to stainfo 1429 * 1430 * Return: None. 1431 */ 1432 static void hdd_fill_station_info(struct hdd_adapter *adapter, 1433 tSap_StationAssocReassocCompleteEvent *event) 1434 { 1435 struct hdd_station_info *stainfo; 1436 uint8_t i = 0; 1437 1438 if (event->staId >= WLAN_MAX_STA_COUNT) { 1439 hdd_err("invalid sta id"); 1440 return; 1441 } 1442 1443 stainfo = &adapter->sta_info[event->staId]; 1444 1445 if (!stainfo) { 1446 hdd_err("invalid stainfo"); 1447 return; 1448 } 1449 1450 stainfo->freq = cds_chan_to_freq(event->chan_info.chan_id); 1451 stainfo->sta_type = event->staType; 1452 stainfo->dot11_mode = 1453 hdd_convert_dot11mode_from_phymode(event->chan_info.info); 1454 1455 stainfo->nss = event->chan_info.nss; 1456 stainfo->rate_flags = event->chan_info.rate_flags; 1457 stainfo->ampdu = event->ampdu; 1458 stainfo->sgi_enable = event->sgi_enable; 1459 stainfo->tx_stbc = event->tx_stbc; 1460 stainfo->rx_stbc = event->rx_stbc; 1461 stainfo->ch_width = event->ch_width; 1462 stainfo->mode = event->mode; 1463 stainfo->max_supp_idx = event->max_supp_idx; 1464 stainfo->max_ext_idx = event->max_ext_idx; 1465 stainfo->max_mcs_idx = event->max_mcs_idx; 1466 stainfo->rx_mcs_map = event->rx_mcs_map; 1467 stainfo->tx_mcs_map = event->tx_mcs_map; 1468 stainfo->assoc_ts = qdf_system_ticks(); 1469 stainfo->max_phy_rate = 1470 calcuate_max_phy_rate(stainfo->mode, 1471 stainfo->nss, 1472 stainfo->ch_width, 1473 stainfo->sgi_enable, 1474 stainfo->max_supp_idx, 1475 stainfo->max_ext_idx, 1476 stainfo->max_mcs_idx, 1477 stainfo->rx_mcs_map); 1478 /* expect max_phy_rate report in kbps */ 1479 stainfo->max_phy_rate *= 100; 1480 1481 if (event->vht_caps.present) { 1482 stainfo->vht_present = true; 1483 hdd_copy_vht_caps(&stainfo->vht_caps, &event->vht_caps); 1484 } 1485 if (event->ht_caps.present) { 1486 stainfo->ht_present = true; 1487 hdd_copy_ht_caps(&stainfo->ht_caps, &event->ht_caps); 1488 } 1489 1490 /* Initialize DHCP info */ 1491 stainfo->dhcp_phase = DHCP_PHASE_ACK; 1492 stainfo->dhcp_nego_status = DHCP_NEGO_STOP; 1493 1494 while (i < WLAN_MAX_STA_COUNT) { 1495 if (!qdf_mem_cmp(adapter->cache_sta_info[i].sta_mac.bytes, 1496 event->staMac.bytes, 1497 QDF_MAC_ADDR_SIZE)) { 1498 qdf_mem_zero(&adapter->cache_sta_info[i], 1499 sizeof(*stainfo)); 1500 break; 1501 } 1502 i++; 1503 } 1504 if (i >= WLAN_MAX_STA_COUNT) { 1505 i = 0; 1506 while (i < WLAN_MAX_STA_COUNT) { 1507 if (adapter->cache_sta_info[i].in_use != TRUE) 1508 break; 1509 i++; 1510 } 1511 } 1512 if (i < WLAN_MAX_STA_COUNT) 1513 qdf_mem_copy(&adapter->cache_sta_info[i], 1514 stainfo, sizeof(struct hdd_station_info)); 1515 else 1516 hdd_debug("reached max staid, stainfo can't be cached"); 1517 1518 hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d", 1519 stainfo->ampdu, 1520 stainfo->sgi_enable, 1521 stainfo->tx_stbc, 1522 stainfo->rx_stbc, 1523 stainfo->is_qos_enabled, 1524 stainfo->ch_width, 1525 stainfo->mode, 1526 event->wmmEnabled, 1527 event->chan_info.nss, 1528 event->chan_info.rate_flags, 1529 stainfo->max_phy_rate); 1530 hdd_debug("rate info %d %d %d %d %d", 1531 stainfo->max_supp_idx, 1532 stainfo->max_ext_idx, 1533 stainfo->max_mcs_idx, 1534 stainfo->rx_mcs_map, 1535 stainfo->tx_mcs_map); 1536 } 1537 1538 /** 1539 * hdd_stop_sap_due_to_invalid_channel() - to stop sap in case of invalid chnl 1540 * @work: pointer to work structure 1541 * 1542 * Let's say SAP detected RADAR and trying to select the new channel and if no 1543 * valid channel is found due to none of the channels are available or 1544 * regulatory restriction then SAP needs to be stopped. so SAP state-machine 1545 * will create a work to stop the bss 1546 * 1547 * stop bss has to happen through worker thread because radar indication comes 1548 * from FW through mc thread or main host thread and if same thread is used to 1549 * do stopbss then waiting for stopbss to finish operation will halt mc thread 1550 * to freeze which will trigger stopbss timeout. Instead worker thread can do 1551 * the stopbss operation while mc thread waits for stopbss to finish. 1552 * 1553 * Return: none 1554 */ 1555 static void 1556 hdd_stop_sap_due_to_invalid_channel(struct work_struct *work) 1557 { 1558 /* 1559 * Extract the adapter from work structure. sap_stop_bss_work 1560 * is part of adapter context. 1561 */ 1562 struct hdd_adapter *sap_adapter = container_of(work, 1563 struct hdd_adapter, 1564 sap_stop_bss_work); 1565 cds_ssr_protect(__func__); 1566 if (sap_adapter == NULL) { 1567 cds_err("sap_adapter is NULL, no work needed"); 1568 cds_ssr_unprotect(__func__); 1569 return; 1570 } 1571 hdd_debug("work started for sap session[%d]", sap_adapter->session_id); 1572 wlan_hdd_stop_sap(sap_adapter); 1573 wlansap_set_invalid_session(WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter)); 1574 wlansap_cleanup_cac_timer(WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter)); 1575 hdd_debug("work finished for sap"); 1576 cds_ssr_unprotect(__func__); 1577 } 1578 1579 QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, 1580 void *context) 1581 { 1582 struct hdd_adapter *adapter; 1583 struct hdd_ap_ctx *ap_ctx; 1584 struct hdd_hostapd_state *hostapd_state; 1585 struct net_device *dev; 1586 eSapHddEvent sapEvent; 1587 union iwreq_data wrqu; 1588 uint8_t *we_custom_event_generic = NULL; 1589 int we_event = 0; 1590 int i = 0; 1591 uint8_t staId; 1592 QDF_STATUS qdf_status; 1593 bool bAuthRequired = true; 1594 tpSap_AssocMacAddr pAssocStasArray = NULL; 1595 char unknownSTAEvent[IW_CUSTOM_MAX + 1]; 1596 char maxAssocExceededEvent[IW_CUSTOM_MAX + 1]; 1597 uint8_t we_custom_start_event[64]; 1598 char *startBssEvent; 1599 struct hdd_context *hdd_ctx; 1600 struct iw_michaelmicfailure msg; 1601 uint8_t ignoreCAC = 0; 1602 struct hdd_config *cfg = NULL; 1603 struct wlan_dfs_info dfs_info; 1604 uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN; 1605 struct hdd_adapter *con_sap_adapter; 1606 QDF_STATUS status = QDF_STATUS_SUCCESS; 1607 struct hdd_chan_change_params chan_change; 1608 tSap_StationAssocReassocCompleteEvent *event; 1609 int ret = 0; 1610 struct ch_params sap_ch_param = {0}; 1611 eCsrPhyMode phy_mode; 1612 bool legacy_phymode; 1613 tSap_StationDisassocCompleteEvent *disassoc_comp; 1614 struct hdd_station_info *stainfo; 1615 1616 dev = context; 1617 if (!dev) { 1618 hdd_err("context is null"); 1619 return QDF_STATUS_E_FAILURE; 1620 } 1621 1622 adapter = netdev_priv(dev); 1623 1624 if ((NULL == adapter) || 1625 (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) { 1626 hdd_err("invalid adapter or adapter has invalid magic"); 1627 return QDF_STATUS_E_FAILURE; 1628 } 1629 1630 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 1631 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); 1632 1633 if (!pSapEvent) { 1634 hdd_err("pSapEvent is null"); 1635 return QDF_STATUS_E_FAILURE; 1636 } 1637 1638 sapEvent = pSapEvent->sapHddEventCode; 1639 memset(&wrqu, '\0', sizeof(wrqu)); 1640 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 1641 1642 if (!hdd_ctx) { 1643 hdd_err("HDD context is null"); 1644 return QDF_STATUS_E_FAILURE; 1645 } 1646 1647 cfg = hdd_ctx->config; 1648 1649 if (!cfg) { 1650 hdd_err("HDD config is null"); 1651 return QDF_STATUS_E_FAILURE; 1652 } 1653 1654 dfs_info.channel = ap_ctx->operating_channel; 1655 sme_get_country_code(hdd_ctx->hHal, dfs_info.country_code, &cc_len); 1656 staId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId; 1657 1658 switch (sapEvent) { 1659 case eSAP_START_BSS_EVENT: 1660 hdd_debug("BSS status = %s, channel = %u, bc sta Id = %d", 1661 pSapEvent->sapevt.sapStartBssCompleteEvent. 1662 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS", 1663 pSapEvent->sapevt.sapStartBssCompleteEvent. 1664 operatingChannel, 1665 pSapEvent->sapevt.sapStartBssCompleteEvent.staId); 1666 1667 adapter->session_id = 1668 pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId; 1669 1670 hostapd_state->qdf_status = 1671 pSapEvent->sapevt.sapStartBssCompleteEvent.status; 1672 1673 qdf_atomic_set(&adapter->dfs_radar_found, 0); 1674 wlansap_get_dfs_ignore_cac(hdd_ctx->hHal, &ignoreCAC); 1675 1676 /* DFS requirement: DO NOT transmit during CAC. */ 1677 if ((CHANNEL_STATE_DFS != 1678 wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, 1679 ap_ctx->operating_channel)) 1680 || ignoreCAC 1681 || hdd_ctx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE) 1682 ap_ctx->dfs_cac_block_tx = false; 1683 else 1684 ap_ctx->dfs_cac_block_tx = true; 1685 1686 ucfg_ipa_set_dfs_cac_tx(hdd_ctx->hdd_pdev, 1687 ap_ctx->dfs_cac_block_tx); 1688 1689 hdd_debug("The value of dfs_cac_block_tx[%d] for ApCtx[%pK]:%d", 1690 ap_ctx->dfs_cac_block_tx, ap_ctx, 1691 adapter->session_id); 1692 1693 if (hostapd_state->qdf_status) { 1694 hdd_err("startbss event failed!!"); 1695 /* 1696 * Make sure to set the event before proceeding 1697 * for error handling otherwise caller thread will 1698 * wait till 10 secs and no other connection will 1699 * go through before that. 1700 */ 1701 hostapd_state->bss_state = BSS_STOP; 1702 qdf_event_set(&hostapd_state->qdf_event); 1703 goto stopbss; 1704 } else { 1705 sme_ch_avoid_update_req(hdd_ctx->hHal); 1706 1707 ap_ctx->broadcast_sta_id = 1708 pSapEvent->sapevt.sapStartBssCompleteEvent.staId; 1709 1710 /* @@@ need wep logic here to set privacy bit */ 1711 qdf_status = 1712 hdd_softap_register_bc_sta(adapter, 1713 ap_ctx->privacy); 1714 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1715 hdd_warn("Failed to register BC STA %d", 1716 qdf_status); 1717 hdd_stop_bss_link(adapter); 1718 } 1719 } 1720 1721 if (ucfg_ipa_is_enabled()) { 1722 status = ucfg_ipa_wlan_evt(hdd_ctx->hdd_pdev, 1723 adapter->dev, adapter->device_mode, 1724 ap_ctx->broadcast_sta_id, 1725 adapter->session_id, 1726 WLAN_IPA_AP_CONNECT, 1727 adapter->dev->dev_addr); 1728 if (status) 1729 hdd_err("WLAN_AP_CONNECT event failed"); 1730 } 1731 1732 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 1733 wlan_hdd_auto_shutdown_enable(hdd_ctx, true); 1734 #endif 1735 ap_ctx->operating_channel = 1736 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel; 1737 1738 hdd_hostapd_channel_prevent_suspend(adapter, 1739 ap_ctx->operating_channel); 1740 1741 hostapd_state->bss_state = BSS_START; 1742 1743 /* Set default key index */ 1744 hdd_debug("default key index %hu", ap_ctx->wep_def_key_idx); 1745 1746 sme_roam_set_default_key_index( 1747 WLAN_HDD_GET_HAL_CTX(adapter), 1748 adapter->session_id, 1749 ap_ctx->wep_def_key_idx); 1750 1751 /* Set group key / WEP key every time when BSS is restarted */ 1752 if (ap_ctx->group_key.keyLength) { 1753 status = wlansap_set_key_sta( 1754 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 1755 &ap_ctx->group_key); 1756 if (!QDF_IS_STATUS_SUCCESS(status)) 1757 hdd_err("wlansap_set_key_sta failed"); 1758 } else { 1759 for (i = 0; i < CSR_MAX_NUM_KEY; i++) { 1760 if (!ap_ctx->wep_key[i].keyLength) 1761 continue; 1762 1763 status = wlansap_set_key_sta( 1764 WLAN_HDD_GET_SAP_CTX_PTR 1765 (adapter), 1766 &ap_ctx->wep_key[i]); 1767 if (!QDF_IS_STATUS_SUCCESS(status)) 1768 hdd_err("set_key failed idx: %d", i); 1769 } 1770 } 1771 1772 /* Fill the params for sending IWEVCUSTOM Event 1773 * with SOFTAP.enabled 1774 */ 1775 startBssEvent = "SOFTAP.enabled"; 1776 memset(&we_custom_start_event, '\0', 1777 sizeof(we_custom_start_event)); 1778 memcpy(&we_custom_start_event, startBssEvent, 1779 strlen(startBssEvent)); 1780 memset(&wrqu, 0, sizeof(wrqu)); 1781 wrqu.data.length = strlen(startBssEvent); 1782 we_event = IWEVCUSTOM; 1783 we_custom_event_generic = we_custom_start_event; 1784 hdd_ipa_set_tx_flow_info(); 1785 1786 hdd_debug("check for SAP restart"); 1787 policy_mgr_check_concurrent_intf_and_restart_sap( 1788 hdd_ctx->hdd_psoc); 1789 1790 if (policy_mgr_is_hw_mode_change_after_vdev_up( 1791 hdd_ctx->hdd_psoc)) { 1792 hdd_debug("check for possible hw mode change"); 1793 status = policy_mgr_set_hw_mode_on_channel_switch( 1794 hdd_ctx->hdd_psoc, adapter->session_id); 1795 if (QDF_IS_STATUS_ERROR(status)) 1796 hdd_debug("set hw mode change not done"); 1797 policy_mgr_set_do_hw_mode_change_flag( 1798 hdd_ctx->hdd_psoc, false); 1799 } 1800 /* 1801 * set this event at the very end because once this events 1802 * get set, caller thread is waiting to do further processing. 1803 * so once this event gets set, current worker thread might get 1804 * pre-empted by caller thread. 1805 */ 1806 qdf_status = qdf_event_set(&hostapd_state->qdf_event); 1807 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1808 hdd_err("qdf_event_set failed! status: %d", qdf_status); 1809 goto stopbss; 1810 } 1811 break; /* Event will be sent after Switch-Case stmt */ 1812 1813 case eSAP_STOP_BSS_EVENT: 1814 hdd_debug("BSS stop status = %s", 1815 pSapEvent->sapevt.sapStopBssCompleteEvent. 1816 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); 1817 1818 hdd_hostapd_channel_allow_suspend(adapter, 1819 ap_ctx->operating_channel); 1820 1821 /* Invalidate the channel info. */ 1822 ap_ctx->operating_channel = 0; 1823 1824 /* reset the dfs_cac_status and dfs_cac_block_tx flag only when 1825 * the last BSS is stopped 1826 */ 1827 con_sap_adapter = hdd_get_con_sap_adapter(adapter, true); 1828 if (!con_sap_adapter) { 1829 ap_ctx->dfs_cac_block_tx = true; 1830 hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; 1831 } 1832 hdd_debug("bss_stop_reason=%d", ap_ctx->bss_stop_reason); 1833 if ((BSS_STOP_DUE_TO_MCC_SCC_SWITCH != 1834 ap_ctx->bss_stop_reason) && 1835 (BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN != 1836 ap_ctx->bss_stop_reason)) { 1837 /* 1838 * when MCC to SCC switching or vendor subcmd 1839 * setting sap config channel happens, key storage 1840 * should not be cleared due to hostapd will not 1841 * repopulate the original keys 1842 */ 1843 ap_ctx->group_key.keyLength = 0; 1844 for (i = 0; i < CSR_MAX_NUM_KEY; i++) 1845 ap_ctx->wep_key[i].keyLength = 0; 1846 } 1847 1848 /* clear the reason code in case BSS is stopped 1849 * in another place 1850 */ 1851 ap_ctx->bss_stop_reason = BSS_STOP_REASON_INVALID; 1852 goto stopbss; 1853 1854 case eSAP_DFS_CAC_START: 1855 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 1856 WLAN_SVC_DFS_CAC_START_IND, 1857 &dfs_info, 1858 sizeof(struct wlan_dfs_info)); 1859 hdd_ctx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS; 1860 if (QDF_STATUS_SUCCESS != 1861 hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_START, 1862 dfs_info, &adapter->wdev)) { 1863 hdd_err("Unable to indicate CAC start NL event"); 1864 } else { 1865 hdd_debug("Sent CAC start to user space"); 1866 } 1867 1868 qdf_atomic_set(&adapter->dfs_radar_found, 0); 1869 break; 1870 case eSAP_DFS_CAC_INTERRUPTED: 1871 /* 1872 * The CAC timer did not run completely and a radar was detected 1873 * during the CAC time. This new state will keep the tx path 1874 * blocked since we do not want any transmission on the DFS 1875 * channel. CAC end will only be reported here since the user 1876 * space applications are waiting on CAC end for their state 1877 * management. 1878 */ 1879 if (QDF_STATUS_SUCCESS != 1880 hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END, 1881 dfs_info, &adapter->wdev)) { 1882 hdd_err("Unable to indicate CAC end (interrupted) event"); 1883 } else { 1884 hdd_debug("Sent CAC end (interrupted) to user space"); 1885 } 1886 break; 1887 case eSAP_DFS_CAC_END: 1888 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 1889 WLAN_SVC_DFS_CAC_END_IND, 1890 &dfs_info, 1891 sizeof(struct wlan_dfs_info)); 1892 ap_ctx->dfs_cac_block_tx = false; 1893 ucfg_ipa_set_dfs_cac_tx(hdd_ctx->hdd_pdev, 1894 ap_ctx->dfs_cac_block_tx); 1895 hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE; 1896 if (QDF_STATUS_SUCCESS != 1897 hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END, 1898 dfs_info, &adapter->wdev)) { 1899 hdd_err("Unable to indicate CAC end NL event"); 1900 } else { 1901 hdd_debug("Sent CAC end to user space"); 1902 } 1903 break; 1904 case eSAP_DFS_RADAR_DETECT: 1905 { 1906 int i; 1907 tsap_config_t *sap_config = 1908 &adapter->session.ap.sap_config; 1909 1910 hdd_dfs_indicate_radar(hdd_ctx); 1911 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 1912 WLAN_SVC_DFS_RADAR_DETECT_IND, 1913 &dfs_info, 1914 sizeof(struct wlan_dfs_info)); 1915 hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; 1916 for (i = 0; i < sap_config->channel_info_count; i++) { 1917 if (sap_config->channel_info[i].ieee_chan_number 1918 == dfs_info.channel) 1919 sap_config->channel_info[i].flags |= 1920 IEEE80211_CHAN_RADAR_DFS; 1921 } 1922 if (QDF_STATUS_SUCCESS != 1923 hdd_send_radar_event(hdd_ctx, eSAP_DFS_RADAR_DETECT, 1924 dfs_info, &adapter->wdev)) { 1925 hdd_err("Unable to indicate Radar detect NL event"); 1926 } else { 1927 hdd_debug("Sent radar detected to user space"); 1928 } 1929 break; 1930 } 1931 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC: 1932 hdd_debug("notification for radar detect during pre cac:%d", 1933 adapter->session_id); 1934 hdd_send_conditional_chan_switch_status(hdd_ctx, 1935 &adapter->wdev, false); 1936 hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; 1937 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work, 1938 wlan_hdd_sap_pre_cac_failure, 1939 (void *)adapter); 1940 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work); 1941 break; 1942 case eSAP_DFS_PRE_CAC_END: 1943 hdd_debug("pre cac end notification received:%d", 1944 adapter->session_id); 1945 hdd_send_conditional_chan_switch_status(hdd_ctx, 1946 &adapter->wdev, true); 1947 ap_ctx->dfs_cac_block_tx = false; 1948 ucfg_ipa_set_dfs_cac_tx(hdd_ctx->hdd_pdev, 1949 ap_ctx->dfs_cac_block_tx); 1950 hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE; 1951 1952 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work, 1953 wlan_hdd_sap_pre_cac_success, 1954 (void *)adapter); 1955 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work); 1956 break; 1957 case eSAP_DFS_NO_AVAILABLE_CHANNEL: 1958 wlan_hdd_send_svc_nlink_msg 1959 (hdd_ctx->radio_index, 1960 WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info, 1961 sizeof(struct wlan_dfs_info)); 1962 break; 1963 1964 case eSAP_STA_SET_KEY_EVENT: 1965 /* TODO: 1966 * forward the message to hostapd once implementation 1967 * is done for now just print 1968 */ 1969 hdd_debug("SET Key: configured status = %s", 1970 pSapEvent->sapevt.sapStationSetKeyCompleteEvent. 1971 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); 1972 return QDF_STATUS_SUCCESS; 1973 case eSAP_STA_MIC_FAILURE_EVENT: 1974 { 1975 memset(&msg, '\0', sizeof(msg)); 1976 msg.src_addr.sa_family = ARPHRD_ETHER; 1977 memcpy(msg.src_addr.sa_data, 1978 &pSapEvent->sapevt.sapStationMICFailureEvent. 1979 staMac, QDF_MAC_ADDR_SIZE); 1980 hdd_debug("MIC MAC " MAC_ADDRESS_STR, 1981 MAC_ADDR_ARRAY(msg.src_addr.sa_data)); 1982 if (pSapEvent->sapevt.sapStationMICFailureEvent. 1983 multicast == true) 1984 msg.flags = IW_MICFAILURE_GROUP; 1985 else 1986 msg.flags = IW_MICFAILURE_PAIRWISE; 1987 memset(&wrqu, 0, sizeof(wrqu)); 1988 wrqu.data.length = sizeof(msg); 1989 we_event = IWEVMICHAELMICFAILURE; 1990 we_custom_event_generic = (uint8_t *) &msg; 1991 } 1992 /* inform mic failure to nl80211 */ 1993 cfg80211_michael_mic_failure(dev, 1994 pSapEvent-> 1995 sapevt.sapStationMICFailureEvent. 1996 staMac.bytes, 1997 ((pSapEvent->sapevt. 1998 sapStationMICFailureEvent. 1999 multicast == 2000 true) ? 2001 NL80211_KEYTYPE_GROUP : 2002 NL80211_KEYTYPE_PAIRWISE), 2003 pSapEvent->sapevt. 2004 sapStationMICFailureEvent.keyId, 2005 pSapEvent->sapevt. 2006 sapStationMICFailureEvent.TSC, 2007 GFP_KERNEL); 2008 break; 2009 2010 case eSAP_STA_ASSOC_EVENT: 2011 case eSAP_STA_REASSOC_EVENT: 2012 event = &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent; 2013 if (eSAP_STATUS_FAILURE == event->status) { 2014 hdd_info("assoc failure: " MAC_ADDRESS_STR, 2015 MAC_ADDR_ARRAY(wrqu.addr.sa_data)); 2016 break; 2017 } 2018 2019 wrqu.addr.sa_family = ARPHRD_ETHER; 2020 memcpy(wrqu.addr.sa_data, 2021 &event->staMac, QDF_MAC_ADDR_SIZE); 2022 hdd_info("associated " MAC_ADDRESS_STR, 2023 MAC_ADDR_ARRAY(wrqu.addr.sa_data)); 2024 we_event = IWEVREGISTERED; 2025 2026 if ((eCSR_ENCRYPT_TYPE_NONE == ap_ctx->encryption_type) || 2027 (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == 2028 ap_ctx->encryption_type) 2029 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == 2030 ap_ctx->encryption_type)) { 2031 bAuthRequired = false; 2032 } 2033 2034 if (bAuthRequired) { 2035 qdf_status = hdd_softap_register_sta( 2036 adapter, 2037 true, 2038 ap_ctx->privacy, 2039 event->staId, 2040 (struct qdf_mac_addr *) 2041 wrqu.addr.sa_data, 2042 event->wmmEnabled); 2043 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 2044 hdd_err("Failed to register STA %d " 2045 MAC_ADDRESS_STR "", qdf_status, 2046 MAC_ADDR_ARRAY(wrqu.addr.sa_data)); 2047 } else { 2048 qdf_status = hdd_softap_register_sta( 2049 adapter, 2050 false, 2051 ap_ctx->privacy, 2052 event->staId, 2053 (struct qdf_mac_addr *) 2054 wrqu.addr.sa_data, 2055 event->wmmEnabled); 2056 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 2057 hdd_err("Failed to register STA %d " 2058 MAC_ADDRESS_STR "", qdf_status, 2059 MAC_ADDR_ARRAY(wrqu.addr.sa_data)); 2060 } 2061 2062 staId = event->staId; 2063 if (QDF_IS_STATUS_SUCCESS(qdf_status)) 2064 hdd_fill_station_info(adapter, event); 2065 2066 adapter->sta_info[staId].ecsa_capable = event->ecsa_capable; 2067 2068 if (ucfg_ipa_is_enabled()) { 2069 status = ucfg_ipa_wlan_evt(hdd_ctx->hdd_pdev, 2070 adapter->dev, 2071 adapter->device_mode, 2072 event->staId, 2073 adapter->session_id, 2074 WLAN_IPA_CLIENT_CONNECT_EX, 2075 event->staMac.bytes); 2076 if (status) 2077 hdd_err("WLAN_CLIENT_CONNECT_EX event failed"); 2078 } 2079 2080 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD, 2081 adapter->session_id, 2082 QDF_TRACE_DEFAULT_PDEV_ID, 2083 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC)); 2084 2085 #ifdef MSM_PLATFORM 2086 /* start timer in sap/p2p_go */ 2087 if (ap_ctx->ap_active == false) { 2088 spin_lock_bh(&hdd_ctx->bus_bw_lock); 2089 adapter->prev_tx_packets = 2090 adapter->stats.tx_packets; 2091 adapter->prev_rx_packets = 2092 adapter->stats.rx_packets; 2093 2094 cdp_get_intra_bss_fwd_pkts_count( 2095 cds_get_context(QDF_MODULE_ID_SOC), 2096 adapter->session_id, 2097 &adapter->prev_fwd_tx_packets, 2098 &adapter->prev_fwd_rx_packets); 2099 2100 spin_unlock_bh(&hdd_ctx->bus_bw_lock); 2101 hdd_bus_bw_compute_timer_start(hdd_ctx); 2102 } 2103 #endif 2104 ap_ctx->ap_active = true; 2105 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 2106 wlan_hdd_auto_shutdown_enable(hdd_ctx, false); 2107 #endif 2108 cds_host_diag_log_work(&hdd_ctx->sap_wake_lock, 2109 HDD_SAP_WAKE_LOCK_DURATION, 2110 WIFI_POWER_EVENT_WAKELOCK_SAP); 2111 qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock, 2112 HDD_SAP_WAKE_LOCK_DURATION); 2113 { 2114 struct station_info *sta_info; 2115 uint16_t iesLen = event->iesLen; 2116 2117 sta_info = qdf_mem_malloc(sizeof(*sta_info)); 2118 if (!sta_info) { 2119 hdd_err("Failed to allocate station info"); 2120 return QDF_STATUS_E_FAILURE; 2121 } 2122 if (iesLen <= MAX_ASSOC_IND_IE_LEN) { 2123 sta_info->assoc_req_ies = 2124 (const u8 *)&event->ies[0]; 2125 sta_info->assoc_req_ies_len = iesLen; 2126 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) 2127 /* 2128 * After Kernel 4.0, it's no longer need to set 2129 * STATION_INFO_ASSOC_REQ_IES flag, as it 2130 * changed to use assoc_req_ies_len length to 2131 * check the existence of request IE. 2132 */ 2133 sta_info->filled |= STATION_INFO_ASSOC_REQ_IES; 2134 #endif 2135 cfg80211_new_sta(dev, 2136 (const u8 *)&event->staMac.bytes[0], 2137 sta_info, GFP_KERNEL); 2138 } else { 2139 hdd_err("Assoc Ie length is too long"); 2140 } 2141 qdf_mem_free(sta_info); 2142 } 2143 /* Lets abort scan to ensure smooth authentication for client */ 2144 if (ucfg_scan_get_vdev_status(adapter->hdd_vdev) != 2145 SCAN_NOT_IN_PROGRESS) { 2146 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID, 2147 adapter->session_id, INVALID_SCAN_ID, false); 2148 } 2149 if (adapter->device_mode == QDF_P2P_GO_MODE) { 2150 /* send peer status indication to oem app */ 2151 hdd_send_peer_status_ind_to_app( 2152 &event->staMac, 2153 ePeerConnected, 2154 event->timingMeasCap, 2155 adapter->session_id, 2156 &event->chan_info, 2157 adapter->device_mode); 2158 } 2159 2160 ret = hdd_objmgr_add_peer_object( 2161 adapter->hdd_vdev, 2162 adapter->device_mode, 2163 event->staMac.bytes, 2164 (adapter->sta_info[event->staId].sta_type 2165 == eSTA_TYPE_P2P_CLI)); 2166 if (ret) 2167 hdd_err("Peer object "MAC_ADDRESS_STR" add fails!", 2168 MAC_ADDR_ARRAY(event->staMac.bytes)); 2169 2170 hdd_green_ap_add_sta(hdd_ctx); 2171 break; 2172 2173 case eSAP_STA_DISASSOC_EVENT: 2174 disassoc_comp = 2175 &pSapEvent->sapevt.sapStationDisassocCompleteEvent; 2176 memcpy(wrqu.addr.sa_data, 2177 &disassoc_comp->staMac, QDF_MAC_ADDR_SIZE); 2178 2179 stainfo = hdd_get_stainfo(adapter->cache_sta_info, 2180 disassoc_comp->staMac); 2181 if (!stainfo) { 2182 hdd_err("peer " MAC_ADDRESS_STR " not found", 2183 MAC_ADDR_ARRAY(wrqu.addr.sa_data)); 2184 return -EINVAL; 2185 } 2186 hdd_info(" disassociated " MAC_ADDRESS_STR, 2187 MAC_ADDR_ARRAY(wrqu.addr.sa_data)); 2188 2189 stainfo->rssi = disassoc_comp->rssi; 2190 stainfo->tx_rate = disassoc_comp->tx_rate; 2191 stainfo->rx_rate = disassoc_comp->rx_rate; 2192 stainfo->reason_code = disassoc_comp->reason_code; 2193 2194 qdf_status = qdf_event_set(&hostapd_state->qdf_sta_disassoc_event); 2195 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 2196 hdd_err("Station Deauth event Set failed"); 2197 2198 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == 2199 eSAP_USR_INITATED_DISASSOC) 2200 hdd_debug(" User initiated disassociation"); 2201 else 2202 hdd_debug(" MAC initiated disassociation"); 2203 we_event = IWEVEXPIRED; 2204 qdf_status = 2205 hdd_softap_get_sta_id(adapter, 2206 &pSapEvent->sapevt. 2207 sapStationDisassocCompleteEvent.staMac, 2208 &staId); 2209 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2210 hdd_err("Failed to find sta id status: %d", qdf_status); 2211 return QDF_STATUS_E_FAILURE; 2212 } 2213 2214 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD, 2215 adapter->session_id, 2216 QDF_TRACE_DEFAULT_PDEV_ID, 2217 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC)); 2218 2219 /* Send DHCP STOP indication to FW */ 2220 stainfo->dhcp_phase = DHCP_PHASE_ACK; 2221 if (stainfo->dhcp_nego_status == 2222 DHCP_NEGO_IN_PROGRESS) 2223 hdd_post_dhcp_ind(adapter, staId, 2224 WMA_DHCP_STOP_IND); 2225 stainfo->dhcp_nego_status = DHCP_NEGO_STOP; 2226 2227 hdd_softap_deregister_sta(adapter, staId); 2228 2229 ap_ctx->ap_active = false; 2230 spin_lock_bh(&adapter->sta_info_lock); 2231 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { 2232 if (adapter->sta_info[i].in_use 2233 && i != 2234 (WLAN_HDD_GET_AP_CTX_PTR(adapter))-> 2235 broadcast_sta_id) { 2236 ap_ctx->ap_active = true; 2237 break; 2238 } 2239 } 2240 spin_unlock_bh(&adapter->sta_info_lock); 2241 2242 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 2243 wlan_hdd_auto_shutdown_enable(hdd_ctx, true); 2244 #endif 2245 2246 cds_host_diag_log_work(&hdd_ctx->sap_wake_lock, 2247 HDD_SAP_WAKE_LOCK_DURATION, 2248 WIFI_POWER_EVENT_WAKELOCK_SAP); 2249 qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock, 2250 HDD_SAP_CLIENT_DISCONNECT_WAKE_LOCK_DURATION); 2251 cfg80211_del_sta(dev, 2252 (const u8 *)&pSapEvent->sapevt. 2253 sapStationDisassocCompleteEvent.staMac. 2254 bytes[0], GFP_KERNEL); 2255 2256 /* Update the beacon Interval if it is P2P GO */ 2257 qdf_status = policy_mgr_change_mcc_go_beacon_interval( 2258 hdd_ctx->hdd_psoc, adapter->session_id, 2259 adapter->device_mode); 2260 if (QDF_STATUS_SUCCESS != qdf_status) { 2261 hdd_err("Failed to update Beacon interval status: %d", 2262 qdf_status); 2263 } 2264 if (adapter->device_mode == QDF_P2P_GO_MODE) { 2265 /* send peer status indication to oem app */ 2266 hdd_send_peer_status_ind_to_app(&pSapEvent->sapevt. 2267 sapStationDisassocCompleteEvent. 2268 staMac, ePeerDisconnected, 2269 0, 2270 adapter->session_id, 2271 NULL, 2272 adapter->device_mode); 2273 } 2274 #ifdef MSM_PLATFORM 2275 /*stop timer in sap/p2p_go */ 2276 if (ap_ctx->ap_active == false) { 2277 spin_lock_bh(&hdd_ctx->bus_bw_lock); 2278 adapter->prev_tx_packets = 0; 2279 adapter->prev_rx_packets = 0; 2280 adapter->prev_fwd_tx_packets = 0; 2281 adapter->prev_fwd_rx_packets = 0; 2282 spin_unlock_bh(&hdd_ctx->bus_bw_lock); 2283 hdd_bus_bw_compute_timer_try_stop(hdd_ctx); 2284 } 2285 #endif 2286 hdd_green_ap_del_sta(hdd_ctx); 2287 break; 2288 2289 case eSAP_WPS_PBC_PROBE_REQ_EVENT: 2290 hdd_debug("WPS PBC probe req"); 2291 return QDF_STATUS_SUCCESS; 2292 2293 case eSAP_ASSOC_STA_CALLBACK_EVENT: 2294 pAssocStasArray = 2295 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas; 2296 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) { 2297 for (i = 0; 2298 i < 2299 pSapEvent->sapevt.sapAssocStaListEvent. 2300 noOfAssocSta; i++) { 2301 hdd_info("Associated Sta Num %d:assocId=%d, staId=%d, staMac=" 2302 MAC_ADDRESS_STR, i + 1, 2303 pAssocStasArray->assocId, 2304 pAssocStasArray->staId, 2305 MAC_ADDR_ARRAY(pAssocStasArray->staMac. 2306 bytes)); 2307 pAssocStasArray++; 2308 } 2309 } 2310 qdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas); 2311 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL; 2312 return QDF_STATUS_SUCCESS; 2313 case eSAP_UNKNOWN_STA_JOIN: 2314 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, 2315 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x", 2316 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0], 2317 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1], 2318 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2], 2319 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3], 2320 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4], 2321 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]); 2322 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ 2323 wrqu.data.pointer = unknownSTAEvent; 2324 wrqu.data.length = strlen(unknownSTAEvent); 2325 we_custom_event_generic = (uint8_t *) unknownSTAEvent; 2326 hdd_err("%s", unknownSTAEvent); 2327 break; 2328 2329 case eSAP_MAX_ASSOC_EXCEEDED: 2330 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, 2331 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied" 2332 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect" 2333 " one or more devices to enable the new device connection", 2334 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0], 2335 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1], 2336 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2], 2337 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3], 2338 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4], 2339 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr. 2340 bytes[5]); 2341 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ 2342 wrqu.data.pointer = maxAssocExceededEvent; 2343 wrqu.data.length = strlen(maxAssocExceededEvent); 2344 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent; 2345 hdd_debug("%s", maxAssocExceededEvent); 2346 break; 2347 case eSAP_STA_ASSOC_IND: 2348 return QDF_STATUS_SUCCESS; 2349 2350 case eSAP_DISCONNECT_ALL_P2P_CLIENT: 2351 hdd_clear_all_sta(adapter); 2352 return QDF_STATUS_SUCCESS; 2353 2354 case eSAP_MAC_TRIG_STOP_BSS_EVENT: 2355 ret = hdd_stop_bss_link(adapter); 2356 if (ret) 2357 hdd_warn("hdd_stop_bss_link failed %d", ret); 2358 return QDF_STATUS_SUCCESS; 2359 2360 case eSAP_CHANNEL_CHANGE_EVENT: 2361 hdd_debug("Received eSAP_CHANNEL_CHANGE_EVENT event"); 2362 if (hostapd_state->bss_state != BSS_STOP) { 2363 /* Prevent suspend for new channel */ 2364 hdd_hostapd_channel_prevent_suspend(adapter, 2365 pSapEvent->sapevt.sap_ch_selected.pri_ch); 2366 /* Allow suspend for old channel */ 2367 hdd_hostapd_channel_allow_suspend(adapter, 2368 ap_ctx->operating_channel); 2369 } 2370 /* SME/PE is already updated for new operation 2371 * channel. So update HDD layer also here. This 2372 * resolves issue in AP-AP mode where AP1 channel is 2373 * changed due to RADAR then CAC is going on and 2374 * START_BSS on new channel has not come to HDD. At 2375 * this case if AP2 is started it needs current 2376 * operation channel for MCC DFS restriction 2377 */ 2378 ap_ctx->operating_channel = 2379 pSapEvent->sapevt.sap_ch_selected.pri_ch; 2380 ap_ctx->sap_config.acs_cfg.pri_ch = 2381 pSapEvent->sapevt.sap_ch_selected.pri_ch; 2382 ap_ctx->sap_config.acs_cfg.ht_sec_ch = 2383 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch; 2384 ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch = 2385 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch; 2386 ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch = 2387 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch; 2388 ap_ctx->sap_config.acs_cfg.ch_width = 2389 pSapEvent->sapevt.sap_ch_selected.ch_width; 2390 2391 sap_ch_param.ch_width = 2392 pSapEvent->sapevt.sap_ch_selected.ch_width; 2393 sap_ch_param.center_freq_seg0 = 2394 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch; 2395 sap_ch_param.center_freq_seg1 = 2396 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch; 2397 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, 2398 pSapEvent->sapevt.sap_ch_selected.pri_ch, 2399 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch, 2400 &sap_ch_param); 2401 2402 phy_mode = wlan_sap_get_phymode( 2403 WLAN_HDD_GET_SAP_CTX_PTR(adapter)); 2404 2405 switch (phy_mode) { 2406 case eCSR_DOT11_MODE_11n: 2407 case eCSR_DOT11_MODE_11n_ONLY: 2408 case eCSR_DOT11_MODE_11ac: 2409 case eCSR_DOT11_MODE_11ac_ONLY: 2410 legacy_phymode = false; 2411 break; 2412 default: 2413 legacy_phymode = true; 2414 break; 2415 } 2416 2417 chan_change.chan = 2418 pSapEvent->sapevt.sap_ch_selected.pri_ch; 2419 chan_change.chan_params.ch_width = 2420 pSapEvent->sapevt.sap_ch_selected.ch_width; 2421 chan_change.chan_params.sec_ch_offset = 2422 sap_ch_param.sec_ch_offset; 2423 chan_change.chan_params.center_freq_seg0 = 2424 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch; 2425 chan_change.chan_params.center_freq_seg1 = 2426 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch; 2427 2428 return hdd_chan_change_notify(adapter, dev, 2429 chan_change, legacy_phymode); 2430 case eSAP_ACS_SCAN_SUCCESS_EVENT: 2431 return hdd_handle_acs_scan_event(pSapEvent, adapter); 2432 2433 case eSAP_ACS_CHANNEL_SELECTED: 2434 hdd_debug("ACS Completed for wlan%d", 2435 adapter->dev->ifindex); 2436 clear_bit(ACS_PENDING, &adapter->event_flags); 2437 clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags); 2438 ap_ctx->sap_config.acs_cfg.pri_ch = 2439 pSapEvent->sapevt.sap_ch_selected.pri_ch; 2440 ap_ctx->sap_config.acs_cfg.ht_sec_ch = 2441 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch; 2442 ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch = 2443 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch; 2444 ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch = 2445 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch; 2446 ap_ctx->sap_config.acs_cfg.ch_width = 2447 pSapEvent->sapevt.sap_ch_selected.ch_width; 2448 wlan_hdd_cfg80211_acs_ch_select_evt(adapter); 2449 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); 2450 return QDF_STATUS_SUCCESS; 2451 case eSAP_ECSA_CHANGE_CHAN_IND: 2452 hdd_debug("Channel change indication from peer for channel %d", 2453 pSapEvent->sapevt.sap_chan_cng_ind.new_chan); 2454 if (hdd_softap_set_channel_change(dev, 2455 pSapEvent->sapevt.sap_chan_cng_ind.new_chan, 2456 CH_WIDTH_MAX, false)) 2457 return QDF_STATUS_E_FAILURE; 2458 else 2459 return QDF_STATUS_SUCCESS; 2460 2461 case eSAP_DFS_NEXT_CHANNEL_REQ: 2462 hdd_debug("Sending next channel query to userspace"); 2463 hdd_update_acs_timer_reason(adapter, 2464 QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS); 2465 return QDF_STATUS_SUCCESS; 2466 2467 case eSAP_STOP_BSS_DUE_TO_NO_CHNL: 2468 hdd_debug("Stop sap session[%d]", 2469 adapter->session_id); 2470 INIT_WORK(&adapter->sap_stop_bss_work, 2471 hdd_stop_sap_due_to_invalid_channel); 2472 schedule_work(&adapter->sap_stop_bss_work); 2473 return QDF_STATUS_SUCCESS; 2474 2475 default: 2476 hdd_debug("SAP message is not handled"); 2477 goto stopbss; 2478 return QDF_STATUS_SUCCESS; 2479 } 2480 wireless_send_event(dev, we_event, &wrqu, 2481 (char *)we_custom_event_generic); 2482 2483 return QDF_STATUS_SUCCESS; 2484 2485 stopbss: 2486 { 2487 uint8_t we_custom_event[64]; 2488 char *stopBssEvent = "STOP-BSS.response"; /* 17 */ 2489 int event_len = strlen(stopBssEvent); 2490 2491 hdd_debug("BSS stop status = %s", 2492 pSapEvent->sapevt.sapStopBssCompleteEvent.status ? 2493 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); 2494 2495 /* Change the BSS state now since, as we are shutting 2496 * things down, we don't want interfaces to become 2497 * re-enabled 2498 */ 2499 hostapd_state->bss_state = BSS_STOP; 2500 2501 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 2502 wlan_hdd_auto_shutdown_enable(hdd_ctx, true); 2503 #endif 2504 2505 /* Stop the pkts from n/w stack as we are going to free all of 2506 * the TX WMM queues for all STAID's 2507 */ 2508 hdd_debug("Disabling queues"); 2509 wlan_hdd_netif_queue_control(adapter, 2510 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 2511 WLAN_CONTROL_PATH); 2512 2513 /* reclaim all resources allocated to the BSS */ 2514 qdf_status = hdd_softap_stop_bss(adapter); 2515 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2516 hdd_warn("hdd_softap_stop_bss failed %d", 2517 qdf_status); 2518 } 2519 2520 /* notify userspace that the BSS has stopped */ 2521 memset(&we_custom_event, '\0', sizeof(we_custom_event)); 2522 memcpy(&we_custom_event, stopBssEvent, event_len); 2523 memset(&wrqu, 0, sizeof(wrqu)); 2524 wrqu.data.length = event_len; 2525 we_event = IWEVCUSTOM; 2526 we_custom_event_generic = we_custom_event; 2527 wireless_send_event(dev, we_event, &wrqu, 2528 (char *)we_custom_event_generic); 2529 2530 /* once the event is set, structure dev/adapter should 2531 * not be touched since they are now subject to being deleted 2532 * by another thread 2533 */ 2534 if (eSAP_STOP_BSS_EVENT == sapEvent) 2535 qdf_event_set(&hostapd_state->qdf_stop_bss_event); 2536 2537 hdd_ipa_set_tx_flow_info(); 2538 } 2539 return QDF_STATUS_SUCCESS; 2540 } 2541 2542 int hdd_softap_unpack_ie(tHalHandle halHandle, 2543 eCsrEncryptionType *pEncryptType, 2544 eCsrEncryptionType *mcEncryptType, 2545 eCsrAuthType *pAuthType, 2546 bool *pMFPCapable, 2547 bool *pMFPRequired, 2548 uint16_t gen_ie_len, uint8_t *gen_ie) 2549 { 2550 uint32_t ret; 2551 uint8_t *pRsnIe; 2552 uint16_t RSNIeLen; 2553 tDot11fIERSN dot11RSNIE = {0}; 2554 tDot11fIEWPA dot11WPAIE = {0}; 2555 2556 if (NULL == halHandle) { 2557 hdd_err("Error haHandle returned NULL"); 2558 return -EINVAL; 2559 } 2560 /* Validity checks */ 2561 if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) 2562 || (gen_ie_len > 2563 QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN))) 2564 return -EINVAL; 2565 /* Type check */ 2566 if (gen_ie[0] == DOT11F_EID_RSN) { 2567 /* Validity checks */ 2568 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) || 2569 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) { 2570 return QDF_STATUS_E_FAILURE; 2571 } 2572 /* Skip past the EID byte and length byte */ 2573 pRsnIe = gen_ie + 2; 2574 RSNIeLen = gen_ie_len - 2; 2575 /* Unpack the RSN IE */ 2576 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN)); 2577 ret = sme_unpack_rsn_ie(halHandle, pRsnIe, RSNIeLen, 2578 &dot11RSNIE, false); 2579 if (DOT11F_FAILED(ret)) { 2580 hdd_err("unpack failed, ret: 0x%x", ret); 2581 return -EINVAL; 2582 } 2583 /* Copy out the encryption and authentication types */ 2584 hdd_debug("pairwise cipher suite count: %d", 2585 dot11RSNIE.pwise_cipher_suite_count); 2586 hdd_debug("authentication suite count: %d", 2587 dot11RSNIE.akm_suite_cnt); 2588 /* 2589 * Here we have followed the apple base code, 2590 * but probably I suspect we can do something different 2591 * dot11RSNIE.akm_suite_cnt 2592 * Just translate the FIRST one 2593 */ 2594 *pAuthType = 2595 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suite[0]); 2596 /* dot11RSNIE.pwise_cipher_suite_count */ 2597 *pEncryptType = 2598 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE. 2599 pwise_cipher_suites[0]); 2600 /* dot11RSNIE.gp_cipher_suite_count */ 2601 *mcEncryptType = 2602 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE. 2603 gp_cipher_suite); 2604 /* Set the PMKSA ID Cache for this interface */ 2605 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80); 2606 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40); 2607 } else if (gen_ie[0] == DOT11F_EID_WPA) { 2608 /* Validity checks */ 2609 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) || 2610 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) { 2611 return QDF_STATUS_E_FAILURE; 2612 } 2613 /* Skip past the EID byte and length byte and 4 byte WiFi OUI */ 2614 pRsnIe = gen_ie + 2 + 4; 2615 RSNIeLen = gen_ie_len - (2 + 4); 2616 /* Unpack the WPA IE */ 2617 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA)); 2618 ret = dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle, 2619 pRsnIe, RSNIeLen, &dot11WPAIE, false); 2620 if (DOT11F_FAILED(ret)) { 2621 hdd_err("unpack failed, ret: 0x%x", ret); 2622 return -EINVAL; 2623 } 2624 /* Copy out the encryption and authentication types */ 2625 hdd_debug("WPA unicast cipher suite count: %d", 2626 dot11WPAIE.unicast_cipher_count); 2627 hdd_debug("WPA authentication suite count: %d", 2628 dot11WPAIE.auth_suite_count); 2629 /* dot11WPAIE.auth_suite_count */ 2630 /* Just translate the FIRST one */ 2631 *pAuthType = 2632 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]); 2633 /* dot11WPAIE.unicast_cipher_count */ 2634 *pEncryptType = 2635 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE. 2636 unicast_ciphers[0]); 2637 /* dot11WPAIE.unicast_cipher_count */ 2638 *mcEncryptType = 2639 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE. 2640 multicast_cipher); 2641 *pMFPCapable = false; 2642 *pMFPRequired = false; 2643 } else { 2644 hdd_err("gen_ie[0]: %d", gen_ie[0]); 2645 return QDF_STATUS_E_FAILURE; 2646 } 2647 return QDF_STATUS_SUCCESS; 2648 } 2649 2650 /** 2651 * hdd_softap_set_channel_change() - 2652 * This function to support SAP channel change with CSA IE 2653 * set in the beacons. 2654 * 2655 * @dev: pointer to the net device. 2656 * @target_channel: target channel number. 2657 * @target_bw: Target bandwidth to move. 2658 * If no bandwidth is specified, the value is CH_WIDTH_MAX 2659 * @forced: Force to switch channel, ignore SCC/MCC check 2660 * 2661 * Return: 0 for success, non zero for failure 2662 */ 2663 int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, 2664 enum phy_ch_width target_bw, bool forced) 2665 { 2666 QDF_STATUS status; 2667 int ret = 0; 2668 struct hdd_adapter *adapter = (netdev_priv(dev)); 2669 struct hdd_context *hdd_ctx = NULL; 2670 struct hdd_adapter *sta_adapter; 2671 struct hdd_station_ctx *sta_ctx; 2672 2673 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 2674 ret = wlan_hdd_validate_context(hdd_ctx); 2675 if (ret) 2676 return ret; 2677 2678 ret = hdd_validate_channel_and_bandwidth(adapter, 2679 target_channel, target_bw); 2680 if (ret) { 2681 hdd_err("Invalid CH and BW combo"); 2682 return ret; 2683 } 2684 2685 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2686 /* 2687 * conc_custom_rule1: 2688 * Force SCC for SAP + STA 2689 * if STA is already connected then we shouldn't allow 2690 * channel switch in SAP interface. 2691 */ 2692 if (sta_adapter && hdd_ctx->config->conc_custom_rule1) { 2693 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter); 2694 if (hdd_conn_is_connected(sta_ctx)) { 2695 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled"); 2696 return -EBUSY; 2697 } 2698 } 2699 2700 /* 2701 * Set the dfs_radar_found flag to mimic channel change 2702 * when a radar is found. This will enable synchronizing 2703 * SAP and HDD states similar to that of radar indication. 2704 * Suspend the netif queues to stop queuing Tx frames 2705 * from upper layers. netif queues will be resumed 2706 * once the channel change is completed and SAP will 2707 * post eSAP_START_BSS_EVENT success event to HDD. 2708 */ 2709 if (qdf_atomic_inc_return(&adapter->dfs_radar_found) > 1) { 2710 hdd_err("Channel switch in progress!!"); 2711 return -EBUSY; 2712 } 2713 2714 /* 2715 * Post the Channel Change request to SAP. 2716 */ 2717 status = wlansap_set_channel_change_with_csa( 2718 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 2719 (uint32_t)target_channel, 2720 target_bw, forced); 2721 2722 if (QDF_STATUS_SUCCESS != status) { 2723 hdd_err("SAP set channel failed for channel: %d, bw: %d", 2724 target_channel, target_bw); 2725 /* 2726 * If channel change command fails then clear the 2727 * radar found flag and also restart the netif 2728 * queues. 2729 */ 2730 qdf_atomic_set(&adapter->dfs_radar_found, 0); 2731 2732 ret = -EINVAL; 2733 } 2734 2735 return ret; 2736 } 2737 2738 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 2739 /** 2740 * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA 2741 * @ap_adapter: HDD adapter 2742 * @target_channel: Channel to which switch must happen 2743 * @target_bw: Bandwidth of the target channel 2744 * @forced: Force to switch channel, ignore SCC/MCC check 2745 * 2746 * Invokes the necessary API to perform channel switch for the SAP or GO 2747 * 2748 * Return: None 2749 */ 2750 void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, 2751 uint32_t target_channel, 2752 uint32_t target_bw, 2753 bool forced) 2754 { 2755 struct net_device *dev = ap_adapter->dev; 2756 int ret; 2757 2758 hdd_enter(); 2759 2760 if (!dev) { 2761 hdd_err("Invalid dev pointer"); 2762 return; 2763 } 2764 2765 ret = hdd_softap_set_channel_change(dev, target_channel, 2766 target_bw, forced); 2767 if (ret) { 2768 hdd_err("channel switch failed"); 2769 return; 2770 } 2771 } 2772 2773 void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, 2774 uint8_t vdev_id, uint32_t channel, 2775 uint32_t channel_bw, 2776 bool forced) 2777 { 2778 struct hdd_adapter *ap_adapter = 2779 wlan_hdd_get_adapter_from_vdev(psoc, vdev_id); 2780 2781 if (!ap_adapter) { 2782 hdd_err("Adapter is NULL"); 2783 return; 2784 } 2785 hdd_sap_restart_with_channel_switch(ap_adapter, channel, 2786 channel_bw, forced); 2787 } 2788 2789 QDF_STATUS wlan_hdd_get_channel_for_sap_restart( 2790 struct wlan_objmgr_psoc *psoc, 2791 uint8_t vdev_id, uint8_t *channel, 2792 uint8_t *sec_ch) 2793 { 2794 tHalHandle hal_handle; 2795 struct hdd_ap_ctx *hdd_ap_ctx; 2796 uint8_t intf_ch = 0; 2797 struct hdd_context *hdd_ctx; 2798 struct hdd_station_ctx *hdd_sta_ctx; 2799 struct hdd_adapter *sta_adapter; 2800 struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev( 2801 psoc, vdev_id); 2802 if (!ap_adapter) { 2803 hdd_err("ap_adapter is NULL"); 2804 return QDF_STATUS_E_FAILURE; 2805 } 2806 2807 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 2808 if (!hdd_ctx) { 2809 hdd_err("hdd_ctx is NULL"); 2810 return QDF_STATUS_E_FAILURE; 2811 } 2812 2813 /* TODO: need work for 3 port case with sta+sta */ 2814 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2815 if (!sta_adapter) { 2816 hdd_err("sta_adapter is NULL"); 2817 return QDF_STATUS_E_FAILURE; 2818 } 2819 2820 if (NULL == channel || NULL == sec_ch) { 2821 hdd_err("Null parameters"); 2822 return QDF_STATUS_E_FAILURE; 2823 } 2824 2825 if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) { 2826 hdd_err("SOFTAP_BSS_STARTED not set"); 2827 return QDF_STATUS_E_FAILURE; 2828 } 2829 2830 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); 2831 hal_handle = WLAN_HDD_GET_HAL_CTX(ap_adapter); 2832 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter); 2833 2834 if (!hal_handle) { 2835 hdd_err("hal_handle is NULL"); 2836 return QDF_STATUS_E_FAILURE; 2837 } 2838 2839 /* 2840 * Check if STA's channel is DFS or passive or part of LTE avoided 2841 * channel list. In that case move SAP to other band if DBS is 2842 * supported, return from here if DBS is not supported. 2843 * Need to take care of 3 port cases with 2 STA iface in future. 2844 */ 2845 intf_ch = wlansap_check_cc_intf(hdd_ap_ctx->sap_context); 2846 hdd_info("intf_ch: %d", intf_ch); 2847 if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION != 2848 hdd_ctx->config->WlanMccToSccSwitchMode) { 2849 if (QDF_IS_STATUS_ERROR( 2850 policy_mgr_valid_sap_conc_channel_check( 2851 hdd_ctx->hdd_psoc, 2852 &intf_ch, 2853 policy_mgr_mode_specific_get_channel( 2854 hdd_ctx->hdd_psoc, PM_SAP_MODE)))) { 2855 hdd_debug("can't move sap to %d", 2856 hdd_sta_ctx->conn_info.operationChannel); 2857 return QDF_STATUS_E_FAILURE; 2858 } 2859 } 2860 2861 if (intf_ch == 0) { 2862 hdd_debug("interface channel is 0"); 2863 return QDF_STATUS_E_FAILURE; 2864 } 2865 2866 hdd_info("SAP restart orig chan: %d, new chan: %d", 2867 hdd_ap_ctx->sap_config.channel, intf_ch); 2868 hdd_ap_ctx->sap_config.channel = intf_ch; 2869 hdd_ap_ctx->sap_config.ch_params.ch_width = 2870 hdd_ap_ctx->sap_config.ch_width_orig; 2871 hdd_ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH; 2872 2873 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, 2874 hdd_ap_ctx->sap_config.channel, 2875 hdd_ap_ctx->sap_config.sec_ch, 2876 &hdd_ap_ctx->sap_config.ch_params); 2877 *channel = hdd_ap_ctx->sap_config.channel; 2878 *sec_ch = hdd_ap_ctx->sap_config.sec_ch; 2879 2880 hdd_info("SAP channel change with CSA/ECSA"); 2881 hdd_sap_restart_chan_switch_cb(psoc, vdev_id, 2882 hdd_ap_ctx->sap_config.channel, 2883 hdd_ap_ctx->sap_config.ch_params.ch_width, false); 2884 2885 return QDF_STATUS_SUCCESS; 2886 } 2887 #endif 2888 2889 static int __iw_softap_set_ini_cfg(struct net_device *dev, 2890 struct iw_request_info *info, 2891 union iwreq_data *wrqu, 2892 char *extra) 2893 { 2894 QDF_STATUS status; 2895 int errno; 2896 struct hdd_adapter *adapter; 2897 struct hdd_context *hdd_ctx; 2898 char *value; 2899 size_t len; 2900 2901 hdd_enter_dev(dev); 2902 2903 adapter = netdev_priv(dev); 2904 errno = hdd_validate_adapter(adapter); 2905 if (errno) 2906 return errno; 2907 2908 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 2909 errno = wlan_hdd_validate_context(hdd_ctx); 2910 if (errno) 2911 return errno; 2912 2913 errno = hdd_check_private_wext_control(hdd_ctx, info); 2914 if (errno) 2915 return errno; 2916 2917 /* ensure null termination by copying into a larger, zeroed buffer */ 2918 len = min_t(size_t, wrqu->data.length, QCSAP_IOCTL_MAX_STR_LEN); 2919 value = qdf_mem_malloc(len + 1); 2920 if (!value) 2921 return -ENOMEM; 2922 2923 qdf_mem_copy(value, extra, len); 2924 hdd_debug("Received data %s", value); 2925 status = hdd_execute_global_config_command(hdd_ctx, value); 2926 qdf_mem_free(value); 2927 2928 hdd_exit(); 2929 2930 return qdf_status_to_os_return(status); 2931 } 2932 2933 int 2934 static iw_softap_set_ini_cfg(struct net_device *dev, 2935 struct iw_request_info *info, 2936 union iwreq_data *wrqu, char *extra) 2937 { 2938 int ret; 2939 2940 cds_ssr_protect(__func__); 2941 ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra); 2942 cds_ssr_unprotect(__func__); 2943 2944 return ret; 2945 } 2946 2947 static int hdd_sap_get_chan_width(struct hdd_adapter *adapter, int *value) 2948 { 2949 struct sap_context *sap_ctx; 2950 struct hdd_hostapd_state *hostapdstate; 2951 2952 hdd_enter(); 2953 hostapdstate = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 2954 2955 if (hostapdstate->bss_state != BSS_START) { 2956 *value = -EINVAL; 2957 return -EINVAL; 2958 } 2959 2960 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); 2961 2962 *value = wlansap_get_chan_width(sap_ctx); 2963 hdd_debug("chan_width = %d", *value); 2964 2965 return 0; 2966 } 2967 2968 int 2969 static __iw_softap_get_ini_cfg(struct net_device *dev, 2970 struct iw_request_info *info, 2971 union iwreq_data *wrqu, char *extra) 2972 { 2973 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 2974 struct hdd_context *hdd_ctx; 2975 int ret; 2976 2977 hdd_enter_dev(dev); 2978 2979 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 2980 ret = wlan_hdd_validate_context(hdd_ctx); 2981 if (ret != 0) 2982 return ret; 2983 2984 ret = hdd_check_private_wext_control(hdd_ctx, info); 2985 if (0 != ret) 2986 return ret; 2987 2988 hdd_debug("Printing CLD global INI Config"); 2989 hdd_cfg_get_global_config(hdd_ctx, extra, QCSAP_IOCTL_MAX_STR_LEN); 2990 wrqu->data.length = strlen(extra) + 1; 2991 2992 return 0; 2993 } 2994 2995 int 2996 static iw_softap_get_ini_cfg(struct net_device *dev, 2997 struct iw_request_info *info, 2998 union iwreq_data *wrqu, char *extra) 2999 { 3000 int ret; 3001 3002 cds_ssr_protect(__func__); 3003 ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra); 3004 cds_ssr_unprotect(__func__); 3005 3006 return ret; 3007 } 3008 3009 /** 3010 * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler 3011 * @dev: device upon which the ioctl was received 3012 * @info: ioctl request information 3013 * @wrqu: ioctl request data 3014 * @extra: ioctl extra data 3015 * 3016 * Return: 0 on success, non-zero on error 3017 */ 3018 static int __iw_softap_set_two_ints_getnone(struct net_device *dev, 3019 struct iw_request_info *info, 3020 union iwreq_data *wrqu, char *extra) 3021 { 3022 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3023 int ret; 3024 int *value = (int *)extra; 3025 int sub_cmd = value[0]; 3026 struct hdd_context *hdd_ctx; 3027 struct cdp_vdev *vdev = NULL; 3028 struct cdp_pdev *pdev = NULL; 3029 void *soc = NULL; 3030 struct cdp_txrx_stats_req req = {0}; 3031 3032 hdd_enter_dev(dev); 3033 3034 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3035 ret = wlan_hdd_validate_context(hdd_ctx); 3036 if (ret != 0) 3037 return ret; 3038 3039 ret = hdd_check_private_wext_control(hdd_ctx, info); 3040 if (0 != ret) 3041 return ret; 3042 3043 switch (sub_cmd) { 3044 case QCSAP_PARAM_SET_TXRX_STATS: 3045 { 3046 ret = cds_get_datapath_handles(&soc, &pdev, &vdev, 3047 adapter->session_id); 3048 if (ret != 0) { 3049 hdd_err("Invalid Handles"); 3050 break; 3051 } 3052 req.stats = value[1]; 3053 req.mac_id = value[2]; 3054 hdd_info("QCSAP_PARAM_SET_TXRX_STATS stats_id: %d mac_id: %d", 3055 req.stats, req.mac_id); 3056 ret = cdp_txrx_stats_request(soc, vdev, &req); 3057 break; 3058 } 3059 3060 /* Firmware debug log */ 3061 case QCSAP_IOCTL_SET_FW_CRASH_INJECT: 3062 ret = hdd_crash_inject(adapter, value[1], value[2]); 3063 break; 3064 3065 case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL: 3066 hdd_set_dump_dp_trace(value[1], value[2]); 3067 break; 3068 3069 case QCSAP_ENABLE_FW_PROFILE: 3070 hdd_debug("QCSAP_ENABLE_FW_PROFILE: %d %d", 3071 value[1], value[2]); 3072 ret = wma_cli_set2_command(adapter->session_id, 3073 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 3074 value[1], value[2], DBG_CMD); 3075 break; 3076 3077 case QCSAP_SET_FW_PROFILE_HIST_INTVL: 3078 hdd_debug("QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d", 3079 value[1], value[2]); 3080 ret = wma_cli_set2_command(adapter->session_id, 3081 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 3082 value[1], value[2], DBG_CMD); 3083 break; 3084 3085 case QCSAP_SET_WLAN_SUSPEND: 3086 hdd_info("SAP unit-test suspend(%d, %d)", value[1], value[2]); 3087 ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev, 3088 value[1], value[2]); 3089 break; 3090 3091 case QCSAP_SET_WLAN_RESUME: 3092 ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev); 3093 break; 3094 3095 default: 3096 hdd_err("Invalid IOCTL command: %d", sub_cmd); 3097 break; 3098 } 3099 3100 return ret; 3101 } 3102 3103 static int iw_softap_set_two_ints_getnone(struct net_device *dev, 3104 struct iw_request_info *info, 3105 union iwreq_data *wrqu, char *extra) 3106 { 3107 int ret; 3108 3109 cds_ssr_protect(__func__); 3110 ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra); 3111 cds_ssr_unprotect(__func__); 3112 3113 return ret; 3114 } 3115 3116 static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size) 3117 { 3118 int i; 3119 uint8_t *macArray; 3120 3121 for (i = 0; i < size; i++) { 3122 macArray = (macList + i)->bytes; 3123 pr_info("ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x\n", 3124 i, MAC_ADDR_ARRAY(macArray)); 3125 } 3126 } 3127 3128 static QDF_STATUS hdd_print_acl(struct hdd_adapter *adapter) 3129 { 3130 eSapMacAddrACL acl_mode; 3131 struct qdf_mac_addr maclist[MAX_ACL_MAC_ADDRESS]; 3132 uint8_t listnum; 3133 struct sap_context *sap_ctx; 3134 3135 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); 3136 qdf_mem_zero(&maclist[0], sizeof(maclist)); 3137 if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(sap_ctx, &acl_mode)) { 3138 pr_info("******** ACL MODE *********\n"); 3139 switch (acl_mode) { 3140 case eSAP_ACCEPT_UNLESS_DENIED: 3141 pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n"); 3142 break; 3143 case eSAP_DENY_UNLESS_ACCEPTED: 3144 pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n"); 3145 break; 3146 case eSAP_SUPPORT_ACCEPT_AND_DENY: 3147 pr_info("ACL Mode = ACCEPT_AND_DENY\n"); 3148 break; 3149 case eSAP_ALLOW_ALL: 3150 pr_info("ACL Mode = ALLOW_ALL\n"); 3151 break; 3152 default: 3153 pr_info("Invalid SAP ACL Mode = %d\n", acl_mode); 3154 return QDF_STATUS_E_FAILURE; 3155 } 3156 } else { 3157 return QDF_STATUS_E_FAILURE; 3158 } 3159 3160 if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(sap_ctx, 3161 &maclist[0], 3162 &listnum)) { 3163 pr_info("******* WHITE LIST ***********\n"); 3164 if (listnum <= MAX_ACL_MAC_ADDRESS) 3165 print_mac_list(&maclist[0], listnum); 3166 } else { 3167 return QDF_STATUS_E_FAILURE; 3168 } 3169 3170 if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(sap_ctx, 3171 &maclist[0], 3172 &listnum)) { 3173 pr_info("******* BLACK LIST ***********\n"); 3174 if (listnum <= MAX_ACL_MAC_ADDRESS) 3175 print_mac_list(&maclist[0], listnum); 3176 } else { 3177 return QDF_STATUS_E_FAILURE; 3178 } 3179 return QDF_STATUS_SUCCESS; 3180 } 3181 3182 /** 3183 * hdd_get_aid_rc() - Get AID and rate code passed from user 3184 * @aid: pointer to AID 3185 * @rc: pointer to rate code 3186 * @set_value: value passed from user 3187 * 3188 * If target is 11ax capable, set_value will have AID left shifted 16 bits 3189 * and 16 bits for rate code. If the target is not 11ax capable, rate code 3190 * will only be 8 bits. 3191 * 3192 * Return: None 3193 */ 3194 static void hdd_get_aid_rc(uint8_t *aid, uint16_t *rc, int set_value) 3195 { 3196 uint8_t rc_bits; 3197 3198 if (sme_is_feature_supported_by_fw(DOT11AX)) 3199 rc_bits = 16; 3200 else 3201 rc_bits = 8; 3202 3203 *aid = set_value >> rc_bits; 3204 *rc = set_value & ((1 << (rc_bits + 1)) - 1); 3205 } 3206 3207 /** 3208 * hdd_set_peer_rate() - set peer rate 3209 * @adapter: adapter being modified 3210 * @set_value: rate code with AID 3211 * 3212 * Return: 0 on success, negative errno on failure 3213 */ 3214 static int hdd_set_peer_rate(struct hdd_adapter *adapter, int set_value) 3215 { 3216 uint8_t aid, *peer_mac; 3217 uint16_t rc; 3218 QDF_STATUS status; 3219 3220 if (adapter->device_mode != QDF_SAP_MODE) { 3221 hdd_err("Invalid devicde mode - %d", adapter->device_mode); 3222 return -EINVAL; 3223 } 3224 3225 hdd_get_aid_rc(&aid, &rc, set_value); 3226 3227 if ((adapter->sta_info[aid].in_use) && 3228 (OL_TXRX_PEER_STATE_CONN == adapter->sta_info[aid].peer_state)) { 3229 peer_mac = 3230 (uint8_t *)&(adapter->sta_info[aid].sta_mac.bytes[0]); 3231 hdd_info("Peer AID: %d MAC_ADDR: "MAC_ADDRESS_STR, 3232 aid, MAC_ADDR_ARRAY(peer_mac)); 3233 } else { 3234 hdd_err("No matching peer found for AID: %d", aid); 3235 return -EINVAL; 3236 } 3237 3238 status = sme_set_peer_param(peer_mac, WMI_PEER_PARAM_FIXED_RATE, 3239 rc, adapter->session_id); 3240 if (status != QDF_STATUS_SUCCESS) { 3241 hdd_err("Failed to set peer fixed rate - status: %d", status); 3242 return -EIO; 3243 } 3244 3245 return 0; 3246 } 3247 3248 int 3249 static __iw_softap_setparam(struct net_device *dev, 3250 struct iw_request_info *info, 3251 union iwreq_data *wrqu, char *extra) 3252 { 3253 struct hdd_adapter *adapter = (netdev_priv(dev)); 3254 tHalHandle hHal; 3255 int *value = (int *)extra; 3256 int sub_cmd = value[0]; 3257 int set_value = value[1]; 3258 QDF_STATUS status; 3259 int ret = 0; 3260 struct hdd_context *hdd_ctx; 3261 3262 hdd_enter_dev(dev); 3263 3264 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3265 ret = wlan_hdd_validate_context(hdd_ctx); 3266 if (0 != ret) 3267 return -EINVAL; 3268 3269 ret = hdd_check_private_wext_control(hdd_ctx, info); 3270 if (0 != ret) 3271 return ret; 3272 3273 hHal = WLAN_HDD_GET_HAL_CTX(adapter); 3274 if (!hHal) { 3275 hdd_err("Hal ctx is null"); 3276 return -EINVAL; 3277 } 3278 3279 switch (sub_cmd) { 3280 case QCASAP_SET_RADAR_DBG: 3281 hdd_debug("QCASAP_SET_RADAR_DBG called with: value: %x", 3282 set_value); 3283 wlan_sap_enable_phy_error_logs(hHal, set_value); 3284 break; 3285 3286 case QCSAP_PARAM_CLR_ACL: 3287 if (QDF_STATUS_SUCCESS != wlansap_clear_acl( 3288 WLAN_HDD_GET_SAP_CTX_PTR(adapter))) { 3289 ret = -EIO; 3290 } 3291 break; 3292 3293 case QCSAP_PARAM_ACL_MODE: 3294 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) || 3295 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) { 3296 hdd_err("Invalid ACL Mode value: %d", set_value); 3297 ret = -EINVAL; 3298 } else { 3299 wlansap_set_acl_mode( 3300 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 3301 set_value); 3302 } 3303 break; 3304 3305 case QCSAP_PARAM_SET_CHANNEL_CHANGE: 3306 if ((QDF_SAP_MODE == adapter->device_mode) || 3307 (QDF_P2P_GO_MODE == adapter->device_mode)) { 3308 hdd_debug("SET Channel Change to new channel= %d", 3309 set_value); 3310 ret = hdd_softap_set_channel_change(dev, set_value, 3311 CH_WIDTH_MAX, 3312 false); 3313 } else { 3314 hdd_err("Channel Change Failed, Device in test mode"); 3315 ret = -EINVAL; 3316 } 3317 break; 3318 case QCSAP_PARAM_CONC_SYSTEM_PREF: 3319 hdd_debug("New preference: %d", set_value); 3320 if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) && 3321 (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) { 3322 hdd_err("Invalid system preference: %d", set_value); 3323 return -EINVAL; 3324 } 3325 /* hdd_ctx, hdd_ctx->config are already checked for null */ 3326 hdd_ctx->config->conc_system_pref = set_value; 3327 break; 3328 case QCSAP_PARAM_MAX_ASSOC: 3329 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) { 3330 hdd_err("Invalid setMaxAssoc value %d", 3331 set_value); 3332 ret = -EINVAL; 3333 } else { 3334 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) { 3335 hdd_warn("setMaxAssoc %d > max allowed %d.", 3336 set_value, 3337 WNI_CFG_ASSOC_STA_LIMIT_STAMAX); 3338 hdd_warn("Setting it to max allowed and continuing"); 3339 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX; 3340 } 3341 status = sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT, 3342 set_value); 3343 if (status != QDF_STATUS_SUCCESS) { 3344 hdd_err("setMaxAssoc failure, status: %d", 3345 status); 3346 ret = -EIO; 3347 } 3348 } 3349 break; 3350 3351 case QCSAP_PARAM_HIDE_SSID: 3352 { 3353 QDF_STATUS status; 3354 3355 status = sme_update_session_param(hHal, 3356 adapter->session_id, 3357 SIR_PARAM_SSID_HIDDEN, set_value); 3358 if (QDF_STATUS_SUCCESS != status) { 3359 hdd_err("QCSAP_PARAM_HIDE_SSID failed"); 3360 return -EIO; 3361 } 3362 break; 3363 } 3364 case QCSAP_PARAM_SET_MC_RATE: 3365 { 3366 tSirRateUpdateInd rateUpdate = {0}; 3367 struct hdd_config *pConfig = hdd_ctx->config; 3368 3369 hdd_debug("MC Target rate %d", set_value); 3370 qdf_copy_macaddr(&rateUpdate.bssid, 3371 &adapter->mac_addr); 3372 rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1; 3373 rateUpdate.dev_mode = adapter->device_mode; 3374 rateUpdate.mcastDataRate24GHz = set_value; 3375 rateUpdate.mcastDataRate24GHzTxFlag = 1; 3376 rateUpdate.mcastDataRate5GHz = set_value; 3377 rateUpdate.bcastDataRate = -1; 3378 status = sme_send_rate_update_ind(hHal, &rateUpdate); 3379 if (QDF_STATUS_SUCCESS != status) { 3380 hdd_err("SET_MC_RATE failed"); 3381 ret = -1; 3382 } 3383 break; 3384 } 3385 3386 case QCSAP_PARAM_SET_TXRX_FW_STATS: 3387 { 3388 hdd_debug("QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value); 3389 ret = wma_cli_set_command(adapter->session_id, 3390 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID, 3391 set_value, VDEV_CMD); 3392 break; 3393 } 3394 3395 /* Firmware debug log */ 3396 case QCSAP_DBGLOG_LOG_LEVEL: 3397 { 3398 hdd_debug("QCSAP_DBGLOG_LOG_LEVEL val %d", set_value); 3399 ret = wma_cli_set_command(adapter->session_id, 3400 WMI_DBGLOG_LOG_LEVEL, 3401 set_value, DBG_CMD); 3402 break; 3403 } 3404 3405 case QCSAP_DBGLOG_VAP_ENABLE: 3406 { 3407 hdd_debug("QCSAP_DBGLOG_VAP_ENABLE val %d", set_value); 3408 ret = wma_cli_set_command(adapter->session_id, 3409 WMI_DBGLOG_VAP_ENABLE, 3410 set_value, DBG_CMD); 3411 break; 3412 } 3413 3414 case QCSAP_DBGLOG_VAP_DISABLE: 3415 { 3416 hdd_debug("QCSAP_DBGLOG_VAP_DISABLE val %d", set_value); 3417 ret = wma_cli_set_command(adapter->session_id, 3418 WMI_DBGLOG_VAP_DISABLE, 3419 set_value, DBG_CMD); 3420 break; 3421 } 3422 3423 case QCSAP_DBGLOG_MODULE_ENABLE: 3424 { 3425 hdd_debug("QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value); 3426 ret = wma_cli_set_command(adapter->session_id, 3427 WMI_DBGLOG_MODULE_ENABLE, 3428 set_value, DBG_CMD); 3429 break; 3430 } 3431 3432 case QCSAP_DBGLOG_MODULE_DISABLE: 3433 { 3434 hdd_debug("QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value); 3435 ret = wma_cli_set_command(adapter->session_id, 3436 WMI_DBGLOG_MODULE_DISABLE, 3437 set_value, DBG_CMD); 3438 break; 3439 } 3440 3441 case QCSAP_DBGLOG_MOD_LOG_LEVEL: 3442 { 3443 hdd_debug("QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value); 3444 ret = wma_cli_set_command(adapter->session_id, 3445 WMI_DBGLOG_MOD_LOG_LEVEL, 3446 set_value, DBG_CMD); 3447 break; 3448 } 3449 3450 case QCSAP_DBGLOG_TYPE: 3451 { 3452 hdd_debug("QCSAP_DBGLOG_TYPE val %d", set_value); 3453 ret = wma_cli_set_command(adapter->session_id, 3454 WMI_DBGLOG_TYPE, 3455 set_value, DBG_CMD); 3456 break; 3457 } 3458 case QCSAP_DBGLOG_REPORT_ENABLE: 3459 { 3460 hdd_debug("QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value); 3461 ret = wma_cli_set_command(adapter->session_id, 3462 WMI_DBGLOG_REPORT_ENABLE, 3463 set_value, DBG_CMD); 3464 break; 3465 } 3466 case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY: 3467 { 3468 wlan_hdd_set_mcc_latency(adapter, set_value); 3469 break; 3470 } 3471 3472 case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA: 3473 { 3474 hdd_debug("iwpriv cmd to set MCC quota value %dms", 3475 set_value); 3476 ret = wlan_hdd_go_set_mcc_p2p_quota(adapter, 3477 set_value); 3478 break; 3479 } 3480 3481 case QCASAP_TXRX_FWSTATS_RESET: 3482 { 3483 hdd_debug("WE_TXRX_FWSTATS_RESET val %d", set_value); 3484 ret = wma_cli_set_command(adapter->session_id, 3485 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID, 3486 set_value, VDEV_CMD); 3487 break; 3488 } 3489 3490 case QCSAP_PARAM_RTSCTS: 3491 { 3492 ret = wma_cli_set_command(adapter->session_id, 3493 WMI_VDEV_PARAM_ENABLE_RTSCTS, 3494 set_value, VDEV_CMD); 3495 if (ret) { 3496 hdd_err("FAILED TO SET RTSCTS at SAP"); 3497 ret = -EIO; 3498 } 3499 break; 3500 } 3501 case QCASAP_SET_11N_RATE: 3502 { 3503 uint8_t preamble = 0, nss = 0, rix = 0; 3504 tsap_config_t *pConfig = 3505 &adapter->session.ap.sap_config; 3506 3507 hdd_debug("SET_HT_RATE val %d", set_value); 3508 3509 if (set_value != 0xff) { 3510 rix = RC_2_RATE_IDX(set_value); 3511 if (set_value & 0x80) { 3512 if (pConfig->SapHw_mode == 3513 eCSR_DOT11_MODE_11b 3514 || pConfig->SapHw_mode == 3515 eCSR_DOT11_MODE_11b_ONLY 3516 || pConfig->SapHw_mode == 3517 eCSR_DOT11_MODE_11g 3518 || pConfig->SapHw_mode == 3519 eCSR_DOT11_MODE_11g_ONLY 3520 || pConfig->SapHw_mode == 3521 eCSR_DOT11_MODE_abg 3522 || pConfig->SapHw_mode == 3523 eCSR_DOT11_MODE_11a) { 3524 hdd_err("Not valid mode for HT"); 3525 ret = -EIO; 3526 break; 3527 } 3528 preamble = WMI_RATE_PREAMBLE_HT; 3529 nss = HT_RC_2_STREAMS(set_value) - 1; 3530 } else if (set_value & 0x10) { 3531 if (pConfig->SapHw_mode == 3532 eCSR_DOT11_MODE_11a) { 3533 hdd_err("Not valid for cck"); 3534 ret = -EIO; 3535 break; 3536 } 3537 preamble = WMI_RATE_PREAMBLE_CCK; 3538 /* Enable Short preamble always 3539 * for CCK except 1mbps 3540 */ 3541 if (rix != 0x3) 3542 rix |= 0x4; 3543 } else { 3544 if (pConfig->SapHw_mode == 3545 eCSR_DOT11_MODE_11b 3546 || pConfig->SapHw_mode == 3547 eCSR_DOT11_MODE_11b_ONLY) { 3548 hdd_err("Not valid for OFDM"); 3549 ret = -EIO; 3550 break; 3551 } 3552 preamble = WMI_RATE_PREAMBLE_OFDM; 3553 } 3554 set_value = hdd_assemble_rate_code(preamble, nss, rix); 3555 } 3556 hdd_debug("SET_HT_RATE val %d rix %d preamble %x nss %d", 3557 set_value, rix, preamble, nss); 3558 ret = wma_cli_set_command(adapter->session_id, 3559 WMI_VDEV_PARAM_FIXED_RATE, 3560 set_value, VDEV_CMD); 3561 break; 3562 } 3563 3564 case QCASAP_SET_VHT_RATE: 3565 { 3566 uint8_t preamble = 0, nss = 0, rix = 0; 3567 tsap_config_t *pConfig = 3568 &adapter->session.ap.sap_config; 3569 3570 if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac && 3571 pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) { 3572 hdd_err("SET_VHT_RATE error: SapHw_mode= 0x%x, ch: %d", 3573 pConfig->SapHw_mode, pConfig->channel); 3574 ret = -EIO; 3575 break; 3576 } 3577 3578 if (set_value != 0xff) { 3579 rix = RC_2_RATE_IDX_11AC(set_value); 3580 preamble = WMI_RATE_PREAMBLE_VHT; 3581 nss = HT_RC_2_STREAMS_11AC(set_value) - 1; 3582 3583 set_value = hdd_assemble_rate_code(preamble, nss, rix); 3584 } 3585 hdd_debug("SET_VHT_RATE val %d rix %d preamble %x nss %d", 3586 set_value, rix, preamble, nss); 3587 3588 ret = wma_cli_set_command(adapter->session_id, 3589 WMI_VDEV_PARAM_FIXED_RATE, 3590 set_value, VDEV_CMD); 3591 break; 3592 } 3593 3594 case QCASAP_SHORT_GI: 3595 { 3596 hdd_debug("QCASAP_SET_SHORT_GI val %d", set_value); 3597 /* 3598 * wma_cli_set_command should be called instead of 3599 * sme_update_ht_config since SGI is used for HT/HE. 3600 * This should be refactored. 3601 * 3602 * SGI is same for 20MHZ and 40MHZ. 3603 */ 3604 ret = sme_update_ht_config(hHal, adapter->session_id, 3605 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ, 3606 set_value); 3607 if (ret) 3608 hdd_err("Failed to set ShortGI value ret: %d", ret); 3609 break; 3610 } 3611 3612 case QCSAP_SET_AMPDU: 3613 { 3614 hdd_debug("QCSAP_SET_AMPDU %d", set_value); 3615 ret = wma_cli_set_command(adapter->session_id, 3616 GEN_VDEV_PARAM_AMPDU, 3617 set_value, GEN_CMD); 3618 break; 3619 } 3620 3621 case QCSAP_SET_AMSDU: 3622 { 3623 hdd_debug("QCSAP_SET_AMSDU %d", set_value); 3624 ret = wma_cli_set_command(adapter->session_id, 3625 GEN_VDEV_PARAM_AMSDU, 3626 set_value, GEN_CMD); 3627 break; 3628 } 3629 case QCSAP_GTX_HT_MCS: 3630 { 3631 hdd_debug("WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value); 3632 ret = wma_cli_set_command(adapter->session_id, 3633 WMI_VDEV_PARAM_GTX_HT_MCS, 3634 set_value, GTX_CMD); 3635 break; 3636 } 3637 3638 case QCSAP_GTX_VHT_MCS: 3639 { 3640 hdd_debug("WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value); 3641 ret = wma_cli_set_command(adapter->session_id, 3642 WMI_VDEV_PARAM_GTX_VHT_MCS, 3643 set_value, GTX_CMD); 3644 break; 3645 } 3646 3647 case QCSAP_GTX_USRCFG: 3648 { 3649 hdd_debug("WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value); 3650 ret = wma_cli_set_command(adapter->session_id, 3651 WMI_VDEV_PARAM_GTX_USR_CFG, 3652 set_value, GTX_CMD); 3653 break; 3654 } 3655 3656 case QCSAP_GTX_THRE: 3657 { 3658 hdd_debug("WMI_VDEV_PARAM_GTX_THRE %d", set_value); 3659 ret = wma_cli_set_command(adapter->session_id, 3660 WMI_VDEV_PARAM_GTX_THRE, 3661 set_value, GTX_CMD); 3662 break; 3663 } 3664 3665 case QCSAP_GTX_MARGIN: 3666 { 3667 hdd_debug("WMI_VDEV_PARAM_GTX_MARGIN %d", set_value); 3668 ret = wma_cli_set_command(adapter->session_id, 3669 WMI_VDEV_PARAM_GTX_MARGIN, 3670 set_value, GTX_CMD); 3671 break; 3672 } 3673 3674 case QCSAP_GTX_STEP: 3675 { 3676 hdd_debug("WMI_VDEV_PARAM_GTX_STEP %d", set_value); 3677 ret = wma_cli_set_command(adapter->session_id, 3678 WMI_VDEV_PARAM_GTX_STEP, 3679 set_value, GTX_CMD); 3680 break; 3681 } 3682 3683 case QCSAP_GTX_MINTPC: 3684 { 3685 hdd_debug("WMI_VDEV_PARAM_GTX_MINTPC %d", set_value); 3686 ret = wma_cli_set_command(adapter->session_id, 3687 WMI_VDEV_PARAM_GTX_MINTPC, 3688 set_value, GTX_CMD); 3689 break; 3690 } 3691 3692 case QCSAP_GTX_BWMASK: 3693 { 3694 hdd_debug("WMI_VDEV_PARAM_GTX_BWMASK %d", set_value); 3695 ret = wma_cli_set_command(adapter->session_id, 3696 WMI_VDEV_PARAM_GTX_BW_MASK, 3697 set_value, GTX_CMD); 3698 break; 3699 } 3700 3701 case QCASAP_SET_TM_LEVEL: 3702 { 3703 hdd_debug("Set Thermal Mitigation Level %d", set_value); 3704 (void)sme_set_thermal_level(hHal, set_value); 3705 break; 3706 } 3707 3708 case QCASAP_SET_DFS_IGNORE_CAC: 3709 { 3710 hdd_debug("Set Dfs ignore CAC %d", set_value); 3711 3712 if (adapter->device_mode != QDF_SAP_MODE) 3713 return -EINVAL; 3714 3715 ret = wlansap_set_dfs_ignore_cac(hHal, set_value); 3716 break; 3717 } 3718 3719 case QCASAP_SET_DFS_TARGET_CHNL: 3720 { 3721 hdd_debug("Set Dfs target channel %d", set_value); 3722 3723 if (adapter->device_mode != QDF_SAP_MODE) 3724 return -EINVAL; 3725 3726 ret = wlansap_set_dfs_target_chnl(hHal, set_value); 3727 break; 3728 } 3729 3730 case QCASAP_SET_HE_BSS_COLOR: 3731 if (adapter->device_mode != QDF_SAP_MODE) 3732 return -EINVAL; 3733 3734 status = sme_set_he_bss_color(hHal, adapter->session_id, 3735 set_value); 3736 if (QDF_STATUS_SUCCESS != status) { 3737 hdd_err("SET_HE_BSS_COLOR failed"); 3738 return -EIO; 3739 } 3740 break; 3741 case QCASAP_SET_DFS_NOL: 3742 wlansap_set_dfs_nol( 3743 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 3744 (eSapDfsNolType) set_value); 3745 break; 3746 3747 case QCASAP_SET_RADAR_CMD: 3748 { 3749 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3750 struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); 3751 uint8_t ch = ap_ctx->operating_channel; 3752 struct wlan_objmgr_pdev *pdev; 3753 struct radar_found_info radar; 3754 3755 hdd_debug("Set QCASAP_SET_RADAR_CMD val %d", set_value); 3756 3757 pdev = hdd_ctx->hdd_pdev; 3758 if (!pdev) { 3759 hdd_err("null pdev"); 3760 return -EINVAL; 3761 } 3762 3763 qdf_mem_zero(&radar, sizeof(radar)); 3764 if (wlan_reg_is_dfs_ch(pdev, ch)) 3765 tgt_dfs_process_radar_ind(pdev, &radar); 3766 else 3767 hdd_err("Ignore set radar, op ch(%d) is not dfs", ch); 3768 3769 break; 3770 } 3771 case QCASAP_TX_CHAINMASK_CMD: 3772 { 3773 hdd_debug("QCASAP_TX_CHAINMASK_CMD val %d", set_value); 3774 ret = wma_cli_set_command(adapter->session_id, 3775 WMI_PDEV_PARAM_TX_CHAIN_MASK, 3776 set_value, PDEV_CMD); 3777 ret = hdd_set_antenna_mode(adapter, hdd_ctx, set_value); 3778 break; 3779 } 3780 3781 case QCASAP_RX_CHAINMASK_CMD: 3782 { 3783 hdd_debug("QCASAP_RX_CHAINMASK_CMD val %d", set_value); 3784 ret = wma_cli_set_command(adapter->session_id, 3785 WMI_PDEV_PARAM_RX_CHAIN_MASK, 3786 set_value, PDEV_CMD); 3787 ret = hdd_set_antenna_mode(adapter, hdd_ctx, set_value); 3788 break; 3789 } 3790 3791 case QCASAP_NSS_CMD: 3792 { 3793 hdd_debug("QCASAP_NSS_CMD val %d", set_value); 3794 ret = wma_cli_set_command(adapter->session_id, 3795 WMI_VDEV_PARAM_NSS, 3796 set_value, VDEV_CMD); 3797 break; 3798 } 3799 3800 case QCSAP_IPA_UC_STAT: 3801 { 3802 /* If input value is non-zero get stats */ 3803 switch (set_value) { 3804 case 1: 3805 ucfg_ipa_uc_stat(hdd_ctx->hdd_pdev); 3806 break; 3807 case 2: 3808 ucfg_ipa_uc_info(hdd_ctx->hdd_pdev); 3809 break; 3810 case 3: 3811 ucfg_ipa_uc_rt_debug_host_dump(hdd_ctx->hdd_pdev); 3812 break; 3813 case 4: 3814 ucfg_ipa_dump_info(hdd_ctx->hdd_pdev); 3815 break; 3816 default: 3817 /* place holder for stats clean up 3818 * Stats clean not implemented yet on FW and IPA 3819 */ 3820 break; 3821 } 3822 return ret; 3823 } 3824 3825 case QCASAP_SET_PHYMODE: 3826 { 3827 struct hdd_context *phddctx = 3828 WLAN_HDD_GET_CTX(adapter); 3829 3830 ret = 3831 wlan_hdd_update_phymode(dev, hHal, set_value, 3832 phddctx); 3833 break; 3834 } 3835 case QCASAP_DUMP_STATS: 3836 { 3837 hdd_debug("QCASAP_DUMP_STATS val %d", set_value); 3838 ret = hdd_wlan_dump_stats(adapter, set_value); 3839 break; 3840 } 3841 case QCASAP_CLEAR_STATS: 3842 { 3843 struct hdd_context *hdd_ctx = 3844 WLAN_HDD_GET_CTX(adapter); 3845 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 3846 3847 hdd_debug("QCASAP_CLEAR_STATS val %d", set_value); 3848 switch (set_value) { 3849 case CDP_HDD_STATS: 3850 memset(&adapter->stats, 0, 3851 sizeof(adapter->stats)); 3852 memset(&adapter->hdd_stats, 0, 3853 sizeof(adapter->hdd_stats)); 3854 break; 3855 case CDP_TXRX_HIST_STATS: 3856 wlan_hdd_clear_tx_rx_histogram(hdd_ctx); 3857 break; 3858 case CDP_HDD_NETIF_OPER_HISTORY: 3859 wlan_hdd_clear_netif_queue_history(hdd_ctx); 3860 break; 3861 case CDP_HIF_STATS: 3862 hdd_clear_hif_stats(); 3863 break; 3864 default: 3865 if (soc) 3866 cdp_clear_stats(soc, set_value); 3867 } 3868 break; 3869 } 3870 case QCSAP_START_FW_PROFILING: 3871 hdd_debug("QCSAP_START_FW_PROFILING %d", set_value); 3872 ret = wma_cli_set_command(adapter->session_id, 3873 WMI_WLAN_PROFILE_TRIGGER_CMDID, 3874 set_value, DBG_CMD); 3875 break; 3876 case QCASAP_PARAM_LDPC: 3877 ret = hdd_set_ldpc(adapter, set_value); 3878 break; 3879 case QCASAP_PARAM_TX_STBC: 3880 ret = hdd_set_tx_stbc(adapter, set_value); 3881 break; 3882 case QCASAP_PARAM_RX_STBC: 3883 ret = hdd_set_rx_stbc(adapter, set_value); 3884 break; 3885 case QCASAP_SET_11AX_RATE: 3886 ret = hdd_set_11ax_rate(adapter, set_value, 3887 &adapter->session.ap. 3888 sap_config); 3889 break; 3890 case QCASAP_SET_PEER_RATE: 3891 ret = hdd_set_peer_rate(adapter, set_value); 3892 break; 3893 case QCASAP_PARAM_DCM: 3894 hdd_debug("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value); 3895 ret = wma_cli_set_command(adapter->session_id, 3896 WMI_VDEV_PARAM_HE_DCM, set_value, 3897 VDEV_CMD); 3898 break; 3899 case QCASAP_PARAM_RANGE_EXT: 3900 hdd_debug("Set WMI_VDEV_PARAM_HE_RANGE_EXT: %d", set_value); 3901 ret = wma_cli_set_command(adapter->session_id, 3902 WMI_VDEV_PARAM_HE_RANGE_EXT, 3903 set_value, VDEV_CMD); 3904 break; 3905 case QCSAP_SET_DEFAULT_AMPDU: 3906 hdd_debug("QCSAP_SET_DEFAULT_AMPDU val %d", set_value); 3907 ret = wma_cli_set_command((int)adapter->session_id, 3908 (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU, 3909 set_value, PDEV_CMD); 3910 break; 3911 case QCSAP_ENABLE_RTS_BURSTING: 3912 hdd_debug("QCSAP_ENABLE_RTS_BURSTING val %d", set_value); 3913 ret = wma_cli_set_command((int)adapter->session_id, 3914 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING, 3915 set_value, PDEV_CMD); 3916 break; 3917 default: 3918 hdd_err("Invalid setparam command %d value %d", 3919 sub_cmd, set_value); 3920 ret = -EINVAL; 3921 break; 3922 } 3923 hdd_exit(); 3924 return ret; 3925 } 3926 3927 /** 3928 * __iw_softap_get_three() - return three value to upper layer. 3929 * @dev: pointer of net_device of this wireless card 3930 * @info: meta data about Request sent 3931 * @wrqu: include request info 3932 * @extra: buf used for in/out 3933 * 3934 * Return: execute result 3935 */ 3936 static int __iw_softap_get_three(struct net_device *dev, 3937 struct iw_request_info *info, 3938 union iwreq_data *wrqu, char *extra) 3939 { 3940 uint32_t *value = (uint32_t *)extra; 3941 uint32_t sub_cmd = value[0]; 3942 int ret = 0; /* success */ 3943 struct hdd_context *hdd_ctx; 3944 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3945 3946 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3947 ret = wlan_hdd_validate_context(hdd_ctx); 3948 if (ret != 0) 3949 return ret; 3950 3951 ret = hdd_check_private_wext_control(hdd_ctx, info); 3952 if (0 != ret) 3953 return ret; 3954 3955 switch (sub_cmd) { 3956 case QCSAP_GET_TSF: 3957 ret = hdd_indicate_tsf(adapter, value, 3); 3958 break; 3959 default: 3960 hdd_err("Invalid getparam command: %d", sub_cmd); 3961 ret = -EINVAL; 3962 break; 3963 } 3964 return ret; 3965 } 3966 3967 3968 /** 3969 * iw_softap_get_three() - return three value to upper layer. 3970 * 3971 * @dev: pointer of net_device of this wireless card 3972 * @info: meta data about Request sent 3973 * @wrqu: include request info 3974 * @extra: buf used for in/Output 3975 * 3976 * Return: execute result 3977 */ 3978 static int iw_softap_get_three(struct net_device *dev, 3979 struct iw_request_info *info, 3980 union iwreq_data *wrqu, char *extra) 3981 { 3982 int ret; 3983 3984 cds_ssr_protect(__func__); 3985 ret = __iw_softap_get_three(dev, info, wrqu, extra); 3986 cds_ssr_unprotect(__func__); 3987 3988 return ret; 3989 } 3990 3991 int 3992 static iw_softap_setparam(struct net_device *dev, 3993 struct iw_request_info *info, 3994 union iwreq_data *wrqu, char *extra) 3995 { 3996 int ret; 3997 3998 cds_ssr_protect(__func__); 3999 ret = __iw_softap_setparam(dev, info, wrqu, extra); 4000 cds_ssr_unprotect(__func__); 4001 4002 return ret; 4003 } 4004 4005 int 4006 static __iw_softap_getparam(struct net_device *dev, 4007 struct iw_request_info *info, 4008 union iwreq_data *wrqu, char *extra) 4009 { 4010 struct hdd_adapter *adapter = (netdev_priv(dev)); 4011 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter); 4012 int *value = (int *)extra; 4013 int sub_cmd = value[0]; 4014 QDF_STATUS status; 4015 int ret; 4016 struct hdd_context *hdd_ctx; 4017 4018 hdd_enter_dev(dev); 4019 4020 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4021 ret = wlan_hdd_validate_context(hdd_ctx); 4022 if (0 != ret) 4023 return ret; 4024 4025 ret = hdd_check_private_wext_control(hdd_ctx, info); 4026 if (0 != ret) 4027 return ret; 4028 4029 switch (sub_cmd) { 4030 case QCSAP_PARAM_MAX_ASSOC: 4031 status = sme_cfg_get_int(hHal, WNI_CFG_ASSOC_STA_LIMIT, 4032 (uint32_t *) value); 4033 if (QDF_STATUS_SUCCESS != status) { 4034 hdd_err("get WNI_CFG_ASSOC_STA_LIMIT failed status: %d", 4035 status); 4036 ret = -EIO; 4037 } 4038 break; 4039 4040 case QCSAP_PARAM_GET_WLAN_DBG: 4041 { 4042 qdf_trace_display(); 4043 *value = 0; 4044 break; 4045 } 4046 4047 case QCSAP_PARAM_RTSCTS: 4048 { 4049 *value = wma_cli_get_command(adapter->session_id, 4050 WMI_VDEV_PARAM_ENABLE_RTSCTS, 4051 VDEV_CMD); 4052 break; 4053 } 4054 4055 case QCASAP_SHORT_GI: 4056 { 4057 *value = wma_cli_get_command(adapter->session_id, 4058 WMI_VDEV_PARAM_SGI, 4059 VDEV_CMD); 4060 break; 4061 } 4062 4063 case QCSAP_GTX_HT_MCS: 4064 { 4065 hdd_debug("GET WMI_VDEV_PARAM_GTX_HT_MCS"); 4066 *value = wma_cli_get_command(adapter->session_id, 4067 WMI_VDEV_PARAM_GTX_HT_MCS, 4068 GTX_CMD); 4069 break; 4070 } 4071 4072 case QCSAP_GTX_VHT_MCS: 4073 { 4074 hdd_debug("GET WMI_VDEV_PARAM_GTX_VHT_MCS"); 4075 *value = wma_cli_get_command(adapter->session_id, 4076 WMI_VDEV_PARAM_GTX_VHT_MCS, 4077 GTX_CMD); 4078 break; 4079 } 4080 4081 case QCSAP_GTX_USRCFG: 4082 { 4083 hdd_debug("GET WMI_VDEV_PARAM_GTX_USR_CFG"); 4084 *value = wma_cli_get_command(adapter->session_id, 4085 WMI_VDEV_PARAM_GTX_USR_CFG, 4086 GTX_CMD); 4087 break; 4088 } 4089 4090 case QCSAP_GTX_THRE: 4091 { 4092 hdd_debug("GET WMI_VDEV_PARAM_GTX_THRE"); 4093 *value = wma_cli_get_command(adapter->session_id, 4094 WMI_VDEV_PARAM_GTX_THRE, 4095 GTX_CMD); 4096 break; 4097 } 4098 4099 case QCSAP_GTX_MARGIN: 4100 { 4101 hdd_debug("GET WMI_VDEV_PARAM_GTX_MARGIN"); 4102 *value = wma_cli_get_command(adapter->session_id, 4103 WMI_VDEV_PARAM_GTX_MARGIN, 4104 GTX_CMD); 4105 break; 4106 } 4107 4108 case QCSAP_GTX_STEP: 4109 { 4110 hdd_debug("GET WMI_VDEV_PARAM_GTX_STEP"); 4111 *value = wma_cli_get_command(adapter->session_id, 4112 WMI_VDEV_PARAM_GTX_STEP, 4113 GTX_CMD); 4114 break; 4115 } 4116 4117 case QCSAP_GTX_MINTPC: 4118 { 4119 hdd_debug("GET WMI_VDEV_PARAM_GTX_MINTPC"); 4120 *value = wma_cli_get_command(adapter->session_id, 4121 WMI_VDEV_PARAM_GTX_MINTPC, 4122 GTX_CMD); 4123 break; 4124 } 4125 4126 case QCSAP_GTX_BWMASK: 4127 { 4128 hdd_debug("GET WMI_VDEV_PARAM_GTX_BW_MASK"); 4129 *value = wma_cli_get_command(adapter->session_id, 4130 WMI_VDEV_PARAM_GTX_BW_MASK, 4131 GTX_CMD); 4132 break; 4133 } 4134 4135 case QCASAP_GET_DFS_NOL: 4136 { 4137 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4138 struct wlan_objmgr_pdev *pdev; 4139 4140 pdev = hdd_ctx->hdd_pdev; 4141 if (!pdev) { 4142 hdd_err("null pdev"); 4143 return -EINVAL; 4144 } 4145 4146 utils_dfs_print_nol_channels(pdev); 4147 } 4148 break; 4149 4150 case QCSAP_GET_ACL: 4151 { 4152 hdd_debug("QCSAP_GET_ACL"); 4153 if (hdd_print_acl(adapter) != 4154 QDF_STATUS_SUCCESS) { 4155 hdd_err("QCSAP_GET_ACL returned Error: not completed"); 4156 } 4157 *value = 0; 4158 break; 4159 } 4160 4161 case QCASAP_TX_CHAINMASK_CMD: 4162 { 4163 hdd_debug("QCASAP_TX_CHAINMASK_CMD"); 4164 *value = wma_cli_get_command(adapter->session_id, 4165 WMI_PDEV_PARAM_TX_CHAIN_MASK, 4166 PDEV_CMD); 4167 break; 4168 } 4169 4170 case QCASAP_RX_CHAINMASK_CMD: 4171 { 4172 hdd_debug("QCASAP_RX_CHAINMASK_CMD"); 4173 *value = wma_cli_get_command(adapter->session_id, 4174 WMI_PDEV_PARAM_RX_CHAIN_MASK, 4175 PDEV_CMD); 4176 break; 4177 } 4178 4179 case QCASAP_NSS_CMD: 4180 { 4181 hdd_debug("QCASAP_NSS_CMD"); 4182 *value = wma_cli_get_command(adapter->session_id, 4183 WMI_VDEV_PARAM_NSS, 4184 VDEV_CMD); 4185 break; 4186 } 4187 case QCSAP_CAP_TSF: 4188 ret = hdd_capture_tsf(adapter, (uint32_t *)value, 1); 4189 break; 4190 case QCASAP_GET_TEMP_CMD: 4191 { 4192 hdd_debug("QCASAP_GET_TEMP_CMD"); 4193 ret = wlan_hdd_get_temperature(adapter, value); 4194 break; 4195 } 4196 case QCSAP_GET_FW_PROFILE_DATA: 4197 hdd_debug("QCSAP_GET_FW_PROFILE_DATA"); 4198 ret = wma_cli_set_command(adapter->session_id, 4199 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 4200 0, DBG_CMD); 4201 break; 4202 case QCASAP_PARAM_LDPC: 4203 { 4204 ret = hdd_get_ldpc(adapter, value); 4205 break; 4206 } 4207 case QCASAP_PARAM_TX_STBC: 4208 { 4209 ret = hdd_get_tx_stbc(adapter, value); 4210 break; 4211 } 4212 case QCASAP_PARAM_RX_STBC: 4213 { 4214 ret = hdd_get_rx_stbc(adapter, value); 4215 break; 4216 } 4217 case QCSAP_PARAM_CHAN_WIDTH: 4218 { 4219 ret = hdd_sap_get_chan_width(adapter, value); 4220 break; 4221 } 4222 case QCASAP_PARAM_DCM: 4223 { 4224 *value = wma_cli_get_command(adapter->session_id, 4225 WMI_VDEV_PARAM_HE_DCM, 4226 VDEV_CMD); 4227 break; 4228 } 4229 case QCASAP_PARAM_RANGE_EXT: 4230 { 4231 *value = wma_cli_get_command(adapter->session_id, 4232 WMI_VDEV_PARAM_HE_RANGE_EXT, 4233 VDEV_CMD); 4234 break; 4235 } 4236 default: 4237 hdd_err("Invalid getparam command: %d", sub_cmd); 4238 ret = -EINVAL; 4239 break; 4240 4241 } 4242 hdd_exit(); 4243 return ret; 4244 } 4245 4246 int 4247 static iw_softap_getparam(struct net_device *dev, 4248 struct iw_request_info *info, 4249 union iwreq_data *wrqu, char *extra) 4250 { 4251 int ret; 4252 4253 cds_ssr_protect(__func__); 4254 ret = __iw_softap_getparam(dev, info, wrqu, extra); 4255 cds_ssr_unprotect(__func__); 4256 4257 return ret; 4258 } 4259 4260 /* Usage: 4261 * BLACK_LIST = 0 4262 * WHITE_LIST = 1 4263 * ADD MAC = 0 4264 * REMOVE MAC = 1 4265 * 4266 * mac addr will be accepted as a 6 octet mac address with each octet 4267 * inputted in hex for e.g. 00:0a:f5:11:22:33 will be represented as 4268 * 0x00 0x0a 0xf5 0x11 0x22 0x33 while using this ioctl 4269 * 4270 * Syntax: 4271 * iwpriv softap.0 modify_acl 4272 * <6 octet mac addr> <list type> <cmd type> 4273 * 4274 * Examples: 4275 * eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list 4276 * iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0 4277 * eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list 4278 * iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1 4279 */ 4280 static 4281 int __iw_softap_modify_acl(struct net_device *dev, 4282 struct iw_request_info *info, 4283 union iwreq_data *wrqu, char *extra) 4284 { 4285 struct hdd_adapter *adapter = (netdev_priv(dev)); 4286 uint8_t *value = (uint8_t *) extra; 4287 uint8_t pPeerStaMac[QDF_MAC_ADDR_SIZE]; 4288 int listType, cmd, i; 4289 int ret; 4290 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4291 struct hdd_context *hdd_ctx; 4292 4293 hdd_enter_dev(dev); 4294 4295 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4296 ret = wlan_hdd_validate_context(hdd_ctx); 4297 if (0 != ret) 4298 return ret; 4299 4300 ret = hdd_check_private_wext_control(hdd_ctx, info); 4301 if (0 != ret) 4302 return ret; 4303 4304 for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) 4305 pPeerStaMac[i] = *(value + i); 4306 4307 listType = (int)(*(value + i)); 4308 i++; 4309 cmd = (int)(*(value + i)); 4310 4311 hdd_debug("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d", 4312 MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd); 4313 4314 qdf_status = wlansap_modify_acl( 4315 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 4316 pPeerStaMac, (eSapACLType) listType, (eSapACLCmdType) cmd); 4317 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4318 hdd_err("Modify ACL failed"); 4319 ret = -EIO; 4320 } 4321 hdd_exit(); 4322 return ret; 4323 } 4324 4325 static 4326 int iw_softap_modify_acl(struct net_device *dev, 4327 struct iw_request_info *info, 4328 union iwreq_data *wrqu, char *extra) 4329 { 4330 int ret; 4331 4332 cds_ssr_protect(__func__); 4333 ret = __iw_softap_modify_acl(dev, info, wrqu, extra); 4334 cds_ssr_unprotect(__func__); 4335 4336 return ret; 4337 } 4338 4339 int 4340 static __iw_softap_getchannel(struct net_device *dev, 4341 struct iw_request_info *info, 4342 union iwreq_data *wrqu, char *extra) 4343 { 4344 struct hdd_adapter *adapter = (netdev_priv(dev)); 4345 struct hdd_context *hdd_ctx; 4346 int *value = (int *)extra; 4347 int ret; 4348 4349 hdd_enter_dev(dev); 4350 4351 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4352 ret = wlan_hdd_validate_context(hdd_ctx); 4353 if (0 != ret) 4354 return ret; 4355 4356 ret = hdd_check_private_wext_control(hdd_ctx, info); 4357 if (0 != ret) 4358 return ret; 4359 4360 *value = 0; 4361 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) 4362 *value = (WLAN_HDD_GET_AP_CTX_PTR( 4363 adapter))->operating_channel; 4364 hdd_exit(); 4365 return 0; 4366 } 4367 4368 int 4369 static iw_softap_getchannel(struct net_device *dev, 4370 struct iw_request_info *info, 4371 union iwreq_data *wrqu, char *extra) 4372 { 4373 int ret; 4374 4375 cds_ssr_protect(__func__); 4376 ret = __iw_softap_getchannel(dev, info, wrqu, extra); 4377 cds_ssr_unprotect(__func__); 4378 4379 return ret; 4380 } 4381 4382 int 4383 static __iw_softap_set_max_tx_power(struct net_device *dev, 4384 struct iw_request_info *info, 4385 union iwreq_data *wrqu, char *extra) 4386 { 4387 struct hdd_adapter *adapter = (netdev_priv(dev)); 4388 struct hdd_context *hdd_ctx; 4389 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter); 4390 int *value = (int *)extra; 4391 int set_value; 4392 int ret; 4393 struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT; 4394 struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BCAST_INIT; 4395 4396 hdd_enter_dev(dev); 4397 4398 if (NULL == value) 4399 return -ENOMEM; 4400 4401 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4402 ret = wlan_hdd_validate_context(hdd_ctx); 4403 if (0 != ret) 4404 return ret; 4405 4406 ret = hdd_check_private_wext_control(hdd_ctx, info); 4407 if (0 != ret) 4408 return ret; 4409 4410 /* Assign correct self MAC address */ 4411 qdf_copy_macaddr(&bssid, &adapter->mac_addr); 4412 qdf_copy_macaddr(&selfMac, &adapter->mac_addr); 4413 4414 set_value = value[0]; 4415 if (QDF_STATUS_SUCCESS != 4416 sme_set_max_tx_power(hHal, bssid, selfMac, set_value)) { 4417 hdd_err("Setting maximum tx power failed"); 4418 return -EIO; 4419 } 4420 hdd_exit(); 4421 return 0; 4422 } 4423 4424 int 4425 static iw_softap_set_max_tx_power(struct net_device *dev, 4426 struct iw_request_info *info, 4427 union iwreq_data *wrqu, char *extra) 4428 { 4429 int ret; 4430 4431 cds_ssr_protect(__func__); 4432 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra); 4433 cds_ssr_unprotect(__func__); 4434 4435 return ret; 4436 } 4437 4438 #ifndef REMOVE_PKT_LOG 4439 int 4440 static __iw_softap_set_pktlog(struct net_device *dev, 4441 struct iw_request_info *info, 4442 union iwreq_data *wrqu, char *extra) 4443 { 4444 struct hdd_adapter *adapter = netdev_priv(dev); 4445 struct hdd_context *hdd_ctx; 4446 int *value = (int *)extra; 4447 int ret; 4448 4449 hdd_enter_dev(dev); 4450 4451 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4452 ret = hdd_check_private_wext_control(hdd_ctx, info); 4453 if (0 != ret) 4454 return ret; 4455 4456 if (wrqu->data.length < 1 || wrqu->data.length > 2) { 4457 hdd_err("pktlog: either 1 or 2 parameters are required"); 4458 return -EINVAL; 4459 } 4460 4461 return hdd_process_pktlog_command(hdd_ctx, value[0], value[1]); 4462 } 4463 4464 int 4465 static iw_softap_set_pktlog(struct net_device *dev, 4466 struct iw_request_info *info, 4467 union iwreq_data *wrqu, char *extra) 4468 { 4469 int ret; 4470 4471 cds_ssr_protect(__func__); 4472 ret = __iw_softap_set_pktlog(dev, info, wrqu, extra); 4473 cds_ssr_unprotect(__func__); 4474 4475 return ret; 4476 } 4477 #else 4478 int 4479 static iw_softap_set_pktlog(struct net_device *dev, 4480 struct iw_request_info *info, 4481 union iwreq_data *wrqu, char *extra) 4482 { 4483 return -EINVAL; 4484 } 4485 #endif 4486 4487 int 4488 static __iw_softap_set_tx_power(struct net_device *dev, 4489 struct iw_request_info *info, 4490 union iwreq_data *wrqu, char *extra) 4491 { 4492 struct hdd_adapter *adapter = (netdev_priv(dev)); 4493 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter); 4494 struct hdd_context *hdd_ctx; 4495 int *value = (int *)extra; 4496 int set_value; 4497 struct qdf_mac_addr bssid; 4498 int ret; 4499 4500 hdd_enter_dev(dev); 4501 4502 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4503 ret = wlan_hdd_validate_context(hdd_ctx); 4504 if (0 != ret) 4505 return ret; 4506 4507 ret = hdd_check_private_wext_control(hdd_ctx, info); 4508 if (0 != ret) 4509 return ret; 4510 4511 qdf_copy_macaddr(&bssid, &adapter->mac_addr); 4512 4513 set_value = value[0]; 4514 if (QDF_STATUS_SUCCESS != 4515 sme_set_tx_power(hHal, adapter->session_id, bssid, 4516 adapter->device_mode, set_value)) { 4517 hdd_err("Setting tx power failed"); 4518 return -EIO; 4519 } 4520 hdd_exit(); 4521 return 0; 4522 } 4523 4524 int 4525 static iw_softap_set_tx_power(struct net_device *dev, 4526 struct iw_request_info *info, 4527 union iwreq_data *wrqu, char *extra) 4528 { 4529 int ret; 4530 4531 cds_ssr_protect(__func__); 4532 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra); 4533 cds_ssr_unprotect(__func__); 4534 4535 return ret; 4536 } 4537 4538 #define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0) 4539 4540 int 4541 static __iw_softap_getassoc_stamacaddr(struct net_device *dev, 4542 struct iw_request_info *info, 4543 union iwreq_data *wrqu, char *extra) 4544 { 4545 struct hdd_adapter *adapter = (netdev_priv(dev)); 4546 struct hdd_station_info *pStaInfo = adapter->sta_info; 4547 struct hdd_context *hdd_ctx; 4548 char *buf; 4549 int cnt = 0; 4550 int left; 4551 int ret; 4552 /* maclist_index must be u32 to match userspace */ 4553 u32 maclist_index; 4554 4555 hdd_enter_dev(dev); 4556 4557 /* 4558 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl 4559 * number, and even numbered iocts are supposed to have "set" 4560 * semantics. Hence the wireless extensions support in the kernel 4561 * won't correctly copy the result to userspace, so the ioctl 4562 * handler itself must copy the data. Output format is 32-bit 4563 * record length, followed by 0 or more 6-byte STA MAC addresses. 4564 * 4565 * Further note that due to the incorrect semantics, the "iwpriv" 4566 * userspace application is unable to correctly invoke this API, 4567 * hence it is not registered in the hostapd_private_args. This 4568 * API can only be invoked by directly invoking the ioctl() system 4569 * call. 4570 */ 4571 4572 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4573 ret = wlan_hdd_validate_context(hdd_ctx); 4574 if (0 != ret) 4575 return ret; 4576 4577 ret = hdd_check_private_wext_control(hdd_ctx, info); 4578 if (0 != ret) 4579 return ret; 4580 4581 /* make sure userspace allocated a reasonable buffer size */ 4582 if (wrqu->data.length < sizeof(maclist_index)) { 4583 hdd_err("invalid userspace buffer"); 4584 return -EINVAL; 4585 } 4586 4587 /* allocate local buffer to build the response */ 4588 buf = qdf_mem_malloc(wrqu->data.length); 4589 if (!buf) { 4590 hdd_err("failed to allocate response buffer"); 4591 return -ENOMEM; 4592 } 4593 4594 /* start indexing beyond where the record count will be written */ 4595 maclist_index = sizeof(maclist_index); 4596 left = wrqu->data.length - maclist_index; 4597 4598 spin_lock_bh(&adapter->sta_info_lock); 4599 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) { 4600 if ((pStaInfo[cnt].in_use) && 4601 (!IS_BROADCAST_MAC(pStaInfo[cnt].sta_mac.bytes))) { 4602 memcpy(&buf[maclist_index], &(pStaInfo[cnt].sta_mac), 4603 QDF_MAC_ADDR_SIZE); 4604 maclist_index += QDF_MAC_ADDR_SIZE; 4605 left -= QDF_MAC_ADDR_SIZE; 4606 } 4607 cnt++; 4608 } 4609 spin_unlock_bh(&adapter->sta_info_lock); 4610 4611 *((u32 *) buf) = maclist_index; 4612 wrqu->data.length = maclist_index; 4613 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) { 4614 hdd_err("failed to copy response to user buffer"); 4615 ret = -EFAULT; 4616 } 4617 qdf_mem_free(buf); 4618 hdd_exit(); 4619 return ret; 4620 } 4621 4622 int 4623 static iw_softap_getassoc_stamacaddr(struct net_device *dev, 4624 struct iw_request_info *info, 4625 union iwreq_data *wrqu, char *extra) 4626 { 4627 int ret; 4628 4629 cds_ssr_protect(__func__); 4630 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra); 4631 cds_ssr_unprotect(__func__); 4632 4633 return ret; 4634 } 4635 4636 /* Usage: 4637 * mac addr will be accepted as a 6 octet mac address with each octet 4638 * inputted in hex for e.g. 00:0a:f5:11:22:33 will be represented as 4639 * 0x00 0x0a 0xf5 0x11 0x22 0x33 while using this ioctl 4640 * 4641 * Syntax: 4642 * iwpriv softap.0 disassoc_sta <6 octet mac address> 4643 * 4644 * e.g. 4645 * disassociate sta with mac addr 00:0a:f5:11:22:33 from softap 4646 * iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33 4647 */ 4648 4649 int 4650 static __iw_softap_disassoc_sta(struct net_device *dev, 4651 struct iw_request_info *info, 4652 union iwreq_data *wrqu, char *extra) 4653 { 4654 struct hdd_adapter *adapter = (netdev_priv(dev)); 4655 struct hdd_context *hdd_ctx; 4656 uint8_t *peerMacAddr; 4657 int ret; 4658 struct csr_del_sta_params del_sta_params; 4659 4660 hdd_enter_dev(dev); 4661 4662 if (!capable(CAP_NET_ADMIN)) { 4663 hdd_err("permission check failed"); 4664 return -EPERM; 4665 } 4666 4667 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4668 ret = wlan_hdd_validate_context(hdd_ctx); 4669 if (0 != ret) 4670 return ret; 4671 4672 ret = hdd_check_private_wext_control(hdd_ctx, info); 4673 if (0 != ret) 4674 return ret; 4675 4676 /* iwpriv tool or framework calls this ioctl with 4677 * data passed in extra (less than 16 octets); 4678 */ 4679 peerMacAddr = (uint8_t *) (extra); 4680 4681 hdd_debug("data " MAC_ADDRESS_STR, 4682 MAC_ADDR_ARRAY(peerMacAddr)); 4683 wlansap_populate_del_sta_params(peerMacAddr, 4684 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, 4685 (SIR_MAC_MGMT_DISASSOC >> 4), 4686 &del_sta_params); 4687 hdd_softap_sta_disassoc(adapter, &del_sta_params); 4688 4689 hdd_exit(); 4690 return 0; 4691 } 4692 4693 int 4694 static iw_softap_disassoc_sta(struct net_device *dev, 4695 struct iw_request_info *info, 4696 union iwreq_data *wrqu, char *extra) 4697 { 4698 int ret; 4699 4700 cds_ssr_protect(__func__); 4701 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra); 4702 cds_ssr_unprotect(__func__); 4703 4704 return ret; 4705 } 4706 4707 /** 4708 * iw_get_char_setnone() - Generic "get char" private ioctl handler 4709 * @dev: device upon which the ioctl was received 4710 * @info: ioctl request information 4711 * @wrqu: ioctl request data 4712 * @extra: ioctl extra data 4713 * 4714 * Return: 0 on success, non-zero on error 4715 */ 4716 static int __iw_get_char_setnone(struct net_device *dev, 4717 struct iw_request_info *info, 4718 union iwreq_data *wrqu, char *extra) 4719 { 4720 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 4721 int ret; 4722 int sub_cmd = wrqu->data.flags; 4723 struct hdd_context *hdd_ctx; 4724 4725 hdd_enter_dev(dev); 4726 4727 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4728 ret = wlan_hdd_validate_context(hdd_ctx); 4729 if (ret != 0) 4730 return ret; 4731 4732 ret = hdd_check_private_wext_control(hdd_ctx, info); 4733 if (0 != ret) 4734 return ret; 4735 4736 switch (sub_cmd) { 4737 case QCSAP_GET_STATS: 4738 hdd_wlan_get_stats(adapter, &(wrqu->data.length), 4739 extra, WE_MAX_STR_LEN); 4740 break; 4741 case QCSAP_LIST_FW_PROFILE: 4742 hdd_wlan_list_fw_profile(&(wrqu->data.length), 4743 extra, WE_MAX_STR_LEN); 4744 break; 4745 } 4746 4747 hdd_exit(); 4748 return ret; 4749 } 4750 4751 static int iw_get_char_setnone(struct net_device *dev, 4752 struct iw_request_info *info, 4753 union iwreq_data *wrqu, char *extra) 4754 { 4755 int ret; 4756 4757 cds_ssr_protect(__func__); 4758 ret = __iw_get_char_setnone(dev, info, wrqu, extra); 4759 cds_ssr_unprotect(__func__); 4760 4761 return ret; 4762 } 4763 4764 static int __iw_get_channel_list(struct net_device *dev, 4765 struct iw_request_info *info, 4766 union iwreq_data *wrqu, char *extra) 4767 { 4768 uint32_t num_channels = 0; 4769 uint8_t i = 0; 4770 uint8_t band_start_channel = CHAN_ENUM_1; 4771 uint8_t band_end_channel = CHAN_ENUM_184; 4772 struct hdd_adapter *hostapd_adapter = (netdev_priv(dev)); 4773 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter); 4774 struct channel_list_info *channel_list = 4775 (struct channel_list_info *) extra; 4776 enum band_info cur_band = BAND_ALL; 4777 struct hdd_context *hdd_ctx; 4778 int ret; 4779 bool is_dfs_mode_enabled = false; 4780 4781 hdd_enter_dev(dev); 4782 4783 hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter); 4784 ret = wlan_hdd_validate_context(hdd_ctx); 4785 if (0 != ret) 4786 return ret; 4787 4788 ret = hdd_check_private_wext_control(hdd_ctx, info); 4789 if (0 != ret) 4790 return ret; 4791 4792 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hal, &cur_band)) { 4793 hdd_err("not able get the current frequency band"); 4794 return -EIO; 4795 } 4796 wrqu->data.length = sizeof(struct channel_list_info); 4797 4798 if (BAND_2G == cur_band) { 4799 band_start_channel = CHAN_ENUM_1; 4800 band_end_channel = CHAN_ENUM_14; 4801 } else if (BAND_5G == cur_band) { 4802 band_start_channel = CHAN_ENUM_36; 4803 band_end_channel = CHAN_ENUM_184; 4804 } 4805 4806 if (cur_band != BAND_2G) { 4807 if (hdd_ctx->config->dot11p_mode) 4808 band_end_channel = CHAN_ENUM_184; 4809 else 4810 band_end_channel = CHAN_ENUM_173; 4811 } 4812 4813 if (hostapd_adapter->device_mode == QDF_STA_MODE && 4814 hdd_ctx->config->enableDFSChnlScan) { 4815 is_dfs_mode_enabled = true; 4816 } else if (hostapd_adapter->device_mode == QDF_SAP_MODE && 4817 hdd_ctx->config->enableDFSMasterCap) { 4818 is_dfs_mode_enabled = true; 4819 } 4820 4821 hdd_debug("curBand = %d, StartChannel = %hu, EndChannel = %hu is_dfs_mode_enabled = %d ", 4822 cur_band, band_start_channel, band_end_channel, 4823 is_dfs_mode_enabled); 4824 4825 for (i = band_start_channel; i <= band_end_channel; i++) { 4826 if ((CHANNEL_STATE_ENABLE == 4827 wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, 4828 WLAN_REG_CH_NUM(i))) || 4829 (is_dfs_mode_enabled && CHANNEL_STATE_DFS == 4830 wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, 4831 WLAN_REG_CH_NUM(i)))) { 4832 channel_list->channels[num_channels] = 4833 WLAN_REG_CH_NUM(i); 4834 num_channels++; 4835 } 4836 } 4837 4838 hdd_debug("number of channels %d", num_channels); 4839 4840 channel_list->num_channels = num_channels; 4841 hdd_exit(); 4842 4843 return 0; 4844 } 4845 4846 int iw_get_channel_list(struct net_device *dev, 4847 struct iw_request_info *info, 4848 union iwreq_data *wrqu, char *extra) 4849 { 4850 int ret; 4851 4852 cds_ssr_protect(__func__); 4853 ret = __iw_get_channel_list(dev, info, wrqu, extra); 4854 cds_ssr_unprotect(__func__); 4855 4856 return ret; 4857 } 4858 4859 static 4860 int __iw_get_genie(struct net_device *dev, 4861 struct iw_request_info *info, 4862 union iwreq_data *wrqu, char *extra) 4863 { 4864 struct hdd_adapter *adapter = (netdev_priv(dev)); 4865 struct hdd_context *hdd_ctx; 4866 int ret; 4867 QDF_STATUS status; 4868 uint32_t length = DOT11F_IE_RSN_MAX_LEN; 4869 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN]; 4870 4871 hdd_enter_dev(dev); 4872 4873 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4874 ret = wlan_hdd_validate_context(hdd_ctx); 4875 if (0 != ret) 4876 return ret; 4877 4878 ret = hdd_check_private_wext_control(hdd_ctx, info); 4879 if (0 != ret) 4880 return ret; 4881 4882 /* 4883 * Actually retrieve the RSN IE from CSR. 4884 * (We previously sent it down in the CSR Roam Profile.) 4885 */ 4886 status = wlan_sap_getstation_ie_information( 4887 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 4888 &length, genIeBytes); 4889 if (status == QDF_STATUS_SUCCESS) { 4890 wrqu->data.length = length; 4891 if (length > DOT11F_IE_RSN_MAX_LEN) { 4892 hdd_err("Invalid buffer length: %d", length); 4893 return -E2BIG; 4894 } 4895 qdf_mem_copy(extra, genIeBytes, length); 4896 hdd_debug(" RSN IE of %d bytes returned", 4897 wrqu->data.length); 4898 } else { 4899 wrqu->data.length = 0; 4900 hdd_debug(" RSN IE failed to populate"); 4901 } 4902 4903 hdd_exit(); 4904 return 0; 4905 } 4906 4907 static 4908 int iw_get_genie(struct net_device *dev, 4909 struct iw_request_info *info, 4910 union iwreq_data *wrqu, char *extra) 4911 { 4912 int ret; 4913 4914 cds_ssr_protect(__func__); 4915 ret = __iw_get_genie(dev, info, wrqu, extra); 4916 cds_ssr_unprotect(__func__); 4917 4918 return ret; 4919 } 4920 4921 static int 4922 __iw_softap_stopbss(struct net_device *dev, 4923 struct iw_request_info *info, 4924 union iwreq_data *wrqu, char *extra) 4925 { 4926 struct hdd_adapter *adapter = (netdev_priv(dev)); 4927 QDF_STATUS status; 4928 struct hdd_context *hdd_ctx; 4929 int ret; 4930 4931 hdd_enter_dev(dev); 4932 4933 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4934 ret = wlan_hdd_validate_context(hdd_ctx); 4935 if (0 != ret) 4936 return ret; 4937 4938 ret = hdd_check_private_wext_control(hdd_ctx, info); 4939 if (0 != ret) 4940 return ret; 4941 4942 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 4943 struct hdd_hostapd_state *hostapd_state = 4944 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 4945 4946 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 4947 status = wlansap_stop_bss( 4948 WLAN_HDD_GET_SAP_CTX_PTR(adapter)); 4949 if (QDF_IS_STATUS_SUCCESS(status)) { 4950 status = 4951 qdf_wait_for_event_completion(&hostapd_state-> 4952 qdf_stop_bss_event, 4953 SME_CMD_TIMEOUT_VALUE); 4954 4955 if (!QDF_IS_STATUS_SUCCESS(status)) { 4956 hdd_err("wait for single_event failed!!"); 4957 QDF_ASSERT(0); 4958 } 4959 } 4960 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); 4961 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc, 4962 adapter->device_mode, 4963 adapter->session_id); 4964 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 4965 false); 4966 ret = qdf_status_to_os_return(status); 4967 } 4968 hdd_exit(); 4969 return ret; 4970 } 4971 4972 static int iw_softap_stopbss(struct net_device *dev, 4973 struct iw_request_info *info, 4974 union iwreq_data *wrqu, 4975 char *extra) 4976 { 4977 int ret; 4978 4979 cds_ssr_protect(__func__); 4980 ret = __iw_softap_stopbss(dev, info, wrqu, extra); 4981 cds_ssr_unprotect(__func__); 4982 4983 return ret; 4984 } 4985 4986 static int 4987 __iw_softap_version(struct net_device *dev, 4988 struct iw_request_info *info, 4989 union iwreq_data *wrqu, char *extra) 4990 { 4991 struct hdd_adapter *adapter = netdev_priv(dev); 4992 struct hdd_context *hdd_ctx; 4993 int ret; 4994 4995 hdd_enter_dev(dev); 4996 4997 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 4998 ret = wlan_hdd_validate_context(hdd_ctx); 4999 if (0 != ret) 5000 return ret; 5001 5002 ret = hdd_check_private_wext_control(hdd_ctx, info); 5003 if (0 != ret) 5004 return ret; 5005 5006 wrqu->data.length = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, 5007 extra); 5008 hdd_exit(); 5009 return 0; 5010 } 5011 5012 static int iw_softap_version(struct net_device *dev, 5013 struct iw_request_info *info, 5014 union iwreq_data *wrqu, 5015 char *extra) 5016 { 5017 int ret; 5018 5019 cds_ssr_protect(__func__); 5020 ret = __iw_softap_version(dev, info, wrqu, extra); 5021 cds_ssr_unprotect(__func__); 5022 5023 return ret; 5024 } 5025 5026 static int hdd_softap_get_sta_info(struct hdd_adapter *adapter, 5027 uint8_t *buf, 5028 int size) 5029 { 5030 int i; 5031 int written; 5032 uint8_t bc_sta_id; 5033 5034 hdd_enter(); 5035 5036 bc_sta_id = WLAN_HDD_GET_AP_CTX_PTR(adapter)->broadcast_sta_id; 5037 5038 written = scnprintf(buf, size, "\nstaId staAddress\n"); 5039 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { 5040 struct hdd_station_info *sta = &adapter->sta_info[i]; 5041 5042 if (written >= size - 1) 5043 break; 5044 5045 if (!sta->in_use) 5046 continue; 5047 5048 if (i == bc_sta_id) 5049 continue; 5050 5051 written += scnprintf(buf + written, size - written, 5052 "%5d %02x:%02x:%02x:%02x:%02x:%02x ecsa=%d\n", 5053 sta->sta_id, 5054 sta->sta_mac.bytes[0], 5055 sta->sta_mac.bytes[1], 5056 sta->sta_mac.bytes[2], 5057 sta->sta_mac.bytes[3], 5058 sta->sta_mac.bytes[4], 5059 sta->sta_mac.bytes[5], 5060 sta->ecsa_capable); 5061 } 5062 5063 hdd_exit(); 5064 5065 return 0; 5066 } 5067 5068 static int __iw_softap_get_sta_info(struct net_device *dev, 5069 struct iw_request_info *info, 5070 union iwreq_data *wrqu, char *extra) 5071 { 5072 int errno; 5073 struct hdd_adapter *adapter; 5074 struct hdd_context *hdd_ctx; 5075 5076 hdd_enter_dev(dev); 5077 5078 adapter = netdev_priv(dev); 5079 errno = hdd_validate_adapter(adapter); 5080 if (errno) 5081 return errno; 5082 5083 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5084 errno = wlan_hdd_validate_context(hdd_ctx); 5085 if (errno) 5086 return errno; 5087 5088 errno = hdd_check_private_wext_control(hdd_ctx, info); 5089 if (errno) 5090 return errno; 5091 5092 errno = hdd_softap_get_sta_info(adapter, extra, WE_SAP_MAX_STA_INFO); 5093 if (errno) { 5094 hdd_err("Failed to get sta info; errno:%d", errno); 5095 return errno; 5096 } 5097 5098 wrqu->data.length = strlen(extra); 5099 5100 hdd_exit(); 5101 5102 return 0; 5103 } 5104 5105 static int iw_softap_get_sta_info(struct net_device *dev, 5106 struct iw_request_info *info, 5107 union iwreq_data *wrqu, 5108 char *extra) 5109 { 5110 int ret; 5111 5112 cds_ssr_protect(__func__); 5113 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra); 5114 cds_ssr_unprotect(__func__); 5115 5116 return ret; 5117 } 5118 5119 static 5120 int __iw_get_softap_linkspeed(struct net_device *dev, 5121 struct iw_request_info *info, 5122 union iwreq_data *wrqu, char *extra) 5123 { 5124 struct hdd_adapter *adapter = (netdev_priv(dev)); 5125 struct hdd_context *hdd_ctx; 5126 char *pLinkSpeed = (char *)extra; 5127 uint32_t link_speed = 0; 5128 int len = sizeof(uint32_t) + 1; 5129 struct qdf_mac_addr macAddress; 5130 char pmacAddress[MAC_ADDRESS_STR_LEN + 1]; 5131 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5132 int rc, ret, i; 5133 5134 hdd_enter_dev(dev); 5135 5136 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5137 ret = wlan_hdd_validate_context(hdd_ctx); 5138 if (0 != ret) 5139 return ret; 5140 5141 ret = hdd_check_private_wext_control(hdd_ctx, info); 5142 if (0 != ret) 5143 return ret; 5144 5145 hdd_debug("wrqu->data.length(%d)", wrqu->data.length); 5146 5147 /* Linkspeed is allowed only for P2P mode */ 5148 if (adapter->device_mode != QDF_P2P_GO_MODE) { 5149 hdd_err("Link Speed is not allowed in Device mode %s(%d)", 5150 hdd_device_mode_to_string( 5151 adapter->device_mode), 5152 adapter->device_mode); 5153 return -ENOTSUPP; 5154 } 5155 5156 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) { 5157 if (copy_from_user((void *)pmacAddress, 5158 wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) { 5159 hdd_err("failed to copy data to user buffer"); 5160 return -EFAULT; 5161 } 5162 pmacAddress[MAC_ADDRESS_STR_LEN - 1] = '\0'; 5163 5164 if (!mac_pton(pmacAddress, macAddress.bytes)) { 5165 hdd_err("String to Hex conversion Failed"); 5166 return -EINVAL; 5167 } 5168 } 5169 /* If no mac address is passed and/or its length is less than 17, 5170 * link speed for first connected client will be returned. 5171 */ 5172 if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) { 5173 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { 5174 if (adapter->sta_info[i].in_use && 5175 (!qdf_is_macaddr_broadcast 5176 (&adapter->sta_info[i].sta_mac))) { 5177 qdf_copy_macaddr( 5178 &macAddress, 5179 &adapter->sta_info[i]. 5180 sta_mac); 5181 status = QDF_STATUS_SUCCESS; 5182 break; 5183 } 5184 } 5185 } 5186 if (!QDF_IS_STATUS_SUCCESS(status)) { 5187 hdd_err("Invalid peer macaddress"); 5188 return -EINVAL; 5189 } 5190 rc = wlan_hdd_get_linkspeed_for_peermac(adapter, &macAddress, 5191 &link_speed); 5192 if (rc) { 5193 hdd_err("Unable to retrieve SME linkspeed"); 5194 return rc; 5195 } 5196 5197 /* linkspeed in units of 500 kbps */ 5198 link_speed = link_speed / 500; 5199 wrqu->data.length = len; 5200 rc = snprintf(pLinkSpeed, len, "%u", link_speed); 5201 if ((rc < 0) || (rc >= len)) { 5202 /* encoding or length error? */ 5203 hdd_err("Unable to encode link speed"); 5204 return -EIO; 5205 } 5206 hdd_exit(); 5207 return 0; 5208 } 5209 5210 static int 5211 iw_get_softap_linkspeed(struct net_device *dev, 5212 struct iw_request_info *info, 5213 union iwreq_data *wrqu, 5214 char *extra) 5215 { 5216 int ret; 5217 5218 cds_ssr_protect(__func__); 5219 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra); 5220 cds_ssr_unprotect(__func__); 5221 5222 return ret; 5223 } 5224 5225 /** 5226 * __iw_get_peer_rssi() - get station's rssi 5227 * @dev: net device 5228 * @info: iwpriv request information 5229 * @wrqu: iwpriv command parameter 5230 * @extra 5231 * 5232 * This function will call wlan_hdd_get_peer_rssi 5233 * to get rssi 5234 * 5235 * Return: 0 on success, otherwise error value 5236 */ 5237 #ifdef QCA_SUPPORT_CP_STATS 5238 static int 5239 __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, 5240 union iwreq_data *wrqu, char *extra) 5241 { 5242 int ret, i; 5243 struct hdd_context *hddctx; 5244 struct stats_event rssi_info; 5245 char macaddrarray[MAC_ADDRESS_STR_LEN]; 5246 struct hdd_adapter *adapter = netdev_priv(dev); 5247 struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT; 5248 5249 hdd_enter(); 5250 5251 hddctx = WLAN_HDD_GET_CTX(adapter); 5252 ret = wlan_hdd_validate_context(hddctx); 5253 if (ret != 0) 5254 return ret; 5255 5256 ret = hdd_check_private_wext_control(hddctx, info); 5257 if (0 != ret) 5258 return ret; 5259 5260 hdd_debug("wrqu->data.length= %d", wrqu->data.length); 5261 5262 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) { 5263 if (copy_from_user(macaddrarray, 5264 wrqu->data.pointer, 5265 MAC_ADDRESS_STR_LEN - 1)) { 5266 hdd_info("failed to copy data from user buffer"); 5267 return -EFAULT; 5268 } 5269 5270 macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0'; 5271 hdd_debug("%s", macaddrarray); 5272 5273 if (!mac_pton(macaddrarray, macaddress.bytes)) 5274 hdd_err("String to Hex conversion Failed"); 5275 } 5276 5277 ret = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->hdd_vdev, 5278 macaddress.bytes, 5279 &rssi_info); 5280 if (ret) { 5281 hdd_err("Unable to retrieve peer rssi: %d", ret); 5282 wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); 5283 return ret; 5284 } 5285 5286 wrqu->data.length = scnprintf(extra, IW_PRIV_SIZE_MASK, "\n"); 5287 for (i = 0; i < rssi_info.num_peer_stats; i++) { 5288 wrqu->data.length += scnprintf(extra + wrqu->data.length, 5289 IW_PRIV_SIZE_MASK - wrqu->data.length, 5290 "[%pM] [%d]\n", 5291 rssi_info.peer_stats[i].peer_macaddr, 5292 rssi_info.peer_stats[i].peer_rssi); 5293 } 5294 wrqu->data.length++; 5295 wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); 5296 5297 hdd_exit(); 5298 return 0; 5299 } 5300 #else 5301 static int 5302 __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, 5303 union iwreq_data *wrqu, char *extra) 5304 { 5305 struct hdd_adapter *adapter = netdev_priv(dev); 5306 struct hdd_context *hddctx; 5307 char macaddrarray[MAC_ADDRESS_STR_LEN]; 5308 struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT; 5309 int ret; 5310 char *rssi_info_output = extra; 5311 struct sir_peer_sta_info peer_sta_info; 5312 struct sir_peer_info *rssi_info; 5313 int i; 5314 int buf; 5315 int length; 5316 5317 hdd_enter(); 5318 5319 hddctx = WLAN_HDD_GET_CTX(adapter); 5320 ret = wlan_hdd_validate_context(hddctx); 5321 if (ret != 0) 5322 return ret; 5323 5324 ret = hdd_check_private_wext_control(hddctx, info); 5325 if (0 != ret) 5326 return ret; 5327 5328 hdd_debug("wrqu->data.length= %d", wrqu->data.length); 5329 5330 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) { 5331 if (copy_from_user(macaddrarray, 5332 wrqu->data.pointer, 5333 MAC_ADDRESS_STR_LEN - 1)) { 5334 hdd_info("failed to copy data from user buffer"); 5335 return -EFAULT; 5336 } 5337 5338 macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0'; 5339 hdd_debug("%s", macaddrarray); 5340 5341 if (!mac_pton(macaddrarray, macaddress.bytes)) 5342 hdd_err("String to Hex conversion Failed"); 5343 } 5344 5345 ret = wlan_hdd_get_peer_rssi(adapter, &macaddress, &peer_sta_info); 5346 if (ret) { 5347 hdd_err("Unable to retrieve peer rssi: %d", ret); 5348 return ret; 5349 } 5350 /* 5351 * The iwpriv tool default print is before mac addr and rssi. 5352 * Add '\n' before first rssi item to align the first rssi item 5353 * with others 5354 * 5355 * wlan getRSSI: 5356 * [macaddr1] [rssi1] 5357 * [macaddr2] [rssi2] 5358 * [macaddr3] [rssi3] 5359 */ 5360 length = scnprintf(rssi_info_output, WE_MAX_STR_LEN, "\n"); 5361 rssi_info = &peer_sta_info.info[0]; 5362 for (i = 0; i < peer_sta_info.sta_num; i++) { 5363 buf = scnprintf 5364 ( 5365 rssi_info_output + length, WE_MAX_STR_LEN - length, 5366 "[%pM] [%d]\n", 5367 rssi_info[i].peer_macaddr.bytes, 5368 rssi_info[i].rssi 5369 ); 5370 length += buf; 5371 } 5372 wrqu->data.length = length + 1; 5373 hdd_exit(); 5374 5375 return 0; 5376 } 5377 #endif 5378 5379 /** 5380 * iw_get_peer_rssi() - get station's rssi 5381 * @dev: net device 5382 * @info: iwpriv request information 5383 * @wrqu: iwpriv command parameter 5384 * @extra 5385 * 5386 * This function will call __iw_get_peer_rssi 5387 * 5388 * Return: 0 on success, otherwise error value 5389 */ 5390 static int 5391 iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, 5392 union iwreq_data *wrqu, char *extra) 5393 { 5394 int ret; 5395 5396 cds_ssr_protect(__func__); 5397 ret = __iw_get_peer_rssi(dev, info, wrqu, extra); 5398 cds_ssr_unprotect(__func__); 5399 5400 return ret; 5401 } 5402 5403 /* 5404 * Note that the following ioctls were defined with semantics which 5405 * cannot be handled by the "iwpriv" userspace application and hence 5406 * they are not included in the hostapd_private_args array 5407 * QCSAP_IOCTL_ASSOC_STA_MACADDR 5408 */ 5409 5410 static const struct iw_priv_args hostapd_private_args[] = { 5411 { 5412 QCSAP_IOCTL_SETPARAM, 5413 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" 5414 }, { 5415 QCSAP_IOCTL_SETPARAM, 5416 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" 5417 }, { 5418 QCSAP_PARAM_MAX_ASSOC, 5419 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, 5420 "setMaxAssoc" 5421 }, { 5422 QCSAP_PARAM_HIDE_SSID, 5423 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" 5424 }, { 5425 QCSAP_PARAM_SET_MC_RATE, 5426 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" 5427 }, { 5428 QCSAP_PARAM_SET_TXRX_FW_STATS, 5429 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, 5430 "txrx_fw_stats" 5431 }, { 5432 QCSAP_PARAM_SET_TXRX_STATS, 5433 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, 5434 "txrx_stats" 5435 }, { 5436 QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY, 5437 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, 5438 "setMccLatency" 5439 }, { 5440 QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA, 5441 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, 5442 "setMccQuota" 5443 }, { 5444 QCSAP_PARAM_SET_CHANNEL_CHANGE, 5445 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, 5446 "setChanChange" 5447 }, { 5448 QCSAP_PARAM_CONC_SYSTEM_PREF, 5449 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, 5450 "setConcSysPref" 5451 }, 5452 #ifdef FEATURE_FW_LOG_PARSING 5453 /* Sub-cmds DBGLOG specific commands */ 5454 { 5455 QCSAP_DBGLOG_LOG_LEVEL, 5456 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5457 0, "dl_loglevel" 5458 }, { 5459 QCSAP_DBGLOG_VAP_ENABLE, 5460 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon" 5461 }, { 5462 QCSAP_DBGLOG_VAP_DISABLE, 5463 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5464 0, "dl_vapoff" 5465 }, { 5466 QCSAP_DBGLOG_MODULE_ENABLE, 5467 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon" 5468 }, { 5469 QCSAP_DBGLOG_MODULE_DISABLE, 5470 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5471 0, "dl_modoff" 5472 }, { 5473 QCSAP_DBGLOG_MOD_LOG_LEVEL, 5474 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5475 0, "dl_mod_loglevel" 5476 }, { 5477 QCSAP_DBGLOG_TYPE, 5478 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type" 5479 }, { 5480 QCSAP_DBGLOG_REPORT_ENABLE, 5481 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5482 0, "dl_report" 5483 }, 5484 #endif /* FEATURE_FW_LOG_PARSING */ 5485 { 5486 5487 QCASAP_TXRX_FWSTATS_RESET, 5488 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5489 0, "txrx_fw_st_rst" 5490 }, { 5491 QCSAP_PARAM_RTSCTS, 5492 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5493 0, "enablertscts" 5494 }, { 5495 QCASAP_SET_11N_RATE, 5496 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5497 0, "set11NRates" 5498 }, { 5499 QCASAP_SET_VHT_RATE, 5500 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5501 0, "set11ACRates" 5502 }, { 5503 QCASAP_SHORT_GI, 5504 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5505 0, "enable_short_gi" 5506 }, { 5507 QCSAP_SET_AMPDU, 5508 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu" 5509 }, { 5510 QCSAP_SET_AMSDU, 5511 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu" 5512 }, { 5513 QCSAP_GTX_HT_MCS, 5514 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs" 5515 }, { 5516 QCSAP_GTX_VHT_MCS, 5517 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5518 0, "gtxVHTMcs" 5519 }, { 5520 QCSAP_GTX_USRCFG, 5521 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5522 0, "gtxUsrCfg" 5523 }, { 5524 QCSAP_GTX_THRE, 5525 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre" 5526 }, { 5527 QCSAP_GTX_MARGIN, 5528 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5529 0, "gtxMargin" 5530 }, { 5531 QCSAP_GTX_STEP, 5532 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep" 5533 }, { 5534 QCSAP_GTX_MINTPC, 5535 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5536 0, "gtxMinTpc" 5537 }, { 5538 QCSAP_GTX_BWMASK, 5539 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5540 0, "gtxBWMask" 5541 }, { 5542 QCSAP_PARAM_CLR_ACL, 5543 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5544 0, "setClearAcl" 5545 }, { 5546 QCSAP_PARAM_ACL_MODE, 5547 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" 5548 }, 5549 { 5550 QCASAP_SET_TM_LEVEL, 5551 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5552 0, "setTmLevel" 5553 }, { 5554 QCASAP_SET_DFS_IGNORE_CAC, 5555 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5556 0, "setDfsIgnoreCAC" 5557 }, { 5558 QCASAP_SET_DFS_NOL, 5559 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5560 0, "setdfsnol" 5561 }, { 5562 QCASAP_SET_DFS_TARGET_CHNL, 5563 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5564 0, "setNextChnl" 5565 }, { 5566 QCASAP_SET_RADAR_CMD, 5567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar" 5568 }, 5569 { 5570 QCSAP_IPA_UC_STAT, 5571 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat" 5572 }, 5573 { 5574 QCASAP_TX_CHAINMASK_CMD, 5575 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5576 0, "set_txchainmask" 5577 }, { 5578 QCASAP_RX_CHAINMASK_CMD, 5579 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5580 0, "set_rxchainmask" 5581 }, { 5582 QCASAP_SET_HE_BSS_COLOR, 5583 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_he_bss_clr" 5584 }, { 5585 QCASAP_NSS_CMD, 5586 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss" 5587 }, { 5588 QCASAP_SET_PHYMODE, 5589 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5590 0, "setphymode" 5591 }, { 5592 QCASAP_DUMP_STATS, 5593 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5594 0, "dumpStats" 5595 }, { 5596 QCASAP_CLEAR_STATS, 5597 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5598 0, "clearStats" 5599 }, { 5600 QCSAP_START_FW_PROFILING, 5601 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5602 0, "startProfile" 5603 }, { 5604 QCASAP_PARAM_LDPC, 5605 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5606 0, "set_ldpc" 5607 }, { 5608 QCASAP_PARAM_TX_STBC, 5609 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5610 0, "set_tx_stbc" 5611 }, { 5612 QCASAP_PARAM_RX_STBC, 5613 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5614 0, "set_rx_stbc" 5615 }, { 5616 QCSAP_IOCTL_GETPARAM, 0, 5617 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" 5618 }, { 5619 QCSAP_IOCTL_GETPARAM, 0, 5620 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" 5621 }, { 5622 QCSAP_PARAM_MAX_ASSOC, 0, 5623 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" 5624 }, { 5625 QCSAP_PARAM_GET_WLAN_DBG, 0, 5626 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" 5627 }, { 5628 QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5629 "get_gtxBWMask" 5630 }, { 5631 QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5632 "get_gtxMinTpc" 5633 }, { 5634 QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5635 "get_gtxStep" 5636 }, { 5637 QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5638 "get_gtxMargin" 5639 }, { 5640 QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5641 "get_gtxThre" 5642 }, { 5643 QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5644 "get_gtxUsrCfg" 5645 }, { 5646 QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5647 "get_gtxVHTMcs" 5648 }, { 5649 QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5650 "get_gtxHTMcs" 5651 }, { 5652 QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5653 "get_short_gi" 5654 }, { 5655 QCSAP_PARAM_RTSCTS, 0, 5656 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts" 5657 }, { 5658 QCASAP_GET_DFS_NOL, 0, 5659 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol" 5660 }, { 5661 QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5662 "get_acl_list" 5663 }, { 5664 QCASAP_PARAM_LDPC, 0, 5665 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5666 "get_ldpc" 5667 }, { 5668 QCASAP_PARAM_TX_STBC, 0, 5669 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5670 "get_tx_stbc" 5671 }, { 5672 QCASAP_PARAM_RX_STBC, 0, 5673 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5674 "get_rx_stbc" 5675 }, { 5676 QCSAP_PARAM_CHAN_WIDTH, 0, 5677 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5678 "get_chwidth" 5679 }, { 5680 QCASAP_TX_CHAINMASK_CMD, 0, 5681 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5682 "get_txchainmask" 5683 }, { 5684 QCASAP_RX_CHAINMASK_CMD, 0, 5685 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5686 "get_rxchainmask" 5687 }, { 5688 QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5689 "get_nss" 5690 }, { 5691 QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5692 "cap_tsf" 5693 }, { 5694 QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT | 5695 IW_PRIV_SIZE_FIXED | 3, "" 5696 }, { 5697 QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 5698 "get_tsf" 5699 }, { 5700 QCASAP_GET_TEMP_CMD, 0, 5701 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp" 5702 }, { 5703 QCSAP_GET_FW_PROFILE_DATA, 0, 5704 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData" 5705 }, { 5706 QCSAP_IOCTL_GET_STAWPAIE, 5707 0, IW_PRIV_TYPE_BYTE | DOT11F_IE_RSN_MAX_LEN, 5708 "get_staWPAIE" 5709 }, { 5710 QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, 5711 "stopbss" 5712 }, { 5713 QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, 5714 "version" 5715 }, { 5716 QCSAP_IOCTL_GET_STA_INFO, 0, 5717 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" 5718 }, { 5719 QCSAP_IOCTL_GET_CHANNEL, 0, 5720 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" 5721 } 5722 , { 5723 QCSAP_IOCTL_DISASSOC_STA, 5724 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0, 5725 "disassoc_sta" 5726 } 5727 /* handler for main ioctl */ 5728 , { 5729 QCSAP_PRIV_GET_CHAR_SET_NONE, 0, 5730 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "" 5731 } 5732 /* handler for sub-ioctl */ 5733 , { 5734 QCSAP_GET_STATS, 0, 5735 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats" 5736 } 5737 , { 5738 QCSAP_LIST_FW_PROFILE, 0, 5739 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile" 5740 } 5741 , { 5742 QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED, 5743 IW_PRIV_TYPE_CHAR | 18, 5744 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" 5745 } 5746 , { 5747 QCSAP_IOCTL_PRIV_GET_RSSI, 5748 IW_PRIV_TYPE_CHAR | 18, 5749 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getRSSI" 5750 } 5751 , { 5752 QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE, 5753 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" 5754 } 5755 , 5756 /* handlers for sub-ioctl */ 5757 { 5758 WE_SET_WLAN_DBG, 5759 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg" 5760 } 5761 , 5762 #ifdef CONFIG_DP_TRACE 5763 /* handlers for sub-ioctl */ 5764 { 5765 WE_SET_DP_TRACE, 5766 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace" 5767 } 5768 , 5769 #endif 5770 /* handlers for main ioctl */ 5771 { 5772 QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE, 5773 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "" 5774 } 5775 , { 5776 WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs" 5777 } 5778 , { 5779 WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, 5780 "setUnitTestCmd" 5781 } 5782 #ifdef WLAN_DEBUG 5783 , 5784 { 5785 WE_SET_CHAN_AVOID, 5786 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 5787 0, 5788 "ch_avoid" 5789 } 5790 #endif 5791 , 5792 /* handlers for main ioctl */ 5793 { 5794 QCSAP_IOCTL_MODIFY_ACL, 5795 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl" 5796 } 5797 , 5798 /* handlers for main ioctl */ 5799 { 5800 QCSAP_IOCTL_GET_CHANNEL_LIST, 5801 0, 5802 IW_PRIV_TYPE_BYTE | sizeof(struct channel_list_info), 5803 "getChannelList" 5804 } 5805 , 5806 /* handlers for main ioctl */ 5807 { 5808 QCSAP_IOCTL_SET_TX_POWER, 5809 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower" 5810 } 5811 , 5812 /* handlers for main ioctl */ 5813 { 5814 QCSAP_IOCTL_SET_MAX_TX_POWER, 5815 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5816 0, "setTxMaxPower" 5817 } 5818 , 5819 { 5820 QCSAP_IOCTL_SET_PKTLOG, 5821 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 5822 0, "pktlog" 5823 } 5824 , 5825 /* Set HDD CFG Ini param */ 5826 { 5827 QCSAP_IOCTL_SET_INI_CFG, 5828 IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig" 5829 } 5830 , 5831 /* Get HDD CFG Ini param */ 5832 { 5833 QCSAP_IOCTL_GET_INI_CFG, 5834 0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig" 5835 } 5836 , 5837 /* handlers for main ioctl */ 5838 { 5839 /* handlers for main ioctl */ 5840 QCSAP_IOCTL_SET_TWO_INT_GET_NONE, 5841 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "" 5842 } 5843 , 5844 /* handlers for sub-ioctl */ 5845 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT 5846 { 5847 QCSAP_IOCTL_SET_FW_CRASH_INJECT, 5848 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 5849 0, "crash_inject" 5850 } 5851 , 5852 #endif 5853 { 5854 QCASAP_SET_RADAR_DBG, 5855 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5856 0, "setRadarDbg" 5857 } 5858 , 5859 #ifdef CONFIG_DP_TRACE 5860 /* dump dp trace - descriptor or dp trace records */ 5861 { 5862 QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL, 5863 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 5864 0, "dump_dp_trace" 5865 } 5866 , 5867 #endif 5868 { 5869 QCSAP_ENABLE_FW_PROFILE, 5870 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 5871 0, "enableProfile" 5872 } 5873 , 5874 { 5875 QCSAP_SET_FW_PROFILE_HIST_INTVL, 5876 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 5877 0, "set_hist_intvl" 5878 } 5879 , 5880 #ifdef WLAN_SUSPEND_RESUME_TEST 5881 { 5882 QCSAP_SET_WLAN_SUSPEND, 5883 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 5884 0, "wlan_suspend" 5885 } 5886 , 5887 { 5888 QCSAP_SET_WLAN_RESUME, 5889 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 5890 0, "wlan_resume" 5891 } 5892 , 5893 #endif 5894 { 5895 QCASAP_SET_11AX_RATE, 5896 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5897 0, "set_11ax_rate" 5898 } 5899 , 5900 { 5901 QCASAP_SET_PEER_RATE, 5902 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5903 0, "set_peer_rate" 5904 } 5905 , 5906 { 5907 QCASAP_PARAM_DCM, 5908 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5909 0, "enable_dcm" 5910 } 5911 , 5912 { 5913 QCASAP_PARAM_RANGE_EXT, 5914 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5915 0, "range_ext" 5916 } 5917 , 5918 { QCSAP_SET_DEFAULT_AMPDU, 5919 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5920 0, "def_ampdu" 5921 } 5922 , 5923 { QCSAP_ENABLE_RTS_BURSTING, 5924 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 5925 0, "rts_bursting" 5926 } 5927 , 5928 }; 5929 5930 static const iw_handler hostapd_private[] = { 5931 /* set priv ioctl */ 5932 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, 5933 /* get priv ioctl */ 5934 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, 5935 [QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] = 5936 iw_softap_get_three, 5937 /* get station genIE */ 5938 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, 5939 /* stop bss */ 5940 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, 5941 /* get driver version */ 5942 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, 5943 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = 5944 iw_softap_getchannel, 5945 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = 5946 iw_softap_getassoc_stamacaddr, 5947 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = 5948 iw_softap_disassoc_sta, 5949 [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = 5950 iw_get_char_setnone, 5951 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - 5952 SIOCIWFIRSTPRIV] = 5953 iw_set_three_ints_getnone, 5954 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - 5955 SIOCIWFIRSTPRIV] = 5956 iw_set_var_ints_getnone, 5957 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = 5958 iw_softap_modify_acl, 5959 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = 5960 iw_get_channel_list, 5961 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = 5962 iw_softap_get_sta_info, 5963 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - 5964 SIOCIWFIRSTPRIV] = 5965 iw_get_softap_linkspeed, 5966 [QCSAP_IOCTL_PRIV_GET_RSSI - SIOCIWFIRSTPRIV] = 5967 iw_get_peer_rssi, 5968 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = 5969 iw_softap_set_tx_power, 5970 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = 5971 iw_softap_set_max_tx_power, 5972 [QCSAP_IOCTL_SET_PKTLOG - SIOCIWFIRSTPRIV] = 5973 iw_softap_set_pktlog, 5974 [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] = 5975 iw_softap_set_ini_cfg, 5976 [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] = 5977 iw_softap_get_ini_cfg, 5978 [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] = 5979 iw_softap_set_two_ints_getnone, 5980 }; 5981 5982 const struct iw_handler_def hostapd_handler_def = { 5983 .num_standard = 0, 5984 .num_private = QDF_ARRAY_SIZE(hostapd_private), 5985 .num_private_args = QDF_ARRAY_SIZE(hostapd_private_args), 5986 .standard = NULL, 5987 .private = (iw_handler *) hostapd_private, 5988 .private_args = hostapd_private_args, 5989 .get_wireless_stats = NULL, 5990 }; 5991 5992 const struct net_device_ops net_ops_struct = { 5993 .ndo_open = hdd_hostapd_open, 5994 .ndo_stop = hdd_hostapd_stop, 5995 .ndo_uninit = hdd_hostapd_uninit, 5996 .ndo_start_xmit = hdd_softap_hard_start_xmit, 5997 .ndo_tx_timeout = hdd_softap_tx_timeout, 5998 .ndo_get_stats = hdd_get_stats, 5999 .ndo_set_mac_address = hdd_hostapd_set_mac_address, 6000 .ndo_do_ioctl = hdd_ioctl, 6001 .ndo_change_mtu = hdd_hostapd_change_mtu, 6002 .ndo_select_queue = hdd_hostapd_select_queue, 6003 }; 6004 6005 void hdd_set_ap_ops(struct net_device *dev) 6006 { 6007 dev->netdev_ops = &net_ops_struct; 6008 } 6009 6010 bool hdd_sap_create_ctx(struct hdd_adapter *adapter) 6011 { 6012 hdd_debug("creating sap context"); 6013 adapter->session.ap.sap_context = sap_create_ctx(); 6014 if (adapter->session.ap.sap_context) 6015 return true; 6016 6017 return false; 6018 } 6019 6020 bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter) 6021 { 6022 hdd_debug("destroying sap context"); 6023 sap_destroy_ctx(adapter->session.ap.sap_context); 6024 adapter->session.ap.sap_context = NULL; 6025 6026 return true; 6027 } 6028 6029 QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) 6030 { 6031 struct hdd_hostapd_state *phostapdBuf; 6032 struct net_device *dev = adapter->dev; 6033 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6034 QDF_STATUS status = QDF_STATUS_E_FAILURE; 6035 struct sap_context *sapContext = NULL; 6036 int ret; 6037 enum dfs_mode acs_dfs_mode; 6038 6039 hdd_enter(); 6040 6041 hdd_info("SSR in progress: %d", reinit); 6042 qdf_atomic_init(&adapter->session.ap.acs_in_progress); 6043 6044 sapContext = hdd_hostapd_init_sap_session(adapter); 6045 if (!sapContext) { 6046 hdd_err("Invalid sap_ctx"); 6047 goto error_release_vdev; 6048 } 6049 6050 if (!reinit) { 6051 adapter->session.ap.sap_config.channel = 6052 hdd_ctx->acs_policy.acs_channel; 6053 acs_dfs_mode = hdd_ctx->acs_policy.acs_dfs_mode; 6054 adapter->session.ap.sap_config.acs_dfs_mode = 6055 wlan_hdd_get_dfs_mode(acs_dfs_mode); 6056 } 6057 6058 /* Allocate the Wireless Extensions state structure */ 6059 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 6060 6061 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode); 6062 6063 /* Zero the memory. This zeros the profile structure. */ 6064 memset(phostapdBuf, 0, sizeof(struct hdd_hostapd_state)); 6065 6066 status = qdf_event_create(&phostapdBuf->qdf_event); 6067 if (!QDF_IS_STATUS_SUCCESS(status)) { 6068 hdd_err("Hostapd HDD qdf event init failed!!"); 6069 goto error_release_sap_session; 6070 } 6071 6072 status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event); 6073 if (!QDF_IS_STATUS_SUCCESS(status)) { 6074 hdd_err("Hostapd HDD stop bss event init failed!!"); 6075 goto error_release_sap_session; 6076 } 6077 6078 status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event); 6079 if (!QDF_IS_STATUS_SUCCESS(status)) { 6080 hdd_err("Hostapd HDD sta disassoc event init failed!!"); 6081 goto error_release_sap_session; 6082 } 6083 6084 6085 /* Register as a wireless device */ 6086 dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def; 6087 6088 /* Initialize the data path module */ 6089 status = hdd_softap_init_tx_rx(adapter); 6090 if (!QDF_IS_STATUS_SUCCESS(status)) { 6091 hdd_err("hdd_softap_init_tx_rx failed"); 6092 goto error_release_sap_session; 6093 } 6094 6095 status = hdd_wmm_adapter_init(adapter); 6096 if (!QDF_IS_STATUS_SUCCESS(status)) { 6097 hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]", 6098 status, status); 6099 goto error_release_wmm; 6100 } 6101 6102 set_bit(WMM_INIT_DONE, &adapter->event_flags); 6103 6104 ret = wma_cli_set_command(adapter->session_id, 6105 WMI_PDEV_PARAM_BURST_ENABLE, 6106 HDD_ENABLE_SIFS_BURST_DEFAULT, 6107 PDEV_CMD); 6108 6109 if (0 != ret) 6110 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed: %d", ret); 6111 6112 if (!reinit) { 6113 adapter->session.ap.sap_config.acs_cfg.acs_mode = false; 6114 wlan_hdd_undo_acs(adapter); 6115 qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg, 6116 sizeof(struct sap_acs_cfg)); 6117 } 6118 6119 /* rcpi info initialization */ 6120 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); 6121 6122 hdd_exit(); 6123 6124 return status; 6125 6126 error_release_wmm: 6127 hdd_softap_deinit_tx_rx(adapter); 6128 error_release_sap_session: 6129 hdd_hostapd_deinit_sap_session(adapter); 6130 error_release_vdev: 6131 QDF_BUG(!hdd_vdev_destroy(adapter)); 6132 6133 hdd_exit(); 6134 return status; 6135 } 6136 6137 void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx, 6138 struct hdd_adapter *adapter, 6139 bool rtnl_held) 6140 { 6141 hdd_enter_dev(adapter->dev); 6142 6143 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 6144 hdd_wmm_adapter_close(adapter); 6145 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 6146 } 6147 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); 6148 wlan_hdd_undo_acs(adapter); 6149 hdd_softap_deinit_tx_rx(adapter); 6150 /* 6151 * if we are being called during driver unload, 6152 * then the dev has already been invalidated. 6153 * if we are being called at other times, then we can 6154 * detach the wireless device handlers 6155 */ 6156 if (adapter->dev) { 6157 if (rtnl_held) { 6158 adapter->dev->wireless_handlers = NULL; 6159 } else { 6160 rtnl_lock(); 6161 adapter->dev->wireless_handlers = NULL; 6162 rtnl_unlock(); 6163 } 6164 } 6165 if (hdd_hostapd_deinit_sap_session(adapter)) 6166 hdd_err("Failed:hdd_hostapd_deinit_sap_session"); 6167 6168 hdd_exit(); 6169 } 6170 6171 /** 6172 * hdd_wlan_create_ap_dev() - create an AP-mode device 6173 * @hdd_ctx: Global HDD context 6174 * @macAddr: MAC address to assign to the interface 6175 * @name_assign_type: the name of assign type of the netdev 6176 * @iface_name: User-visible name of the interface 6177 * 6178 * This function will allocate a Linux net_device and configuration it 6179 * for an AP mode of operation. Note that the device is NOT actually 6180 * registered with the kernel at this time. 6181 * 6182 * Return: A pointer to the private data portion of the net_device if 6183 * the allocation and initialization was successful, NULL otherwise. 6184 */ 6185 struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx, 6186 tSirMacAddr macAddr, 6187 unsigned char name_assign_type, 6188 uint8_t *iface_name) 6189 { 6190 struct net_device *dev; 6191 struct hdd_adapter *adapter; 6192 QDF_STATUS qdf_status; 6193 6194 hdd_debug("iface_name = %s", iface_name); 6195 6196 dev = alloc_netdev_mq(sizeof(struct hdd_adapter), iface_name, 6197 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) 6198 name_assign_type, 6199 #endif 6200 ether_setup, NUM_TX_QUEUES); 6201 6202 if (!dev) 6203 return NULL; 6204 6205 adapter = netdev_priv(dev); 6206 6207 /* Init the net_device structure */ 6208 ether_setup(dev); 6209 6210 /* Initialize the adapter context to zeros. */ 6211 qdf_mem_zero(adapter, sizeof(struct hdd_adapter)); 6212 adapter->dev = dev; 6213 adapter->hdd_ctx = hdd_ctx; 6214 adapter->magic = WLAN_HDD_ADAPTER_MAGIC; 6215 adapter->session_id = HDD_SESSION_ID_INVALID; 6216 6217 hdd_debug("dev = %pK, adapter = %pK, concurrency_mode=0x%x", 6218 dev, adapter, 6219 (int)policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc)); 6220 6221 /* Init the net_device structure */ 6222 strlcpy(dev->name, (const char *)iface_name, IFNAMSIZ); 6223 6224 hdd_set_ap_ops(dev); 6225 6226 dev->watchdog_timeo = HDD_TX_TIMEOUT; 6227 dev->mtu = HDD_DEFAULT_MTU; 6228 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN; 6229 6230 if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload) 6231 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 6232 dev->features |= NETIF_F_RXCSUM; 6233 6234 qdf_mem_copy(dev->dev_addr, (void *)macAddr, 6235 sizeof(tSirMacAddr)); 6236 qdf_mem_copy(adapter->mac_addr.bytes, 6237 (void *)macAddr, sizeof(tSirMacAddr)); 6238 6239 adapter->offloads_configured = false; 6240 hdd_dev_setup_destructor(dev); 6241 dev->ieee80211_ptr = &adapter->wdev; 6242 adapter->wdev.wiphy = hdd_ctx->wiphy; 6243 adapter->wdev.netdev = dev; 6244 hdd_set_tso_flags(hdd_ctx, dev); 6245 6246 qdf_status = qdf_event_create( 6247 &adapter->qdf_session_open_event); 6248 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 6249 hdd_err("failed to create session open QDF event!"); 6250 free_netdev(adapter->dev); 6251 return NULL; 6252 } 6253 6254 qdf_status = qdf_event_create( 6255 &adapter->qdf_session_close_event); 6256 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 6257 hdd_err("failed to create session close QDF event!"); 6258 free_netdev(adapter->dev); 6259 return NULL; 6260 } 6261 6262 init_completion(&adapter->tx_action_cnf_event); 6263 init_completion(&adapter->cancel_rem_on_chan_var); 6264 init_completion(&adapter->rem_on_chan_ready_event); 6265 init_completion(&adapter->sta_authorized_event); 6266 init_completion(&adapter->offchannel_tx_event); 6267 6268 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); 6269 spin_lock_init(&adapter->pause_map_lock); 6270 adapter->start_time = adapter->last_time = qdf_system_ticks(); 6271 6272 qdf_atomic_init(&adapter->dfs_radar_found); 6273 6274 return adapter; 6275 } 6276 6277 /** 6278 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not 6279 * @rate: Rate to be checked 6280 * 6281 * Return: true if rate if 11g else false 6282 */ 6283 static bool wlan_hdd_rate_is_11g(u8 rate) 6284 { 6285 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 6286 96, 108}; /* actual rate * 2 */ 6287 u8 i; 6288 6289 for (i = 0; i < 8; i++) { 6290 if (rate == gRateArray[i]) 6291 return true; 6292 } 6293 return false; 6294 } 6295 6296 #ifdef QCA_HT_2040_COEX 6297 /** 6298 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE 6299 * @adapter: Pointer to hostapd adapter 6300 * 6301 * Return: HT support channel width config value 6302 */ 6303 static bool wlan_hdd_get_sap_obss(struct hdd_adapter *adapter) 6304 { 6305 uint32_t ret; 6306 const uint8_t *ie = NULL; 6307 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN]; 6308 tDot11fIEHTCaps dot11_ht_cap_ie = {0}; 6309 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6310 struct hdd_beacon_data *beacon = adapter->session.ap.beacon; 6311 6312 ie = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY, 6313 beacon->tail, beacon->tail_len); 6314 if (ie && ie[1]) { 6315 qdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN); 6316 ret = dot11f_unpack_ie_ht_caps((tpAniSirGlobal)hdd_ctx->hHal, 6317 ht_cap_ie, ie[1], 6318 &dot11_ht_cap_ie, false); 6319 if (DOT11F_FAILED(ret)) { 6320 hdd_err("unpack failed, ret: 0x%x", ret); 6321 return false; 6322 } 6323 return dot11_ht_cap_ie.supportedChannelWidthSet; 6324 } 6325 6326 return false; 6327 } 6328 #else 6329 static bool wlan_hdd_get_sap_obss(struct hdd_adapter *adapter) 6330 { 6331 return false; 6332 } 6333 #endif 6334 /** 6335 * wlan_hdd_set_channel() - set channel in sap mode 6336 * @wiphy: Pointer to wiphy structure 6337 * @dev: Pointer to net_device structure 6338 * @chandef: Pointer to channel definition structure 6339 * @channel_type: Channel type 6340 * 6341 * Return: 0 for success non-zero for failure 6342 */ 6343 int wlan_hdd_set_channel(struct wiphy *wiphy, 6344 struct net_device *dev, 6345 struct cfg80211_chan_def *chandef, 6346 enum nl80211_channel_type channel_type) 6347 { 6348 struct hdd_adapter *adapter = NULL; 6349 uint32_t num_ch = 0; 6350 int channel = 0; 6351 int channel_seg2 = 0; 6352 struct hdd_context *hdd_ctx; 6353 int status; 6354 6355 tSmeConfigParams *sme_config; 6356 tsap_config_t *sap_config; 6357 6358 hdd_enter(); 6359 6360 6361 if (NULL == dev) { 6362 hdd_err("Called with dev = NULL"); 6363 return -ENODEV; 6364 } 6365 adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6366 6367 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, 6368 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, 6369 adapter->session_id, channel_type)); 6370 6371 hdd_debug("Device_mode %s(%d) freq = %d", 6372 hdd_device_mode_to_string(adapter->device_mode), 6373 adapter->device_mode, chandef->chan->center_freq); 6374 6375 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6376 status = wlan_hdd_validate_context(hdd_ctx); 6377 if (status) 6378 return status; 6379 6380 6381 /* 6382 * Do freq to chan conversion 6383 * TODO: for 11a 6384 */ 6385 6386 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq); 6387 6388 if (NL80211_CHAN_WIDTH_80P80 == chandef->width || 6389 NL80211_CHAN_WIDTH_160 == chandef->width) { 6390 if (chandef->center_freq2) 6391 channel_seg2 = ieee80211_frequency_to_channel( 6392 chandef->center_freq2); 6393 else 6394 hdd_err("Invalid center_freq2"); 6395 } 6396 6397 /* Check freq range */ 6398 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) || 6399 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) { 6400 hdd_err("Channel: %d is outside valid range from %d to %d", 6401 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN, 6402 WNI_CFG_CURRENT_CHANNEL_STAMAX); 6403 return -EINVAL; 6404 } 6405 6406 /* Check freq range */ 6407 6408 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) || 6409 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) { 6410 hdd_err("Channel: %d is outside valid range from %d to %d", 6411 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN, 6412 WNI_CFG_CURRENT_CHANNEL_STAMAX); 6413 return -EINVAL; 6414 } 6415 6416 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN; 6417 6418 if ((QDF_SAP_MODE != adapter->device_mode) && 6419 (QDF_P2P_GO_MODE != adapter->device_mode)) { 6420 if (QDF_STATUS_SUCCESS != 6421 wlan_hdd_validate_operation_channel(adapter, channel)) { 6422 hdd_err("Invalid Channel: %d", channel); 6423 return -EINVAL; 6424 } 6425 hdd_debug("set channel to [%d] for device mode %s(%d)", 6426 channel, 6427 hdd_device_mode_to_string(adapter->device_mode), 6428 adapter->device_mode); 6429 } 6430 6431 if ((adapter->device_mode == QDF_STA_MODE) || 6432 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 6433 struct csr_roam_profile *roam_profile; 6434 struct hdd_station_ctx *sta_ctx = 6435 WLAN_HDD_GET_STATION_CTX_PTR(adapter); 6436 6437 if (eConnectionState_IbssConnected == 6438 sta_ctx->conn_info.connState) { 6439 /* Link is up then return cant set channel */ 6440 hdd_err("IBSS Associated, can't set the channel"); 6441 return -EINVAL; 6442 } 6443 6444 roam_profile = hdd_roam_profile(adapter); 6445 num_ch = roam_profile->ChannelInfo.numOfChannels = 1; 6446 sta_ctx->conn_info.operationChannel = channel; 6447 roam_profile->ChannelInfo.ChannelList = 6448 &sta_ctx->conn_info.operationChannel; 6449 } else if ((adapter->device_mode == QDF_SAP_MODE) 6450 || (adapter->device_mode == QDF_P2P_GO_MODE) 6451 ) { 6452 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config); 6453 if (QDF_P2P_GO_MODE == adapter->device_mode) { 6454 if (QDF_STATUS_SUCCESS != 6455 wlan_hdd_validate_operation_channel(adapter, 6456 channel)) { 6457 hdd_err("Invalid Channel: %d", channel); 6458 return -EINVAL; 6459 } 6460 sap_config->channel = channel; 6461 sap_config->ch_params.center_freq_seg1 = channel_seg2; 6462 } else { 6463 /* set channel to what hostapd configured */ 6464 if (QDF_STATUS_SUCCESS != 6465 wlan_hdd_validate_operation_channel(adapter, 6466 channel)) { 6467 hdd_err("Invalid Channel: %d", channel); 6468 return -EINVAL; 6469 } 6470 6471 sap_config->channel = channel; 6472 sap_config->ch_params.center_freq_seg1 = channel_seg2; 6473 6474 sme_config = qdf_mem_malloc(sizeof(*sme_config)); 6475 6476 if (!sme_config) { 6477 hdd_err("Unable to allocate memory for smeconfig!"); 6478 return -ENOMEM; 6479 } 6480 sme_get_config_param(hdd_ctx->hHal, sme_config); 6481 switch (channel_type) { 6482 case NL80211_CHAN_HT20: 6483 case NL80211_CHAN_NO_HT: 6484 sme_config->csrConfig.obssEnabled = false; 6485 sap_config->sec_ch = 0; 6486 break; 6487 case NL80211_CHAN_HT40MINUS: 6488 sap_config->sec_ch = sap_config->channel - 4; 6489 break; 6490 case NL80211_CHAN_HT40PLUS: 6491 sap_config->sec_ch = sap_config->channel + 4; 6492 break; 6493 default: 6494 hdd_err("Error!!! Invalid HT20/40 mode !"); 6495 qdf_mem_free(sme_config); 6496 return -EINVAL; 6497 } 6498 sme_config->csrConfig.obssEnabled = 6499 wlan_hdd_get_sap_obss(adapter); 6500 6501 sme_update_config(hdd_ctx->hHal, sme_config); 6502 qdf_mem_free(sme_config); 6503 } 6504 } else { 6505 hdd_err("Invalid device mode failed to set valid channel"); 6506 return -EINVAL; 6507 } 6508 hdd_exit(); 6509 return status; 6510 } 6511 6512 /** 6513 * wlan_hdd_check_11gmode() - check for 11g mode 6514 * @pIe: Pointer to IE 6515 * @require_ht: Pointer to require ht 6516 * @require_vht: Pointer to require vht 6517 * @pCheckRatesfor11g: Pointer to check rates for 11g mode 6518 * @pSapHw_mode: SAP HW mode 6519 * 6520 * Check for 11g rate and set proper 11g only mode 6521 * 6522 * Return: none 6523 */ 6524 static void wlan_hdd_check_11gmode(const u8 *pIe, u8 *require_ht, 6525 u8 *require_vht, u8 *pCheckRatesfor11g, 6526 eCsrPhyMode *pSapHw_mode) 6527 { 6528 u8 i, num_rates = pIe[0]; 6529 6530 pIe += 1; 6531 for (i = 0; i < num_rates; i++) { 6532 if (*pCheckRatesfor11g 6533 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) { 6534 /* If rate set have 11g rate than change the mode 6535 * to 11G 6536 */ 6537 *pSapHw_mode = eCSR_DOT11_MODE_11g; 6538 if (pIe[i] & BASIC_RATE_MASK) { 6539 /* If we have 11g rate as basic rate, it 6540 * means mode is 11g only mode. 6541 */ 6542 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY; 6543 *pCheckRatesfor11g = false; 6544 } 6545 } else { 6546 if ((BASIC_RATE_MASK | 6547 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i]) 6548 *require_ht = true; 6549 else if ((BASIC_RATE_MASK | 6550 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i]) 6551 *require_vht = true; 6552 } 6553 } 6554 } 6555 6556 #ifdef WLAN_FEATURE_11AX 6557 /** 6558 * wlan_hdd_add_extn_ie() - add extension IE 6559 * @adapter: Pointer to hostapd adapter 6560 * @genie: Pointer to ie to be added 6561 * @total_ielen: Pointer to store total ie length 6562 * @oui: Pointer to oui 6563 * @oui_size: Size of oui 6564 * 6565 * Return: 0 for success non-zero for failure 6566 */ 6567 static int wlan_hdd_add_extn_ie(struct hdd_adapter *adapter, uint8_t *genie, 6568 uint16_t *total_ielen, uint8_t *oui, 6569 uint8_t oui_size) 6570 { 6571 const uint8_t *ie; 6572 uint16_t ielen = 0; 6573 struct hdd_beacon_data *beacon = adapter->session.ap.beacon; 6574 6575 ie = wlan_get_ext_ie_ptr_from_ext_id(oui, oui_size, 6576 beacon->tail, 6577 beacon->tail_len); 6578 if (ie) { 6579 ielen = ie[1] + 2; 6580 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) { 6581 qdf_mem_copy(&genie[*total_ielen], ie, ielen); 6582 } else { 6583 hdd_err("**Ie Length is too big***"); 6584 return -EINVAL; 6585 } 6586 *total_ielen += ielen; 6587 } 6588 return 0; 6589 } 6590 #endif 6591 6592 /** 6593 * wlan_hdd_add_hostapd_conf_vsie() - configure Vendor IE in sap mode 6594 * @adapter: Pointer to hostapd adapter 6595 * @genie: Pointer to Vendor IE 6596 * @total_ielen: Pointer to store total ie length 6597 * 6598 * Return: none 6599 */ 6600 static void wlan_hdd_add_hostapd_conf_vsie(struct hdd_adapter *adapter, 6601 uint8_t *genie, 6602 uint16_t *total_ielen) 6603 { 6604 struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon; 6605 int left = pBeacon->tail_len; 6606 uint8_t *ptr = pBeacon->tail; 6607 uint8_t elem_id, elem_len; 6608 uint16_t ielen = 0; 6609 bool skip_ie; 6610 6611 if (NULL == ptr || 0 == left) 6612 return; 6613 6614 while (left >= 2) { 6615 elem_id = ptr[0]; 6616 elem_len = ptr[1]; 6617 left -= 2; 6618 if (elem_len > left) { 6619 hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**", 6620 elem_id, elem_len, left); 6621 return; 6622 } 6623 if (IE_EID_VENDOR == elem_id) { 6624 /* 6625 * skipping the Vendor IE's which we don't want to 6626 * include or it will be included by existing code. 6627 */ 6628 if (elem_len >= WPS_OUI_TYPE_SIZE && 6629 (!qdf_mem_cmp(&ptr[2], WHITELIST_OUI_TYPE, 6630 WPA_OUI_TYPE_SIZE) || 6631 !qdf_mem_cmp(&ptr[2], BLACKLIST_OUI_TYPE, 6632 WPA_OUI_TYPE_SIZE) || 6633 !qdf_mem_cmp(&ptr[2], "\x00\x50\xf2\x02", 6634 WPA_OUI_TYPE_SIZE) || 6635 !qdf_mem_cmp(&ptr[2], WPA_OUI_TYPE, 6636 WPA_OUI_TYPE_SIZE))) 6637 skip_ie = true; 6638 else 6639 skip_ie = false; 6640 6641 if (!skip_ie) { 6642 ielen = ptr[1] + 2; 6643 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) { 6644 qdf_mem_copy(&genie[*total_ielen], ptr, 6645 ielen); 6646 *total_ielen += ielen; 6647 } else { 6648 hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_lent: %d", 6649 elem_id, elem_len, *total_ielen); 6650 } 6651 } 6652 } 6653 6654 left -= elem_len; 6655 ptr += (elem_len + 2); 6656 } 6657 } 6658 6659 /** 6660 * wlan_hdd_add_extra_ie() - add extra ies in beacon 6661 * @adapter: Pointer to hostapd adapter 6662 * @genie: Pointer to extra ie 6663 * @total_ielen: Pointer to store total ie length 6664 * @temp_ie_id: ID of extra ie 6665 * 6666 * Return: none 6667 */ 6668 static void wlan_hdd_add_extra_ie(struct hdd_adapter *adapter, 6669 uint8_t *genie, uint16_t *total_ielen, 6670 uint8_t temp_ie_id) 6671 { 6672 struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon; 6673 int left = pBeacon->tail_len; 6674 uint8_t *ptr = pBeacon->tail; 6675 uint8_t elem_id, elem_len; 6676 uint16_t ielen = 0; 6677 6678 if (NULL == ptr || 0 == left) 6679 return; 6680 6681 while (left >= 2) { 6682 elem_id = ptr[0]; 6683 elem_len = ptr[1]; 6684 left -= 2; 6685 if (elem_len > left) { 6686 hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**", 6687 elem_id, elem_len, left); 6688 return; 6689 } 6690 6691 if (temp_ie_id == elem_id) { 6692 ielen = ptr[1] + 2; 6693 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) { 6694 qdf_mem_copy(&genie[*total_ielen], ptr, ielen); 6695 *total_ielen += ielen; 6696 } else { 6697 hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_len: %d", 6698 elem_id, elem_len, *total_ielen); 6699 } 6700 } 6701 6702 left -= elem_len; 6703 ptr += (elem_len + 2); 6704 } 6705 } 6706 6707 /** 6708 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode 6709 * @adapter: Pointer to hostapd adapter 6710 * @ppBeacon: Pointer to pointer to beacon data 6711 * @params: Pointer to beacon parameters 6712 * @dtim_period: DTIM period 6713 * 6714 * Return: 0 for success non-zero for failure 6715 */ 6716 static int 6717 wlan_hdd_cfg80211_alloc_new_beacon(struct hdd_adapter *adapter, 6718 struct hdd_beacon_data **ppBeacon, 6719 struct cfg80211_beacon_data *params, 6720 int dtim_period) 6721 { 6722 int size; 6723 struct hdd_beacon_data *beacon = NULL; 6724 struct hdd_beacon_data *old = NULL; 6725 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len; 6726 const u8 *head, *tail, *proberesp_ies, *assocresp_ies; 6727 6728 hdd_enter(); 6729 if (params->head && !params->head_len) { 6730 hdd_err("head_len is NULL"); 6731 return -EINVAL; 6732 } 6733 6734 old = adapter->session.ap.beacon; 6735 6736 if (!params->head && !old) { 6737 hdd_err("session: %d old and new heads points to NULL", 6738 adapter->session_id); 6739 return -EINVAL; 6740 } 6741 6742 if (params->head) { 6743 head_len = params->head_len; 6744 head = params->head; 6745 } else { 6746 head_len = old->head_len; 6747 head = old->head; 6748 } 6749 6750 if (params->tail || !old) { 6751 tail_len = params->tail_len; 6752 tail = params->tail; 6753 } else { 6754 tail_len = old->tail_len; 6755 tail = old->tail; 6756 } 6757 6758 if (params->proberesp_ies || !old) { 6759 proberesp_ies_len = params->proberesp_ies_len; 6760 proberesp_ies = params->proberesp_ies; 6761 } else { 6762 proberesp_ies_len = old->proberesp_ies_len; 6763 proberesp_ies = old->proberesp_ies; 6764 } 6765 6766 if (params->assocresp_ies || !old) { 6767 assocresp_ies_len = params->assocresp_ies_len; 6768 assocresp_ies = params->assocresp_ies; 6769 } else { 6770 assocresp_ies_len = old->assocresp_ies_len; 6771 assocresp_ies = old->assocresp_ies; 6772 } 6773 6774 size = sizeof(struct hdd_beacon_data) + head_len + tail_len + 6775 proberesp_ies_len + assocresp_ies_len; 6776 6777 beacon = qdf_mem_malloc(size); 6778 6779 if (beacon == NULL) { 6780 hdd_err("Mem allocation for beacon failed"); 6781 return -ENOMEM; 6782 } 6783 if (dtim_period) 6784 beacon->dtim_period = dtim_period; 6785 else if (old) 6786 beacon->dtim_period = old->dtim_period; 6787 /* ----------------------------------------------- 6788 * | head | tail | proberesp_ies | assocresp_ies | 6789 * ----------------------------------------------- 6790 */ 6791 beacon->head = ((u8 *) beacon) + sizeof(struct hdd_beacon_data); 6792 beacon->tail = beacon->head + head_len; 6793 beacon->proberesp_ies = beacon->tail + tail_len; 6794 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len; 6795 6796 beacon->head_len = head_len; 6797 beacon->tail_len = tail_len; 6798 beacon->proberesp_ies_len = proberesp_ies_len; 6799 beacon->assocresp_ies_len = assocresp_ies_len; 6800 6801 if (head && head_len) 6802 memcpy(beacon->head, head, head_len); 6803 if (tail && tail_len) 6804 memcpy(beacon->tail, tail, tail_len); 6805 if (proberesp_ies && proberesp_ies_len) 6806 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len); 6807 if (assocresp_ies && assocresp_ies_len) 6808 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len); 6809 6810 *ppBeacon = beacon; 6811 6812 adapter->session.ap.beacon = NULL; 6813 qdf_mem_free(old); 6814 6815 return 0; 6816 6817 } 6818 6819 #ifdef QCA_HT_2040_COEX 6820 static void wlan_hdd_add_sap_obss_scan_ie( 6821 struct hdd_adapter *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len) 6822 { 6823 if (QDF_SAP_MODE == hostapd_adapter->device_mode) { 6824 if (wlan_hdd_get_sap_obss(hostapd_adapter)) 6825 wlan_hdd_add_extra_ie(hostapd_adapter, ie_buf, ie_len, 6826 WLAN_EID_OVERLAP_BSS_SCAN_PARAM); 6827 } 6828 } 6829 #else 6830 static void wlan_hdd_add_sap_obss_scan_ie( 6831 struct hdd_adapter *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len) 6832 { 6833 } 6834 #endif 6835 6836 /** 6837 * wlan_hdd_cfg80211_update_apies() - update ap mode 11ax ies 6838 * @adapter: Pointer to hostapd adapter 6839 * @genie: generic IE buffer 6840 * @total_ielen: out param to update total ielen 6841 * 6842 * Return: 0 for success non-zero for failure 6843 */ 6844 6845 #ifdef WLAN_FEATURE_11AX 6846 static int hdd_update_11ax_apies(struct hdd_adapter *adapter, 6847 uint8_t *genie, uint16_t *total_ielen) 6848 { 6849 if (wlan_hdd_add_extn_ie(adapter, genie, total_ielen, 6850 HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE)) { 6851 hdd_err("Adding HE Cap ie failed"); 6852 return -EINVAL; 6853 } 6854 6855 if (wlan_hdd_add_extn_ie(adapter, genie, total_ielen, 6856 HE_OP_OUI_TYPE, HE_OP_OUI_SIZE)) { 6857 hdd_err("Adding HE Op ie failed"); 6858 return -EINVAL; 6859 } 6860 6861 return 0; 6862 } 6863 #else 6864 static int hdd_update_11ax_apies(struct hdd_adapter *adapter, 6865 uint8_t *genie, uint16_t *total_ielen) 6866 { 6867 return 0; 6868 } 6869 #endif 6870 6871 /** 6872 * wlan_hdd_cfg80211_update_apies() - update ap mode ies 6873 * @adapter: Pointer to hostapd adapter 6874 * 6875 * Return: 0 for success non-zero for failure 6876 */ 6877 int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter) 6878 { 6879 uint8_t *genie; 6880 uint16_t total_ielen = 0; 6881 int ret = 0; 6882 tsap_config_t *pConfig; 6883 tSirUpdateIE updateIE; 6884 struct hdd_beacon_data *beacon = NULL; 6885 uint16_t proberesp_ies_len; 6886 uint8_t *proberesp_ies = NULL; 6887 6888 pConfig = &adapter->session.ap.sap_config; 6889 beacon = adapter->session.ap.beacon; 6890 if (!beacon) { 6891 hdd_err("Beacon is NULL !"); 6892 return -EINVAL; 6893 } 6894 6895 genie = qdf_mem_malloc(MAX_GENIE_LEN); 6896 6897 if (genie == NULL) 6898 return -ENOMEM; 6899 6900 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, 6901 WLAN_EID_VHT_TX_POWER_ENVELOPE); 6902 6903 /* Extract and add the extended capabilities and interworking IE */ 6904 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, 6905 WLAN_EID_EXT_CAPABILITY); 6906 6907 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, 6908 WLAN_EID_INTERWORKING); 6909 6910 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) 6911 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, 6912 WLAN_EID_RSN); 6913 6914 #ifdef FEATURE_WLAN_WAPI 6915 if (QDF_SAP_MODE == adapter->device_mode) { 6916 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, 6917 WLAN_EID_WAPI); 6918 } 6919 #endif 6920 6921 wlan_hdd_add_hostapd_conf_vsie(adapter, genie, 6922 &total_ielen); 6923 6924 ret = hdd_update_11ax_apies(adapter, genie, &total_ielen); 6925 if (ret) 6926 goto done; 6927 6928 wlan_hdd_add_sap_obss_scan_ie(adapter, genie, &total_ielen); 6929 6930 qdf_copy_macaddr(&updateIE.bssid, &adapter->mac_addr); 6931 updateIE.smeSessionId = adapter->session_id; 6932 6933 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 6934 updateIE.ieBufferlength = total_ielen; 6935 updateIE.pAdditionIEBuffer = genie; 6936 updateIE.append = false; 6937 updateIE.notify = true; 6938 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter), 6939 &updateIE, 6940 eUPDATE_IE_PROBE_BCN) == 6941 QDF_STATUS_E_FAILURE) { 6942 hdd_err("Could not pass on Add Ie probe beacon data"); 6943 ret = -EINVAL; 6944 goto done; 6945 } 6946 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN); 6947 } else { 6948 wlansap_update_sap_config_add_ie(pConfig, 6949 genie, 6950 total_ielen, 6951 eUPDATE_IE_PROBE_BCN); 6952 } 6953 6954 /* Added for Probe Response IE */ 6955 proberesp_ies = qdf_mem_malloc(beacon->proberesp_ies_len + 6956 MAX_GENIE_LEN); 6957 if (proberesp_ies == NULL) { 6958 hdd_err("mem alloc failed for probe resp ies, size: %d", 6959 beacon->proberesp_ies_len + MAX_GENIE_LEN); 6960 ret = -EINVAL; 6961 goto done; 6962 } 6963 qdf_mem_copy(proberesp_ies, beacon->proberesp_ies, 6964 beacon->proberesp_ies_len); 6965 proberesp_ies_len = beacon->proberesp_ies_len; 6966 6967 wlan_hdd_add_sap_obss_scan_ie(adapter, proberesp_ies, 6968 &proberesp_ies_len); 6969 6970 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 6971 updateIE.ieBufferlength = proberesp_ies_len; 6972 updateIE.pAdditionIEBuffer = proberesp_ies; 6973 updateIE.append = false; 6974 updateIE.notify = false; 6975 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter), 6976 &updateIE, 6977 eUPDATE_IE_PROBE_RESP) == 6978 QDF_STATUS_E_FAILURE) { 6979 hdd_err("Could not pass on PROBE_RESP add Ie data"); 6980 ret = -EINVAL; 6981 goto done; 6982 } 6983 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP); 6984 } else { 6985 wlansap_update_sap_config_add_ie(pConfig, 6986 proberesp_ies, 6987 proberesp_ies_len, 6988 eUPDATE_IE_PROBE_RESP); 6989 } 6990 6991 /* Assoc resp Add ie Data */ 6992 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 6993 updateIE.ieBufferlength = beacon->assocresp_ies_len; 6994 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies; 6995 updateIE.append = false; 6996 updateIE.notify = false; 6997 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter), 6998 &updateIE, 6999 eUPDATE_IE_ASSOC_RESP) == 7000 QDF_STATUS_E_FAILURE) { 7001 hdd_err("Could not pass on Add Ie Assoc Response data"); 7002 ret = -EINVAL; 7003 goto done; 7004 } 7005 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP); 7006 } else { 7007 wlansap_update_sap_config_add_ie(pConfig, 7008 beacon->assocresp_ies, 7009 beacon->assocresp_ies_len, 7010 eUPDATE_IE_ASSOC_RESP); 7011 } 7012 7013 done: 7014 qdf_mem_free(genie); 7015 qdf_mem_free(proberesp_ies); 7016 return ret; 7017 } 7018 7019 /** 7020 * wlan_hdd_set_sap_hwmode() - set sap hw mode 7021 * @adapter: Pointer to hostapd adapter 7022 * 7023 * Return: none 7024 */ 7025 static void wlan_hdd_set_sap_hwmode(struct hdd_adapter *adapter) 7026 { 7027 tsap_config_t *pConfig = &adapter->session.ap.sap_config; 7028 struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon; 7029 struct ieee80211_mgmt *pMgmt_frame = 7030 (struct ieee80211_mgmt *)pBeacon->head; 7031 u8 checkRatesfor11g = true; 7032 u8 require_ht = false, require_vht = false; 7033 const u8 *pIe = NULL; 7034 7035 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b; 7036 7037 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES, 7038 &pMgmt_frame->u.beacon.variable[0], 7039 pBeacon->head_len); 7040 if (pIe != NULL) { 7041 pIe += 1; 7042 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht, 7043 &checkRatesfor11g, &pConfig->SapHw_mode); 7044 } 7045 7046 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES, 7047 pBeacon->tail, pBeacon->tail_len); 7048 if (pIe != NULL) { 7049 pIe += 1; 7050 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht, 7051 &checkRatesfor11g, &pConfig->SapHw_mode); 7052 } 7053 7054 if (pConfig->channel > 14) 7055 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a; 7056 7057 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY, 7058 pBeacon->tail, pBeacon->tail_len); 7059 if (pIe) { 7060 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n; 7061 if (require_ht) 7062 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY; 7063 } 7064 7065 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_VHT_CAPABILITY, 7066 pBeacon->tail, pBeacon->tail_len); 7067 if (pIe) { 7068 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac; 7069 if (require_vht) 7070 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY; 7071 } 7072 7073 wlan_hdd_check_11ax_support(pBeacon, pConfig); 7074 7075 hdd_info("SAP hw_mode: %d", pConfig->SapHw_mode); 7076 } 7077 7078 /** 7079 * wlan_hdd_config_acs() - config ACS needed parameters 7080 * @hdd_ctx: HDD context 7081 * @adapter: Adapter pointer 7082 * 7083 * This function get ACS related INI parameters and populated 7084 * sap config and smeConfig for ACS needed configurations. 7085 * 7086 * Return: The QDF_STATUS code associated with performing the operation. 7087 */ 7088 QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) 7089 { 7090 tsap_config_t *sap_config; 7091 struct hdd_config *ini_config; 7092 tHalHandle hal; 7093 7094 hal = WLAN_HDD_GET_HAL_CTX(adapter); 7095 sap_config = &adapter->session.ap.sap_config; 7096 ini_config = hdd_ctx->config; 7097 7098 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh; 7099 7100 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 7101 hdd_debug("HDD_ACS_SKIP_STATUS = %d", 7102 hdd_ctx->skip_acs_scan_status); 7103 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) { 7104 struct hdd_adapter *con_sap_adapter; 7105 tsap_config_t *con_sap_config = NULL; 7106 7107 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false); 7108 7109 if (con_sap_adapter) 7110 con_sap_config = 7111 &con_sap_adapter->session.ap.sap_config; 7112 7113 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN; 7114 7115 if (con_sap_config && 7116 con_sap_config->acs_cfg.acs_mode == true && 7117 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN && 7118 con_sap_config->acs_cfg.hw_mode == 7119 sap_config->acs_cfg.hw_mode) { 7120 uint8_t con_sap_st_ch, con_sap_end_ch; 7121 uint8_t cur_sap_st_ch, cur_sap_end_ch; 7122 uint8_t bandStartChannel, bandEndChannel; 7123 7124 con_sap_st_ch = 7125 con_sap_config->acs_cfg.start_ch; 7126 con_sap_end_ch = 7127 con_sap_config->acs_cfg.end_ch; 7128 cur_sap_st_ch = sap_config->acs_cfg.start_ch; 7129 cur_sap_end_ch = sap_config->acs_cfg.end_ch; 7130 7131 wlansap_extend_to_acs_range(hal, &cur_sap_st_ch, 7132 &cur_sap_end_ch, &bandStartChannel, 7133 &bandEndChannel); 7134 7135 wlansap_extend_to_acs_range(hal, 7136 &con_sap_st_ch, &con_sap_end_ch, 7137 &bandStartChannel, &bandEndChannel); 7138 7139 if (con_sap_st_ch <= cur_sap_st_ch && 7140 con_sap_end_ch >= cur_sap_end_ch) { 7141 sap_config->acs_cfg.skip_scan_status = 7142 eSAP_SKIP_ACS_SCAN; 7143 7144 } else if (con_sap_st_ch >= cur_sap_st_ch && 7145 con_sap_end_ch >= cur_sap_end_ch) { 7146 sap_config->acs_cfg.skip_scan_status = 7147 eSAP_DO_PAR_ACS_SCAN; 7148 7149 sap_config->acs_cfg.skip_scan_range1_stch = 7150 cur_sap_st_ch; 7151 sap_config->acs_cfg.skip_scan_range1_endch = 7152 con_sap_st_ch - 1; 7153 sap_config->acs_cfg.skip_scan_range2_stch = 7154 0; 7155 sap_config->acs_cfg.skip_scan_range2_endch = 7156 0; 7157 7158 } else if (con_sap_st_ch <= cur_sap_st_ch && 7159 con_sap_end_ch <= cur_sap_end_ch) { 7160 sap_config->acs_cfg.skip_scan_status = 7161 eSAP_DO_PAR_ACS_SCAN; 7162 7163 sap_config->acs_cfg.skip_scan_range1_stch = 7164 con_sap_end_ch + 1; 7165 sap_config->acs_cfg.skip_scan_range1_endch = 7166 cur_sap_end_ch; 7167 sap_config->acs_cfg.skip_scan_range2_stch = 7168 0; 7169 sap_config->acs_cfg.skip_scan_range2_endch = 7170 0; 7171 7172 } else if (con_sap_st_ch >= cur_sap_st_ch && 7173 con_sap_end_ch <= cur_sap_end_ch) { 7174 sap_config->acs_cfg.skip_scan_status = 7175 eSAP_DO_PAR_ACS_SCAN; 7176 7177 sap_config->acs_cfg.skip_scan_range1_stch = 7178 cur_sap_st_ch; 7179 sap_config->acs_cfg.skip_scan_range1_endch = 7180 con_sap_st_ch - 1; 7181 sap_config->acs_cfg.skip_scan_range2_stch = 7182 con_sap_end_ch; 7183 sap_config->acs_cfg.skip_scan_range2_endch = 7184 cur_sap_end_ch + 1; 7185 7186 } else 7187 sap_config->acs_cfg.skip_scan_status = 7188 eSAP_DO_NEW_ACS_SCAN; 7189 7190 7191 hdd_debug("SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d", 7192 sap_config->acs_cfg.skip_scan_status, 7193 sap_config->acs_cfg.skip_scan_range1_stch, 7194 sap_config->acs_cfg.skip_scan_range1_endch, 7195 sap_config->acs_cfg.skip_scan_range2_stch, 7196 sap_config->acs_cfg.skip_scan_range2_endch); 7197 } 7198 } 7199 #endif 7200 7201 return QDF_STATUS_SUCCESS; 7202 } 7203 7204 /** 7205 * wlan_hdd_sap_p2p_11ac_overrides: API to overwrite 11ac config in case of 7206 * SAP or p2p go 7207 * @ap_adapter: pointer to adapter 7208 * 7209 * This function overrides SAP / P2P Go configuration based on driver INI 7210 * parameters for 11AC override and ACS. This overrides are done to support 7211 * android legacy configuration method. 7212 * 7213 * NOTE: Non android platform supports concurrency and these overrides shall 7214 * not be used. Also future driver based overrides shall be consolidated in this 7215 * function only. Avoid random overrides in other location based on ini. 7216 * 7217 * Return: 0 for Success or Negative error codes. 7218 */ 7219 static int wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter *ap_adapter) 7220 { 7221 tsap_config_t *sap_cfg = &ap_adapter->session.ap.sap_config; 7222 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 7223 7224 /* Fixed channel 11AC override: 7225 * 11AC override in qcacld is introduced for following reasons: 7226 * 1. P2P GO also follows start_bss and since p2p GO could not be 7227 * configured to setup VHT channel width in wpa_supplicant 7228 * 2. Android UI does not provide advanced configuration options for SAP 7229 * 7230 * Default override enabled (for android). MDM shall disable this in ini 7231 */ 7232 /* 7233 * sub_20 MHz channel width is incompatible with 11AC rates, hence do 7234 * not allow 11AC rates or more than 20 MHz channel width when 7235 * enable_sub_20_channel_width is non zero 7236 */ 7237 if (!hdd_ctx->config->enable_sub_20_channel_width && 7238 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n || 7239 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac || 7240 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY || 7241 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax || 7242 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax_ONLY) && 7243 ((ap_adapter->device_mode == QDF_SAP_MODE && 7244 !hdd_ctx->config->sap_force_11n_for_11ac && 7245 hdd_ctx->config->sap_11ac_override) || 7246 (ap_adapter->device_mode == QDF_P2P_GO_MODE && 7247 !hdd_ctx->config->go_force_11n_for_11ac && 7248 hdd_ctx->config->go_11ac_override))) { 7249 hdd_debug("** Driver force 11AC override for SAP/Go **"); 7250 7251 /* 11n only shall not be overridden since it may be on purpose*/ 7252 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n) 7253 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac; 7254 7255 if (sap_cfg->channel >= 36) { 7256 sap_cfg->ch_width_orig = 7257 hdd_ctx->config->vhtChannelWidth; 7258 } else { 7259 /* 7260 * Allow 40 Mhz in 2.4 Ghz only if indicated by 7261 * supplicant after OBSS scan and if 2.4 Ghz channel 7262 * bonding is set in INI 7263 */ 7264 if (sap_cfg->ch_width_orig >= eHT_CHANNEL_WIDTH_40MHZ && 7265 hdd_ctx->config->nChannelBondingMode24GHz) 7266 sap_cfg->ch_width_orig = 7267 eHT_CHANNEL_WIDTH_40MHZ; 7268 else 7269 sap_cfg->ch_width_orig = 7270 eHT_CHANNEL_WIDTH_20MHZ; 7271 } 7272 } 7273 7274 sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig; 7275 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, sap_cfg->channel, 7276 sap_cfg->sec_ch, &sap_cfg->ch_params); 7277 7278 return 0; 7279 } 7280 7281 /** 7282 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params 7283 * @adapter: pointer to adapter struct 7284 * 7285 * This function overrides SAP / P2P Go configuration based on driver INI 7286 * parameters for 11AC override and ACS. These overrides are done to support 7287 * android legacy configuration method. 7288 * 7289 * NOTE: Non android platform supports concurrency and these overrides shall 7290 * not be used. Also future driver based overrides shall be consolidated in this 7291 * function only. Avoid random overrides in other location based on ini. 7292 * 7293 * Return: 0 for Success or Negative error codes. 7294 */ 7295 static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter) 7296 { 7297 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 7298 7299 if (!hdd_ctx->config->vendor_acs_support) 7300 return wlan_hdd_sap_p2p_11ac_overrides(ap_adapter); 7301 else 7302 return 0; 7303 } 7304 7305 /** 7306 * wlan_hdd_cfg80211_start_bss() - start bss 7307 * @adapter: Pointer to hostapd adapter 7308 * @params: Pointer to start bss beacon parameters 7309 * @ssid: Pointer ssid 7310 * @ssid_len: Length of ssid 7311 * @hidden_ssid: Hidden SSID parameter 7312 * @check_for_concurrency: Flag to indicate if check for concurrency is needed 7313 * 7314 * Return: 0 for success non-zero for failure 7315 */ 7316 int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, 7317 struct cfg80211_beacon_data *params, 7318 const u8 *ssid, size_t ssid_len, 7319 enum nl80211_hidden_ssid hidden_ssid, 7320 bool check_for_concurrency) 7321 { 7322 tsap_config_t *pConfig; 7323 struct hdd_beacon_data *pBeacon = NULL; 7324 struct ieee80211_mgmt *pMgmt_frame; 7325 const uint8_t *pIe = NULL; 7326 uint16_t capab_info; 7327 eCsrAuthType RSNAuthType; 7328 eCsrEncryptionType RSNEncryptType; 7329 eCsrEncryptionType mcRSNEncryptType; 7330 int status = QDF_STATUS_SUCCESS, ret; 7331 int qdf_status = QDF_STATUS_SUCCESS; 7332 tpWLAN_SAPEventCB pSapEventCallback; 7333 struct hdd_hostapd_state *hostapd_state; 7334 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter); 7335 struct qc_mac_acl_entry *acl_entry = NULL; 7336 int32_t i; 7337 struct hdd_config *iniConfig; 7338 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7339 tSmeConfigParams *sme_config; 7340 bool MFPCapable = false; 7341 bool MFPRequired = false; 7342 uint16_t prev_rsn_length = 0; 7343 enum dfs_mode mode; 7344 struct hdd_adapter *sta_adapter; 7345 7346 hdd_enter(); 7347 7348 hdd_notify_teardown_tdls_links(adapter->hdd_vdev); 7349 7350 if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->hdd_psoc)) { 7351 status = policy_mgr_wait_for_connection_update( 7352 hdd_ctx->hdd_psoc); 7353 if (!QDF_IS_STATUS_SUCCESS(status)) { 7354 hdd_err("qdf wait for event failed!!"); 7355 return -EINVAL; 7356 } 7357 } 7358 7359 /* 7360 * For STA+SAP concurrency support from GUI, first STA connection gets 7361 * triggered and while it is in progress, SAP start also comes up. 7362 * Once STA association is successful, STA connect event is sent to 7363 * kernel which gets queued in kernel workqueue and supplicant won't 7364 * process M1 received from AP and send M2 until this NL80211_CONNECT 7365 * event is received. Workqueue is not scheduled as RTNL lock is already 7366 * taken by hostapd thread which has issued start_bss command to driver. 7367 * Driver cannot complete start_bss as the pending command at the head 7368 * of the SME command pending list is hw_mode_update for STA session 7369 * which cannot be processed as SME is in WAITforKey state for STA 7370 * interface. The start_bss command for SAP interface is queued behind 7371 * the hw_mode_update command and so it cannot be processed until 7372 * hw_mode_update command is processed. This is causing a deadlock so 7373 * disconnect the STA interface first if connection or key exchange is 7374 * in progress and then start SAP interface. 7375 */ 7376 sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx); 7377 if (sta_adapter) { 7378 hdd_debug("Disconnecting STA with session id: %d", 7379 sta_adapter->session_id); 7380 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH); 7381 } 7382 7383 sme_config = qdf_mem_malloc(sizeof(*sme_config)); 7384 if (!sme_config) { 7385 hdd_err("failed to allocate memory"); 7386 return -ENOMEM; 7387 } 7388 7389 iniConfig = hdd_ctx->config; 7390 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 7391 7392 clear_bit(ACS_PENDING, &adapter->event_flags); 7393 clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags); 7394 7395 /* Mark the indoor channel (passive) to disable */ 7396 if (iniConfig->force_ssc_disable_indoor_channel) { 7397 hdd_update_indoor_channel(hdd_ctx, true); 7398 if (QDF_IS_STATUS_ERROR( 7399 sme_update_channel_list(hdd_ctx->hHal))) { 7400 hdd_update_indoor_channel(hdd_ctx, false); 7401 hdd_err("Can't start BSS: update channel list failed"); 7402 qdf_mem_free(sme_config); 7403 return -EINVAL; 7404 } 7405 } 7406 7407 pConfig = &adapter->session.ap.sap_config; 7408 7409 pBeacon = adapter->session.ap.beacon; 7410 7411 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head; 7412 7413 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int; 7414 pConfig->dfs_cac_offload = hdd_ctx->dfs_cac_offload; 7415 7416 pConfig->auto_channel_select_weight = 7417 iniConfig->auto_channel_select_weight; 7418 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch; 7419 pConfig->sap_chanswitch_beacon_cnt = 7420 iniConfig->sap_chanswitch_beacon_cnt; 7421 pConfig->sap_chanswitch_mode = iniConfig->sap_chanswitch_mode; 7422 7423 /* channel is already set in the set_channel Call back */ 7424 /* pConfig->channel = pCommitConfig->channel; */ 7425 7426 /* Protection parameter to enable or disable */ 7427 pConfig->protEnabled = iniConfig->apProtEnabled; 7428 7429 pConfig->chan_switch_hostapd_rate_enabled = 7430 iniConfig->chan_switch_hostapd_rate_enabled; 7431 7432 if (iniConfig->WlanMccToSccSwitchMode != 7433 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 7434 pConfig->chan_switch_hostapd_rate_enabled = false; 7435 } 7436 7437 pConfig->enOverLapCh = iniConfig->gEnableOverLapCh; 7438 pConfig->dtim_period = pBeacon->dtim_period; 7439 pConfig->dfs_beacon_tx_enhanced = iniConfig->dfs_beacon_tx_enhanced; 7440 pConfig->reduced_beacon_interval = 7441 iniConfig->reduced_beacon_interval; 7442 hdd_debug("acs_mode %d", pConfig->acs_cfg.acs_mode); 7443 7444 if (pConfig->acs_cfg.acs_mode == true) { 7445 hdd_debug("acs_channel %d, acs_dfs_mode %d", 7446 hdd_ctx->acs_policy.acs_channel, 7447 hdd_ctx->acs_policy.acs_dfs_mode); 7448 7449 if (hdd_ctx->acs_policy.acs_channel) 7450 pConfig->channel = hdd_ctx->acs_policy.acs_channel; 7451 mode = hdd_ctx->acs_policy.acs_dfs_mode; 7452 pConfig->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode); 7453 } 7454 7455 hdd_debug("pConfig->channel %d, pConfig->acs_dfs_mode %d", 7456 pConfig->channel, pConfig->acs_dfs_mode); 7457 7458 hdd_debug("****pConfig->dtim_period=%d***", 7459 pConfig->dtim_period); 7460 7461 if (adapter->device_mode == QDF_SAP_MODE) { 7462 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_COUNTRY, 7463 pBeacon->tail, pBeacon->tail_len); 7464 if (pIe) { 7465 if (pIe[1] < IEEE80211_COUNTRY_IE_MIN_LEN) { 7466 hdd_err("Invalid Country IE len: %d", pIe[1]); 7467 ret = -EINVAL; 7468 goto error; 7469 } 7470 7471 pConfig->ieee80211d = 1; 7472 qdf_mem_copy(pConfig->countryCode, &pIe[2], 3); 7473 status = ucfg_reg_set_country(hdd_ctx->hdd_pdev, 7474 pConfig->countryCode); 7475 if (QDF_IS_STATUS_ERROR(status)) { 7476 hdd_err("Failed to set country"); 7477 pConfig->ieee80211d = 0; 7478 } 7479 } else { 7480 pConfig->countryCode[0] = hdd_ctx->reg.alpha2[0]; 7481 pConfig->countryCode[1] = hdd_ctx->reg.alpha2[1]; 7482 pConfig->ieee80211d = 0; 7483 } 7484 7485 ret = wlan_hdd_sap_cfg_dfs_override(adapter); 7486 if (ret < 0) { 7487 goto error; 7488 } else { 7489 if (ret == 0) { 7490 if (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev, 7491 pConfig->channel)) 7492 hdd_ctx->dev_dfs_cac_status = 7493 DFS_CAC_NEVER_DONE; 7494 } 7495 } 7496 7497 /* 7498 * If auto channel is configured i.e. channel is 0, 7499 * so skip channel validation. 7500 */ 7501 if (AUTO_CHANNEL_SELECT != pConfig->channel) { 7502 if (QDF_STATUS_SUCCESS != 7503 wlan_hdd_validate_operation_channel(adapter, 7504 pConfig->channel)) { 7505 hdd_err("Invalid Channel: %d", pConfig->channel); 7506 ret = -EINVAL; 7507 goto error; 7508 } 7509 7510 /* reject SAP if DFS channel scan is not allowed */ 7511 if (!(hdd_ctx->config->enableDFSChnlScan) && 7512 (CHANNEL_STATE_DFS == 7513 wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, 7514 pConfig->channel))) { 7515 hdd_err("No SAP start on DFS channel"); 7516 ret = -EOPNOTSUPP; 7517 goto error; 7518 } 7519 } 7520 wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC); 7521 wlansap_set_dfs_restrict_japan_w53(hHal, 7522 iniConfig->gDisableDfsJapanW53); 7523 wlansap_set_dfs_preferred_channel_location(hHal, 7524 iniConfig->gSapPreferredChanLocation); 7525 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 7526 wlan_sap_set_channel_avoidance(hHal, 7527 iniConfig->sap_channel_avoidance); 7528 #endif 7529 } else if (adapter->device_mode == QDF_P2P_GO_MODE) { 7530 pConfig->countryCode[0] = hdd_ctx->reg.alpha2[0]; 7531 pConfig->countryCode[1] = hdd_ctx->reg.alpha2[1]; 7532 pConfig->ieee80211d = 0; 7533 } else { 7534 pConfig->ieee80211d = 0; 7535 } 7536 7537 wlansap_set_tx_leakage_threshold(hHal, 7538 iniConfig->sap_tx_leakage_threshold); 7539 7540 capab_info = pMgmt_frame->u.beacon.capab_info; 7541 7542 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info & 7543 WLAN_CAPABILITY_PRIVACY) ? true : false; 7544 7545 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->privacy = pConfig->privacy; 7546 7547 /*Set wps station to configured */ 7548 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len); 7549 7550 if (pIe) { 7551 if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) { 7552 hdd_err("**Wps Ie Length is too small***"); 7553 ret = -EINVAL; 7554 goto error; 7555 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 7556 0) { 7557 hdd_debug("** WPS IE(len %d) ***", (pIe[1] + 2)); 7558 /* Check 15 bit of WPS IE as it contain information for 7559 * wps state 7560 */ 7561 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) { 7562 pConfig->wps_state = 7563 SAP_WPS_ENABLED_UNCONFIGURED; 7564 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) { 7565 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED; 7566 } 7567 } 7568 } else { 7569 hdd_debug("WPS disabled"); 7570 pConfig->wps_state = SAP_WPS_DISABLED; 7571 } 7572 /* Forward WPS PBC probe request frame up */ 7573 pConfig->fwdWPSPBCProbeReq = 1; 7574 7575 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE; 7576 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE; 7577 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->encryption_type = 7578 eCSR_ENCRYPT_TYPE_NONE; 7579 7580 pConfig->RSNWPAReqIELength = 0; 7581 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE)); 7582 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, pBeacon->tail, 7583 pBeacon->tail_len); 7584 if (pIe && pIe[1]) { 7585 pConfig->RSNWPAReqIELength = pIe[1] + 2; 7586 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE)) 7587 memcpy(&pConfig->RSNWPAReqIE[0], pIe, 7588 pConfig->RSNWPAReqIELength); 7589 else 7590 hdd_err("RSNWPA IE MAX Length exceeded; length =%d", 7591 pConfig->RSNWPAReqIELength); 7592 /* The actual processing may eventually be more extensive than 7593 * this. Right now, just consume any PMKIDs that are sent in 7594 * by the app. 7595 */ 7596 status = 7597 hdd_softap_unpack_ie(cds_get_context 7598 (QDF_MODULE_ID_SME), 7599 &RSNEncryptType, &mcRSNEncryptType, 7600 &RSNAuthType, &MFPCapable, 7601 &MFPRequired, 7602 pConfig->RSNWPAReqIE[1] + 2, 7603 pConfig->RSNWPAReqIE); 7604 7605 if (QDF_STATUS_SUCCESS == status) { 7606 /* Now copy over all the security attributes you have 7607 * parsed out. Use the cipher type in the RSN IE 7608 */ 7609 pConfig->RSNEncryptType = RSNEncryptType; 7610 pConfig->mcRSNEncryptType = mcRSNEncryptType; 7611 (WLAN_HDD_GET_AP_CTX_PTR(adapter))-> 7612 encryption_type = RSNEncryptType; 7613 hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d", 7614 RSNAuthType, RSNEncryptType, mcRSNEncryptType); 7615 } 7616 } 7617 7618 pIe = wlan_get_vendor_ie_ptr_from_oui(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE, 7619 pBeacon->tail, pBeacon->tail_len); 7620 7621 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) { 7622 if (pConfig->RSNWPAReqIE[0]) { 7623 /*Mixed mode WPA/WPA2 */ 7624 prev_rsn_length = pConfig->RSNWPAReqIELength; 7625 pConfig->RSNWPAReqIELength += pIe[1] + 2; 7626 if (pConfig->RSNWPAReqIELength < 7627 sizeof(pConfig->RSNWPAReqIE)) 7628 memcpy(&pConfig->RSNWPAReqIE[0] + 7629 prev_rsn_length, pIe, pIe[1] + 2); 7630 else 7631 hdd_err("RSNWPA IE MAX Length exceeded; length: %d", 7632 pConfig->RSNWPAReqIELength); 7633 } else { 7634 pConfig->RSNWPAReqIELength = pIe[1] + 2; 7635 if (pConfig->RSNWPAReqIELength < 7636 sizeof(pConfig->RSNWPAReqIE)) 7637 memcpy(&pConfig->RSNWPAReqIE[0], pIe, 7638 pConfig->RSNWPAReqIELength); 7639 else 7640 hdd_err("RSNWPA IE MAX Length exceeded; length: %d", 7641 pConfig->RSNWPAReqIELength); 7642 status = hdd_softap_unpack_ie 7643 (cds_get_context(QDF_MODULE_ID_SME), 7644 &RSNEncryptType, 7645 &mcRSNEncryptType, &RSNAuthType, 7646 &MFPCapable, &MFPRequired, 7647 pConfig->RSNWPAReqIE[1] + 2, 7648 pConfig->RSNWPAReqIE); 7649 7650 if (QDF_STATUS_SUCCESS == status) { 7651 /* Now copy over all the security attributes 7652 * you have parsed out. Use the cipher type 7653 * in the RSN IE 7654 */ 7655 pConfig->RSNEncryptType = RSNEncryptType; 7656 pConfig->mcRSNEncryptType = mcRSNEncryptType; 7657 (WLAN_HDD_GET_AP_CTX_PTR(adapter))-> 7658 encryption_type = RSNEncryptType; 7659 hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d", 7660 RSNAuthType, RSNEncryptType, 7661 mcRSNEncryptType); 7662 } 7663 } 7664 } 7665 7666 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) { 7667 hdd_err("**RSNWPAReqIELength is too large***"); 7668 ret = -EINVAL; 7669 goto error; 7670 } 7671 7672 pConfig->SSIDinfo.ssidHidden = false; 7673 7674 if (ssid != NULL) { 7675 qdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len); 7676 pConfig->SSIDinfo.ssid.length = ssid_len; 7677 7678 switch (hidden_ssid) { 7679 case NL80211_HIDDEN_SSID_NOT_IN_USE: 7680 hdd_debug("HIDDEN_SSID_NOT_IN_USE"); 7681 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE; 7682 break; 7683 case NL80211_HIDDEN_SSID_ZERO_LEN: 7684 hdd_debug("HIDDEN_SSID_ZERO_LEN"); 7685 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN; 7686 break; 7687 case NL80211_HIDDEN_SSID_ZERO_CONTENTS: 7688 hdd_debug("HIDDEN_SSID_ZERO_CONTENTS"); 7689 pConfig->SSIDinfo.ssidHidden = 7690 eHIDDEN_SSID_ZERO_CONTENTS; 7691 break; 7692 default: 7693 hdd_err("Wrong hidden_ssid param: %d", hidden_ssid); 7694 break; 7695 } 7696 } 7697 7698 qdf_mem_copy(pConfig->self_macaddr.bytes, 7699 adapter->mac_addr.bytes, 7700 QDF_MAC_ADDR_SIZE); 7701 7702 /* default value */ 7703 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED; 7704 pConfig->num_accept_mac = 0; 7705 pConfig->num_deny_mac = 0; 7706 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 7707 /* 7708 * We don't want P2PGO to follow STA's channel 7709 * so lets limit the logic for SAP only. 7710 * Later if we decide to make p2pgo follow STA's 7711 * channel then remove this check. 7712 */ 7713 if ((0 == hdd_ctx->config->conc_custom_rule1) || 7714 (hdd_ctx->config->conc_custom_rule1 && 7715 QDF_SAP_MODE == adapter->device_mode)) 7716 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode; 7717 #endif 7718 7719 pIe = wlan_get_vendor_ie_ptr_from_oui(BLACKLIST_OUI_TYPE, 7720 WPA_OUI_TYPE_SIZE, pBeacon->tail, 7721 pBeacon->tail_len); 7722 7723 /* pIe for black list is following form: 7724 * type : 1 byte 7725 * length : 1 byte 7726 * OUI : 4 bytes 7727 * acl type : 1 byte 7728 * no of mac addr in black list: 1 byte 7729 * list of mac_acl_entries: variable, 6 bytes per mac 7730 * address + sizeof(int) for vlan id 7731 */ 7732 if ((pIe != NULL) && (pIe[1] != 0)) { 7733 pConfig->SapMacaddr_acl = pIe[6]; 7734 pConfig->num_deny_mac = pIe[7]; 7735 hdd_debug("acl type = %d no deny mac = %d", pIe[6], pIe[7]); 7736 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS) 7737 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS; 7738 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); 7739 for (i = 0; i < pConfig->num_deny_mac; i++) { 7740 qdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, 7741 sizeof(qcmacaddr)); 7742 acl_entry++; 7743 } 7744 } 7745 pIe = wlan_get_vendor_ie_ptr_from_oui(WHITELIST_OUI_TYPE, 7746 WPA_OUI_TYPE_SIZE, pBeacon->tail, 7747 pBeacon->tail_len); 7748 7749 /* pIe for white list is following form: 7750 * type : 1 byte 7751 * length : 1 byte 7752 * OUI : 4 bytes 7753 * acl type : 1 byte 7754 * no of mac addr in white list: 1 byte 7755 * list of mac_acl_entries: variable, 6 bytes per mac 7756 * address + sizeof(int) for vlan id 7757 */ 7758 if ((pIe != NULL) && (pIe[1] != 0)) { 7759 pConfig->SapMacaddr_acl = pIe[6]; 7760 pConfig->num_accept_mac = pIe[7]; 7761 hdd_debug("acl type = %d no accept mac = %d", 7762 pIe[6], pIe[7]); 7763 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS) 7764 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS; 7765 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); 7766 for (i = 0; i < pConfig->num_accept_mac; i++) { 7767 qdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, 7768 sizeof(qcmacaddr)); 7769 acl_entry++; 7770 } 7771 } 7772 if (!(ssid && qdf_str_len(PRE_CAC_SSID) == ssid_len && 7773 (0 == qdf_mem_cmp(ssid, PRE_CAC_SSID, ssid_len)))) { 7774 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES, 7775 &pMgmt_frame->u.beacon.variable[0], 7776 pBeacon->head_len); 7777 7778 if (pIe != NULL) { 7779 pIe++; 7780 pConfig->supported_rates.numRates = pIe[0]; 7781 pIe++; 7782 for (i = 0; 7783 i < pConfig->supported_rates.numRates; i++) { 7784 if (pIe[i]) { 7785 pConfig->supported_rates.rate[i] = pIe[i]; 7786 hdd_debug("Configured Supported rate is %2x", 7787 pConfig->supported_rates.rate[i]); 7788 } 7789 } 7790 } 7791 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES, 7792 pBeacon->tail, 7793 pBeacon->tail_len); 7794 if (pIe != NULL) { 7795 pIe++; 7796 pConfig->extended_rates.numRates = pIe[0]; 7797 pIe++; 7798 for (i = 0; i < pConfig->extended_rates.numRates; i++) { 7799 if (pIe[i]) { 7800 pConfig->extended_rates.rate[i] = pIe[i]; 7801 hdd_debug("Configured ext Supported rate is %2x", 7802 pConfig->extended_rates.rate[i]); 7803 } 7804 } 7805 } 7806 } 7807 7808 if (!cds_is_sub_20_mhz_enabled()) 7809 wlan_hdd_set_sap_hwmode(adapter); 7810 7811 if (((adapter->device_mode == QDF_SAP_MODE) && 7812 (hdd_ctx->config->sap_force_11n_for_11ac)) || 7813 ((adapter->device_mode == QDF_P2P_GO_MODE) && 7814 (hdd_ctx->config->go_force_11n_for_11ac))) { 7815 if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac || 7816 pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) 7817 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n; 7818 } 7819 7820 qdf_mem_zero(sme_config, sizeof(*sme_config)); 7821 sme_get_config_param(hdd_ctx->hHal, sme_config); 7822 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT) 7823 * As per spec 11N/AC STA are QOS STA and may not connect or throughput 7824 * may not be good with non QOS 11N AP 7825 * Default: enable QOS for SAP unless WMM IE not present for 11bga 7826 */ 7827 sme_config->csrConfig.WMMSupportMode = eCsrRoamWmmAuto; 7828 pIe = wlan_get_vendor_ie_ptr_from_oui(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE, 7829 pBeacon->tail, pBeacon->tail_len); 7830 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a || 7831 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g || 7832 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b)) 7833 sme_config->csrConfig.WMMSupportMode = eCsrRoamWmmNoQos; 7834 sme_update_config(hdd_ctx->hHal, sme_config); 7835 7836 if (!((adapter->device_mode == QDF_SAP_MODE) && 7837 (hdd_ctx->config->sap_force_11n_for_11ac)) || 7838 ((adapter->device_mode == QDF_P2P_GO_MODE) && 7839 (hdd_ctx->config->go_force_11n_for_11ac))) { 7840 pConfig->ch_width_orig = 7841 hdd_map_nl_chan_width(pConfig->ch_width_orig); 7842 } else { 7843 if (pConfig->ch_width_orig >= NL80211_CHAN_WIDTH_40) 7844 pConfig->ch_width_orig = CH_WIDTH_40MHZ; 7845 else 7846 pConfig->ch_width_orig = CH_WIDTH_20MHZ; 7847 } 7848 7849 if (wlan_hdd_setup_driver_overrides(adapter)) { 7850 ret = -EINVAL; 7851 goto error; 7852 } 7853 7854 /* ht_capab is not what the name conveys, 7855 * this is used for protection bitmap 7856 */ 7857 pConfig->ht_capab = iniConfig->apProtection; 7858 7859 if (0 != wlan_hdd_cfg80211_update_apies(adapter)) { 7860 hdd_err("SAP Not able to set AP IEs"); 7861 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL); 7862 ret = -EINVAL; 7863 goto error; 7864 } 7865 /* Uapsd Enabled Bit */ 7866 pConfig->UapsdEnable = iniConfig->apUapsdEnabled; 7867 /* Enable OBSS protection */ 7868 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled; 7869 7870 if (adapter->device_mode == QDF_SAP_MODE) 7871 pConfig->sap_dot11mc = 7872 (WLAN_HDD_GET_CTX(adapter))->config->sap_dot11mc; 7873 else /* for P2P-Go case */ 7874 pConfig->sap_dot11mc = 1; 7875 7876 hdd_debug("11MC Support Enabled : %d\n", 7877 pConfig->sap_dot11mc); 7878 7879 #ifdef WLAN_FEATURE_11W 7880 pConfig->mfpCapable = MFPCapable; 7881 pConfig->mfpRequired = MFPRequired; 7882 hdd_debug("Soft AP MFP capable %d, MFP required %d", 7883 pConfig->mfpCapable, pConfig->mfpRequired); 7884 #endif 7885 7886 hdd_debug("SOftAP macaddress : " MAC_ADDRESS_STR, 7887 MAC_ADDR_ARRAY(adapter->mac_addr.bytes)); 7888 hdd_debug("ssid =%s, beaconint=%d, channel=%d", 7889 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int, 7890 (int)pConfig->channel); 7891 hdd_debug("hw_mode=%x, privacy=%d, authType=%d", 7892 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType); 7893 hdd_debug("RSN/WPALen=%d, Uapsd = %d", 7894 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable); 7895 hdd_debug("ProtEnabled = %d, OBSSProtEnabled = %d", 7896 pConfig->protEnabled, pConfig->obssProtEnabled); 7897 hdd_debug("ChanSwitchHostapdRateEnabled = %d", 7898 pConfig->chan_switch_hostapd_rate_enabled); 7899 7900 mutex_lock(&hdd_ctx->sap_lock); 7901 if (cds_is_driver_unloading()) { 7902 mutex_unlock(&hdd_ctx->sap_lock); 7903 7904 hdd_err("The driver is unloading, ignore the bss starting"); 7905 ret = -EINVAL; 7906 goto error; 7907 } 7908 7909 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 7910 mutex_unlock(&hdd_ctx->sap_lock); 7911 7912 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL); 7913 /* Bss already started. just return. */ 7914 /* TODO Probably it should update some beacon params. */ 7915 hdd_debug("Bss Already started...Ignore the request"); 7916 hdd_exit(); 7917 ret = 0; 7918 goto free; 7919 } 7920 7921 if (check_for_concurrency) { 7922 if (!policy_mgr_allow_concurrency(hdd_ctx->hdd_psoc, 7923 policy_mgr_convert_device_mode_to_qdf_type( 7924 adapter->device_mode), 7925 pConfig->channel, HW_MODE_20_MHZ)) { 7926 mutex_unlock(&hdd_ctx->sap_lock); 7927 7928 hdd_err("This concurrency combination is not allowed"); 7929 ret = -EINVAL; 7930 goto error; 7931 } 7932 } 7933 7934 if (!hdd_set_connection_in_progress(true)) { 7935 mutex_unlock(&hdd_ctx->sap_lock); 7936 7937 hdd_err("Can't start BSS: set connection in progress failed"); 7938 ret = -EINVAL; 7939 goto error; 7940 } 7941 7942 pConfig->persona = adapter->device_mode; 7943 7944 pSapEventCallback = hdd_hostapd_sap_event_cb; 7945 7946 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->dfs_cac_block_tx = true; 7947 set_bit(SOFTAP_INIT_DONE, &adapter->event_flags); 7948 7949 qdf_event_reset(&hostapd_state->qdf_event); 7950 status = wlansap_start_bss( 7951 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 7952 pSapEventCallback, pConfig, adapter->dev); 7953 if (!QDF_IS_STATUS_SUCCESS(status)) { 7954 mutex_unlock(&hdd_ctx->sap_lock); 7955 7956 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL); 7957 hdd_set_connection_in_progress(false); 7958 hdd_err("SAP Start Bss fail"); 7959 ret = -EINVAL; 7960 goto error; 7961 } 7962 7963 hdd_debug("Waiting for Scan to complete(auto mode) and BSS to start"); 7964 7965 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, 7966 SME_CMD_TIMEOUT_VALUE); 7967 7968 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL); 7969 7970 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 7971 mutex_unlock(&hdd_ctx->sap_lock); 7972 7973 hdd_err("qdf wait for single_event failed!!"); 7974 hdd_set_connection_in_progress(false); 7975 sme_get_command_q_status(hHal); 7976 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); 7977 QDF_ASSERT(0); 7978 ret = -EINVAL; 7979 goto error; 7980 } 7981 /* Successfully started Bss update the state bit. */ 7982 set_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); 7983 7984 mutex_unlock(&hdd_ctx->sap_lock); 7985 7986 /* Initialize WMM configuation */ 7987 hdd_wmm_init(adapter); 7988 if (hostapd_state->bss_state == BSS_START) { 7989 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc, 7990 adapter->device_mode, 7991 adapter->session_id); 7992 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 7993 true); 7994 } 7995 #ifdef DHCP_SERVER_OFFLOAD 7996 if (iniConfig->enableDHCPServerOffload) 7997 wlan_hdd_set_dhcp_server_offload(adapter); 7998 #endif /* DHCP_SERVER_OFFLOAD */ 7999 8000 ucfg_p2p_status_start_bss(adapter->hdd_vdev); 8001 8002 /* Check and restart SAP if it is on unsafe channel */ 8003 hdd_unsafe_channel_restart_sap(hdd_ctx); 8004 8005 hdd_set_connection_in_progress(false); 8006 hdd_exit(); 8007 8008 ret = 0; 8009 goto free; 8010 8011 error: 8012 /* Revert the indoor to passive marking if START BSS fails */ 8013 if (iniConfig->force_ssc_disable_indoor_channel) { 8014 hdd_update_indoor_channel(hdd_ctx, false); 8015 sme_update_channel_list(hdd_ctx->hHal); 8016 } 8017 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); 8018 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); 8019 wlan_hdd_undo_acs(adapter); 8020 8021 free: 8022 qdf_mem_free(sme_config); 8023 return ret; 8024 } 8025 8026 int hdd_destroy_acs_timer(struct hdd_adapter *adapter) 8027 { 8028 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 8029 8030 if (!adapter->session.ap.vendor_acs_timer_initialized) 8031 return 0; 8032 8033 adapter->session.ap.vendor_acs_timer_initialized = false; 8034 8035 if (QDF_TIMER_STATE_RUNNING == 8036 adapter->session.ap.vendor_acs_timer.state) { 8037 qdf_status = 8038 qdf_mc_timer_stop(&adapter->session.ap. 8039 vendor_acs_timer); 8040 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 8041 hdd_err("Failed to stop ACS timer"); 8042 } 8043 8044 if (adapter->session.ap.vendor_acs_timer.user_data) 8045 qdf_mem_free(adapter->session.ap.vendor_acs_timer.user_data); 8046 8047 qdf_mc_timer_destroy(&adapter->session.ap.vendor_acs_timer); 8048 8049 return 0; 8050 } 8051 8052 /** 8053 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap 8054 * @wiphy: Pointer to wiphy structure 8055 * @dev: Pointer to net_device structure 8056 * 8057 * Return: 0 for success non-zero for failure 8058 */ 8059 static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, 8060 struct net_device *dev) 8061 { 8062 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 8063 struct hdd_adapter *sta_adapter; 8064 struct hdd_context *hdd_ctx = wiphy_priv(wiphy); 8065 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8066 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 8067 tSirUpdateIE updateIE; 8068 struct hdd_beacon_data *old; 8069 int ret; 8070 8071 hdd_enter(); 8072 8073 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 8074 hdd_err("Command not allowed in FTM mode"); 8075 return -EINVAL; 8076 } 8077 8078 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 8079 hdd_err("Driver module is closed; dropping request"); 8080 return -EINVAL; 8081 } 8082 8083 if (wlan_hdd_validate_session_id(adapter->session_id)) { 8084 hdd_err("Invalid session id: %d", adapter->session_id); 8085 return -EINVAL; 8086 } 8087 8088 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, 8089 TRACE_CODE_HDD_CFG80211_STOP_AP, 8090 adapter->session_id, adapter->device_mode)); 8091 8092 if (!(adapter->device_mode == QDF_SAP_MODE || 8093 adapter->device_mode == QDF_P2P_GO_MODE)) { 8094 return -EOPNOTSUPP; 8095 } 8096 8097 /* Clear SOFTAP_INIT_DONE flag to mark stop_ap deinit. So that we do 8098 * not restart SAP after SSR as SAP is already stopped from user space. 8099 * This update is moved to start of this function to resolve stop_ap 8100 * call during SSR case. Adapter gets cleaned up as part of SSR. 8101 */ 8102 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); 8103 hdd_debug("Device_mode %s(%d)", 8104 hdd_device_mode_to_string(adapter->device_mode), 8105 adapter->device_mode); 8106 8107 ret = wlan_hdd_validate_context(hdd_ctx); 8108 if (0 != ret) 8109 return ret; 8110 8111 /* 8112 * If a STA connection is in progress in another adapter, disconnect 8113 * the STA and complete the SAP operation. STA will reconnect 8114 * after SAP stop is done. 8115 */ 8116 sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx); 8117 if (sta_adapter) { 8118 hdd_debug("Disconnecting STA with session id: %d", 8119 sta_adapter->session_id); 8120 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH); 8121 } 8122 8123 if (adapter->device_mode == QDF_SAP_MODE) 8124 wlan_hdd_del_station(adapter); 8125 8126 cds_flush_work(&adapter->sap_stop_bss_work); 8127 /* 8128 * When ever stop ap adapter gets called, we need to check 8129 * whether any restart AP work is pending. If any restart is pending 8130 * then lets finish it and go ahead from there. 8131 */ 8132 if (hdd_ctx->config->conc_custom_rule1 && 8133 (QDF_SAP_MODE == adapter->device_mode)) { 8134 cds_flush_work(&hdd_ctx->sap_start_work); 8135 hdd_debug("Canceled the pending restart work"); 8136 qdf_spin_lock(&hdd_ctx->sap_update_info_lock); 8137 hdd_ctx->is_sap_restart_required = false; 8138 qdf_spin_unlock(&hdd_ctx->sap_update_info_lock); 8139 } 8140 adapter->session.ap.sap_config.acs_cfg.acs_mode = false; 8141 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); 8142 wlan_hdd_undo_acs(adapter); 8143 qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg, 8144 sizeof(struct sap_acs_cfg)); 8145 hdd_debug("Disabling queues"); 8146 wlan_hdd_netif_queue_control(adapter, 8147 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8148 WLAN_CONTROL_PATH); 8149 8150 old = adapter->session.ap.beacon; 8151 if (!old) { 8152 hdd_err("Session id: %d beacon data points to NULL", 8153 adapter->session_id); 8154 return -EINVAL; 8155 } 8156 wlan_hdd_cleanup_remain_on_channel_ctx(adapter); 8157 mutex_lock(&hdd_ctx->sap_lock); 8158 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { 8159 struct hdd_hostapd_state *hostapd_state = 8160 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); 8161 8162 /* Set the stop_bss_in_progress flag */ 8163 wlansap_set_stop_bss_inprogress( 8164 WLAN_HDD_GET_SAP_CTX_PTR(adapter), true); 8165 8166 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 8167 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); 8168 if (QDF_IS_STATUS_SUCCESS(status)) { 8169 qdf_status = 8170 qdf_wait_for_event_completion(&hostapd_state-> 8171 qdf_stop_bss_event, 8172 SME_CMD_TIMEOUT_VALUE); 8173 8174 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 8175 hdd_err("qdf wait for single_event failed!!"); 8176 QDF_ASSERT(0); 8177 } 8178 } 8179 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); 8180 8181 /* Clear the stop_bss_in_progress flag */ 8182 wlansap_set_stop_bss_inprogress( 8183 WLAN_HDD_GET_SAP_CTX_PTR(adapter), false); 8184 8185 /*BSS stopped, clear the active sessions for this device mode*/ 8186 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc, 8187 adapter->device_mode, 8188 adapter->session_id); 8189 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 8190 false); 8191 adapter->session.ap.beacon = NULL; 8192 qdf_mem_free(old); 8193 } 8194 mutex_unlock(&hdd_ctx->sap_lock); 8195 8196 if (wlan_sap_is_pre_cac_active(hdd_ctx->hHal)) 8197 hdd_clean_up_pre_cac_interface(hdd_ctx); 8198 8199 if (status != QDF_STATUS_SUCCESS) { 8200 hdd_err("Stopping the BSS"); 8201 return -EINVAL; 8202 } 8203 8204 qdf_copy_macaddr(&updateIE.bssid, &adapter->mac_addr); 8205 updateIE.smeSessionId = adapter->session_id; 8206 updateIE.ieBufferlength = 0; 8207 updateIE.pAdditionIEBuffer = NULL; 8208 updateIE.append = true; 8209 updateIE.notify = true; 8210 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter), 8211 &updateIE, 8212 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) { 8213 hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); 8214 } 8215 8216 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter), 8217 &updateIE, 8218 eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) { 8219 hdd_err("Could not pass on ASSOC_RSP data to PE"); 8220 } 8221 /* Reset WNI_CFG_PROBE_RSP Flags */ 8222 wlan_hdd_reset_prob_rspies(adapter); 8223 hdd_destroy_acs_timer(adapter); 8224 8225 ucfg_p2p_status_stop_bss(adapter->hdd_vdev); 8226 8227 hdd_exit(); 8228 8229 return ret; 8230 } 8231 8232 /** 8233 * wlan_hdd_get_channel_bw() - get channel bandwidth 8234 * @width: input channel width in nl80211_chan_width value 8235 * 8236 * Return: channel width value defined by driver 8237 */ 8238 static enum hw_mode_bandwidth wlan_hdd_get_channel_bw( 8239 enum nl80211_chan_width width) 8240 { 8241 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ; 8242 8243 switch (width) { 8244 case NL80211_CHAN_WIDTH_20_NOHT: 8245 case NL80211_CHAN_WIDTH_20: 8246 ch_bw = HW_MODE_20_MHZ; 8247 break; 8248 case NL80211_CHAN_WIDTH_40: 8249 ch_bw = HW_MODE_40_MHZ; 8250 break; 8251 case NL80211_CHAN_WIDTH_80: 8252 ch_bw = HW_MODE_80_MHZ; 8253 break; 8254 case NL80211_CHAN_WIDTH_80P80: 8255 ch_bw = HW_MODE_80_PLUS_80_MHZ; 8256 break; 8257 case NL80211_CHAN_WIDTH_160: 8258 ch_bw = HW_MODE_160_MHZ; 8259 break; 8260 default: 8261 hdd_err("Invalid width: %d, using default 20MHz", width); 8262 break; 8263 } 8264 8265 return ch_bw; 8266 } 8267 8268 /** 8269 * wlan_hdd_cfg80211_stop_ap() - stop sap 8270 * @wiphy: Pointer to wiphy 8271 * @dev: Pointer to netdev 8272 * 8273 * Return: zero for success non-zero for failure 8274 */ 8275 int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, 8276 struct net_device *dev) 8277 { 8278 int ret; 8279 8280 cds_ssr_protect(__func__); 8281 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev); 8282 cds_ssr_unprotect(__func__); 8283 8284 return ret; 8285 } 8286 8287 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \ 8288 defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT) 8289 /** 8290 * hdd_get_data_rate_from_rate_mask() - convert mask to rate 8291 * @wiphy: Pointer to wiphy 8292 * @band: band 8293 * @bit_rate_mask: pointer to bit_rake_mask 8294 * 8295 * This function takes band and bit_rate_mask as input and 8296 * derives the beacon_tx_rate based on the supported rates 8297 * published as part of wiphy register. 8298 * 8299 * Return: data rate for success or zero for failure 8300 */ 8301 static uint16_t hdd_get_data_rate_from_rate_mask(struct wiphy *wiphy, 8302 enum nl80211_band band, 8303 struct cfg80211_bitrate_mask *bit_rate_mask) 8304 { 8305 struct ieee80211_supported_band *sband = wiphy->bands[band]; 8306 int sband_n_bitrates; 8307 struct ieee80211_rate *sband_bitrates; 8308 int i; 8309 8310 if (sband) { 8311 sband_bitrates = sband->bitrates; 8312 sband_n_bitrates = sband->n_bitrates; 8313 for (i = 0; i < sband_n_bitrates; i++) { 8314 if (bit_rate_mask->control[band].legacy == 8315 sband_bitrates[i].hw_value) 8316 return sband_bitrates[i].bitrate; 8317 } 8318 } 8319 return 0; 8320 } 8321 8322 /** 8323 * hdd_update_beacon_rate() - Update beacon tx rate 8324 * @adapter: Pointer to hdd_adapter_t 8325 * @wiphy: Pointer to wiphy 8326 * @params: Pointet to cfg80211_ap_settings 8327 * 8328 * This function updates the beacon tx rate which is provided 8329 * as part of cfg80211_ap_settions in to the sap_config 8330 * structure 8331 * 8332 * Return: none 8333 */ 8334 static void hdd_update_beacon_rate(struct hdd_adapter *adapter, 8335 struct wiphy *wiphy, 8336 struct cfg80211_ap_settings *params) 8337 { 8338 struct cfg80211_bitrate_mask *beacon_rate_mask; 8339 enum nl80211_band band; 8340 8341 band = params->chandef.chan->band; 8342 beacon_rate_mask = ¶ms->beacon_rate; 8343 if (beacon_rate_mask->control[band].legacy) { 8344 adapter->session.ap.sap_config.beacon_tx_rate = 8345 hdd_get_data_rate_from_rate_mask(wiphy, band, 8346 beacon_rate_mask); 8347 hdd_debug("beacon mask value %u, rate %hu", 8348 params->beacon_rate.control[0].legacy, 8349 adapter->session.ap.sap_config.beacon_tx_rate); 8350 } 8351 } 8352 #else 8353 static void hdd_update_beacon_rate(struct hdd_adapter *adapter, 8354 struct wiphy *wiphy, 8355 struct cfg80211_ap_settings *params) 8356 { 8357 } 8358 #endif 8359 8360 8361 /** 8362 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode 8363 * @wiphy: Pointer to wiphy structure 8364 * @dev: Pointer to net_device structure 8365 * @params: Pointer to AP settings parameters 8366 * 8367 * Return: 0 for success non-zero for failure 8368 */ 8369 static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, 8370 struct net_device *dev, 8371 struct cfg80211_ap_settings *params) 8372 { 8373 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 8374 struct hdd_context *hdd_ctx; 8375 enum hw_mode_bandwidth channel_width; 8376 int status; 8377 struct sme_sta_inactivity_timeout *sta_inactivity_timer; 8378 uint8_t channel; 8379 8380 hdd_enter(); 8381 8382 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); 8383 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 8384 hdd_err("Command not allowed in FTM mode"); 8385 return -EINVAL; 8386 } 8387 8388 if (wlan_hdd_validate_session_id(adapter->session_id)) { 8389 hdd_err("Invalid session id: %d", adapter->session_id); 8390 return -EINVAL; 8391 } 8392 8393 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, 8394 TRACE_CODE_HDD_CFG80211_START_AP, adapter->session_id, 8395 params->beacon_interval)); 8396 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 8397 hdd_err("HDD adapter magic is invalid"); 8398 return -ENODEV; 8399 } 8400 8401 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 8402 status = wlan_hdd_validate_context(hdd_ctx); 8403 if (0 != status) 8404 return status; 8405 8406 hdd_debug("adapter = %pK, Device mode %s(%d) sub20 %d", 8407 adapter, hdd_device_mode_to_string(adapter->device_mode), 8408 adapter->device_mode, cds_is_sub_20_mhz_enabled()); 8409 8410 if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->hdd_psoc)) { 8411 status = policy_mgr_wait_for_connection_update( 8412 hdd_ctx->hdd_psoc); 8413 if (!QDF_IS_STATUS_SUCCESS(status)) { 8414 hdd_err("qdf wait for event failed!!"); 8415 return -EINVAL; 8416 } 8417 } 8418 8419 channel_width = wlan_hdd_get_channel_bw(params->chandef.width); 8420 channel = ieee80211_frequency_to_channel( 8421 params->chandef.chan->center_freq); 8422 adapter->session.ap.sap_config.ch_params.center_freq_seg0 = 8423 cds_freq_to_chan(params->chandef.center_freq1); 8424 adapter->session.ap.sap_config.ch_params.center_freq_seg1 = 8425 cds_freq_to_chan(params->chandef.center_freq2); 8426 8427 if (cds_is_sub_20_mhz_enabled()) { 8428 enum channel_state ch_state; 8429 enum phy_ch_width sub_20_ch_width = CH_WIDTH_INVALID; 8430 tsap_config_t *sap_cfg = &adapter->session.ap.sap_config; 8431 8432 /* Avoid ACS/DFS, and overwrite ch wd to 20 */ 8433 if (channel == 0) { 8434 hdd_err("Can't start SAP-ACS (channel=0) with sub 20 MHz ch width"); 8435 return -EINVAL; 8436 } 8437 if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state( 8438 hdd_ctx->hdd_pdev, channel)) { 8439 hdd_err("Can't start SAP-DFS (channel=%d)with sub 20 MHz ch wd", 8440 channel); 8441 return -EINVAL; 8442 } 8443 if (channel_width != HW_MODE_20_MHZ) { 8444 hdd_err("Hostapd (20+ MHz) conflits with config.ini (sub 20 MHz)"); 8445 return -EINVAL; 8446 } 8447 if (cds_is_5_mhz_enabled()) 8448 sub_20_ch_width = CH_WIDTH_5MHZ; 8449 if (cds_is_10_mhz_enabled()) 8450 sub_20_ch_width = CH_WIDTH_10MHZ; 8451 if (WLAN_REG_IS_5GHZ_CH(channel)) 8452 ch_state = wlan_reg_get_5g_bonded_channel_state( 8453 hdd_ctx->hdd_pdev, channel, 8454 sub_20_ch_width); 8455 else 8456 ch_state = wlan_reg_get_2g_bonded_channel_state( 8457 hdd_ctx->hdd_pdev, channel, 8458 sub_20_ch_width, 0); 8459 if (CHANNEL_STATE_DISABLE == ch_state) { 8460 hdd_err("Given ch width not supported by reg domain"); 8461 return -EINVAL; 8462 } 8463 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_abg; 8464 } 8465 8466 /* check if concurrency is allowed */ 8467 if (!policy_mgr_allow_concurrency(hdd_ctx->hdd_psoc, 8468 policy_mgr_convert_device_mode_to_qdf_type( 8469 adapter->device_mode), 8470 channel, 8471 channel_width)) { 8472 hdd_err("Connection failed due to concurrency check failure"); 8473 return -EINVAL; 8474 } 8475 8476 status = policy_mgr_reset_connection_update(hdd_ctx->hdd_psoc); 8477 if (!QDF_IS_STATUS_SUCCESS(status)) 8478 hdd_err("ERR: clear event failed"); 8479 8480 /* 8481 * Stop opportunistic timer here if running as we are already doing 8482 * hw mode change before vdev start based on the new concurrency 8483 * situation. If timer is not stopped and if it gets triggered before 8484 * VDEV_UP, it will reset the hw mode to some wrong value. 8485 */ 8486 status = policy_mgr_stop_opportunistic_timer(hdd_ctx->hdd_psoc); 8487 if (status != QDF_STATUS_SUCCESS) { 8488 hdd_err("Failed to stop DBS opportunistic timer"); 8489 return -EINVAL; 8490 } 8491 8492 status = policy_mgr_current_connections_update(hdd_ctx->hdd_psoc, 8493 adapter->session_id, channel, 8494 POLICY_MGR_UPDATE_REASON_START_AP); 8495 if (status == QDF_STATUS_E_FAILURE) { 8496 hdd_err("ERROR: connections update failed!!"); 8497 return -EINVAL; 8498 } 8499 8500 if (QDF_STATUS_SUCCESS == status) { 8501 status = policy_mgr_wait_for_connection_update(hdd_ctx->hdd_psoc); 8502 if (!QDF_IS_STATUS_SUCCESS(status)) { 8503 hdd_err("ERROR: qdf wait for event failed!!"); 8504 return -EINVAL; 8505 } 8506 } 8507 8508 if (adapter->device_mode == QDF_P2P_GO_MODE) { 8509 struct hdd_adapter *p2p_adapter; 8510 8511 p2p_adapter = hdd_get_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE); 8512 if (p2p_adapter) { 8513 hdd_debug("Cancel active p2p device ROC before GO starting"); 8514 wlan_hdd_cancel_existing_remain_on_channel( 8515 p2p_adapter); 8516 } 8517 } 8518 8519 if ((adapter->device_mode == QDF_SAP_MODE) 8520 || (adapter->device_mode == QDF_P2P_GO_MODE) 8521 ) { 8522 struct hdd_beacon_data *old, *new; 8523 enum nl80211_channel_type channel_type; 8524 tsap_config_t *sap_config = 8525 &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config); 8526 8527 old = adapter->session.ap.beacon; 8528 8529 if (old) 8530 return -EALREADY; 8531 8532 status = 8533 wlan_hdd_cfg80211_alloc_new_beacon(adapter, &new, 8534 ¶ms->beacon, 8535 params->dtim_period); 8536 8537 if (status != 0) { 8538 hdd_err("Error!!! Allocating the new beacon"); 8539 return -EINVAL; 8540 } 8541 adapter->session.ap.beacon = new; 8542 8543 if (params->chandef.width < NL80211_CHAN_WIDTH_80) 8544 channel_type = cfg80211_get_chandef_type( 8545 &(params->chandef)); 8546 else 8547 channel_type = NL80211_CHAN_HT40PLUS; 8548 8549 8550 wlan_hdd_set_channel(wiphy, dev, 8551 ¶ms->chandef, 8552 channel_type); 8553 8554 hdd_update_beacon_rate(adapter, wiphy, params); 8555 8556 /* set authentication type */ 8557 switch (params->auth_type) { 8558 case NL80211_AUTHTYPE_OPEN_SYSTEM: 8559 adapter->session.ap.sap_config.authType = 8560 eSAP_OPEN_SYSTEM; 8561 break; 8562 case NL80211_AUTHTYPE_SHARED_KEY: 8563 adapter->session.ap.sap_config.authType = 8564 eSAP_SHARED_KEY; 8565 break; 8566 default: 8567 adapter->session.ap.sap_config.authType = 8568 eSAP_AUTO_SWITCH; 8569 } 8570 adapter->session.ap.sap_config.ch_width_orig = 8571 params->chandef.width; 8572 8573 status = 8574 wlan_hdd_cfg80211_start_bss(adapter, 8575 ¶ms->beacon, 8576 params->ssid, params->ssid_len, 8577 params->hidden_ssid, true); 8578 8579 if (status != 0) { 8580 hdd_err("Error Start bss Failed"); 8581 goto err_start_bss; 8582 } 8583 8584 /* 8585 * If Do_Not_Break_Stream enabled send avoid channel list 8586 * to application. 8587 */ 8588 if (policy_mgr_is_dnsc_set(adapter->hdd_vdev) && 8589 sap_config->channel) { 8590 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 8591 sap_config->channel); 8592 } 8593 if (hdd_ctx->config->sap_max_inactivity_override) { 8594 sta_inactivity_timer = qdf_mem_malloc( 8595 sizeof(*sta_inactivity_timer)); 8596 if (!sta_inactivity_timer) { 8597 hdd_err("Failed to allocate Memory"); 8598 return QDF_STATUS_E_FAILURE; 8599 } 8600 sta_inactivity_timer->session_id = adapter->session_id; 8601 sta_inactivity_timer->sta_inactivity_timeout = 8602 params->inactivity_timeout; 8603 sme_update_sta_inactivity_timeout(WLAN_HDD_GET_HAL_CTX 8604 (adapter), sta_inactivity_timer); 8605 qdf_mem_free(sta_inactivity_timer); 8606 } 8607 } 8608 8609 goto success; 8610 8611 err_start_bss: 8612 if (adapter->session.ap.beacon) 8613 qdf_mem_free(adapter->session.ap.beacon); 8614 adapter->session.ap.beacon = NULL; 8615 8616 success: 8617 hdd_exit(); 8618 return status; 8619 } 8620 8621 /** 8622 * wlan_hdd_cfg80211_start_ap() - start sap 8623 * @wiphy: Pointer to wiphy 8624 * @dev: Pointer to netdev 8625 * @params: Pointer to start ap configuration parameters 8626 * 8627 * Return: zero for success non-zero for failure 8628 */ 8629 int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, 8630 struct net_device *dev, 8631 struct cfg80211_ap_settings *params) 8632 { 8633 int ret; 8634 8635 cds_ssr_protect(__func__); 8636 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params); 8637 cds_ssr_unprotect(__func__); 8638 8639 return ret; 8640 } 8641 8642 /** 8643 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go 8644 * @wiphy: Pointer to wiphy structure 8645 * @dev: Pointer to net_device structure 8646 * @params: Pointer to change beacon parameters 8647 * 8648 * Return: 0 for success non-zero for failure 8649 */ 8650 static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, 8651 struct net_device *dev, 8652 struct cfg80211_beacon_data *params) 8653 { 8654 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 8655 struct hdd_context *hdd_ctx; 8656 struct hdd_beacon_data *old, *new; 8657 int status; 8658 8659 hdd_enter(); 8660 8661 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 8662 hdd_err("Command not allowed in FTM mode"); 8663 return -EINVAL; 8664 } 8665 8666 if (wlan_hdd_validate_session_id(adapter->session_id)) { 8667 hdd_err("invalid session id: %d", adapter->session_id); 8668 return -EINVAL; 8669 } 8670 8671 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, 8672 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON, 8673 adapter->session_id, adapter->device_mode)); 8674 hdd_debug("Device_mode %s(%d)", 8675 hdd_device_mode_to_string(adapter->device_mode), 8676 adapter->device_mode); 8677 8678 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 8679 status = wlan_hdd_validate_context(hdd_ctx); 8680 8681 if (0 != status) 8682 return status; 8683 8684 if (!(adapter->device_mode == QDF_SAP_MODE || 8685 adapter->device_mode == QDF_P2P_GO_MODE)) { 8686 return -EOPNOTSUPP; 8687 } 8688 8689 old = adapter->session.ap.beacon; 8690 8691 if (!old) { 8692 hdd_err("session id: %d beacon data points to NULL", 8693 adapter->session_id); 8694 return -EINVAL; 8695 } 8696 8697 status = wlan_hdd_cfg80211_alloc_new_beacon(adapter, &new, params, 0); 8698 8699 if (status != QDF_STATUS_SUCCESS) { 8700 hdd_err("new beacon alloc failed"); 8701 return -EINVAL; 8702 } 8703 8704 adapter->session.ap.beacon = new; 8705 hdd_debug("update beacon for P2P GO/SAP"); 8706 status = wlan_hdd_cfg80211_start_bss(adapter, params, NULL, 8707 0, 0, false); 8708 8709 hdd_exit(); 8710 return status; 8711 } 8712 8713 /** 8714 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode 8715 * @wiphy: Pointer to wiphy 8716 * @dev: Pointer to netdev 8717 * @params: Pointer to change beacon parameters 8718 * 8719 * Return: zero for success non-zero for failure 8720 */ 8721 int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, 8722 struct net_device *dev, 8723 struct cfg80211_beacon_data *params) 8724 { 8725 int ret; 8726 8727 cds_ssr_protect(__func__); 8728 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params); 8729 cds_ssr_unprotect(__func__); 8730 8731 return ret; 8732 } 8733 8734 /** 8735 * hdd_sap_indicate_disconnect_for_sta() - Indicate disconnect indication 8736 * to supplicant, if there any clients connected to SAP interface. 8737 * @adapter: sap adapter context 8738 * 8739 * Return: nothing 8740 */ 8741 void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter) 8742 { 8743 tSap_Event sap_event; 8744 int sta_id; 8745 struct sap_context *sap_ctx; 8746 8747 hdd_enter(); 8748 8749 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); 8750 if (!sap_ctx) { 8751 hdd_err("invalid sap context"); 8752 return; 8753 } 8754 8755 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { 8756 if (adapter->sta_info[sta_id].in_use) { 8757 hdd_debug("sta_id: %d in_use: %d %pK", 8758 sta_id, adapter->sta_info[sta_id].in_use, 8759 adapter); 8760 8761 if (qdf_is_macaddr_broadcast( 8762 &adapter->sta_info[sta_id].sta_mac)) 8763 continue; 8764 8765 sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; 8766 qdf_mem_copy( 8767 &sap_event.sapevt. 8768 sapStationDisassocCompleteEvent.staMac, 8769 &adapter->sta_info[sta_id].sta_mac, 8770 sizeof(struct qdf_mac_addr)); 8771 sap_event.sapevt.sapStationDisassocCompleteEvent. 8772 reason = 8773 eSAP_MAC_INITATED_DISASSOC; 8774 sap_event.sapevt.sapStationDisassocCompleteEvent. 8775 statusCode = 8776 QDF_STATUS_E_RESOURCES; 8777 hdd_hostapd_sap_event_cb(&sap_event, 8778 sap_ctx->pUsrContext); 8779 } 8780 } 8781 8782 hdd_exit(); 8783 } 8784 8785 bool hdd_is_peer_associated(struct hdd_adapter *adapter, 8786 struct qdf_mac_addr *mac_addr) 8787 { 8788 uint32_t cnt; 8789 struct hdd_station_info *sta_info; 8790 8791 if (!adapter || !mac_addr) { 8792 hdd_err("Invalid adapter or mac_addr"); 8793 return false; 8794 } 8795 8796 sta_info = adapter->sta_info; 8797 spin_lock_bh(&adapter->sta_info_lock); 8798 for (cnt = 0; cnt < WLAN_MAX_STA_COUNT; cnt++) { 8799 if ((sta_info[cnt].in_use) && 8800 !qdf_mem_cmp(&(sta_info[cnt].sta_mac), mac_addr, 8801 QDF_MAC_ADDR_SIZE)) 8802 break; 8803 } 8804 spin_unlock_bh(&adapter->sta_info_lock); 8805 if (cnt != WLAN_MAX_STA_COUNT) 8806 return true; 8807 8808 return false; 8809 } 8810