blob: 85a6c92dd969a9908f5fd340ac0913addd20cb51 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_hostapd.c
30 *
31 * WLAN Host Device Driver implementation
32 */
33
34/* Include Files */
35
36#include <linux/version.h>
37#include <linux/module.h>
38#include <linux/kernel.h>
39#include <linux/init.h>
40#include <linux/wireless.h>
41#include <linux/semaphore.h>
42#include <linux/compat.h>
43#include <cds_api.h>
44#include <cds_sched.h>
45#include <linux/etherdevice.h>
46#include <wlan_hdd_includes.h>
47#include <qc_sap_ioctl.h>
48#include <wlan_hdd_hostapd.h>
49#include <sap_api.h>
50#include <sap_internal.h>
51#include <wlan_hdd_softap_tx_rx.h>
52#include <wlan_hdd_main.h>
53#include <wlan_hdd_ioctl.h>
54#include <wlan_hdd_stats.h>
55#include <linux/netdevice.h>
56#include <linux/rtnetlink.h>
57#include <linux/mmc/sdio_func.h>
58#include "wlan_hdd_p2p.h"
59#include <wlan_hdd_ipa.h>
60#include "cfg_api.h"
61#include "wni_cfg.h"
62#include "wlan_hdd_misc.h"
63#include <cds_utils.h>
64#if defined CONFIG_CNSS
65#include <net/cnss.h>
66#endif
67
68#include "wma.h"
69#ifdef DEBUG
70#include "wma_api.h"
71#endif
72#include "wlan_hdd_trace.h"
73#include "cdf_types.h"
74#include "cdf_trace.h"
75#include "wlan_hdd_cfg.h"
76#include "cds_concurrency.h"
77#include "wlan_hdd_green_ap.h"
78
79#define IS_UP(_dev) \
80 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
81#define IS_UP_AUTO(_ic) \
82 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
83#define WE_WLAN_VERSION 1
84#define WE_GET_STA_INFO_SIZE 30
85/* WEXT limitation: MAX allowed buf len for any *
86 * IW_PRIV_TYPE_CHAR is 2Kbytes *
87 */
88#define WE_SAP_MAX_STA_INFO 0x7FF
89
90#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7)
91#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
92#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf)
93#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)
94
95#define SAP_24GHZ_CH_COUNT (14)
96#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097
98#define DUMP_DP_TRACE 0
99
100/* Function definitions */
101
102/**
103 * hdd_hostapd_channel_wakelock_init() - init the channel wakelock
104 * @pHddCtx: pointer to hdd context
105 *
106 * Return: None
107 */
108void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx)
109{
110 /* Initialize the wakelock */
111 cdf_wake_lock_init(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock");
112 atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
113}
114
115/**
116 * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
117 * Called when, 1. bss stopped, 2. channel switch
118 *
119 * @pAdapter: pointer to hdd adapter
120 * @channel: current channel
121 *
122 * Return: None
123 */
124void hdd_hostapd_channel_allow_suspend(hdd_adapter_t *pAdapter,
125 uint8_t channel)
126{
127
128 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
129 hdd_hostapd_state_t *pHostapdState =
130 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
131
132 hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
133 pHostapdState->bssState, channel,
134 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
135
136 /* Return if BSS is already stopped */
137 if (pHostapdState->bssState == BSS_STOP)
138 return;
139
140 /* Release wakelock when no more DFS channels are used */
141 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
142 if (atomic_dec_and_test(&pHddCtx->sap_dfs_ref_cnt)) {
143 hddLog(LOGE, FL("DFS: allowing suspend (chan %d)"),
144 channel);
145 cdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
146 WIFI_POWER_EVENT_WAKELOCK_DFS);
147 }
148 }
149}
150
151/**
152 * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
153 * Called when, 1. bss started, 2. channel switch
154 *
155 * @pAdapter: pointer to hdd adapter
156 * @channel: current channel
157 *
158 * Return - None
159 */
160void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter,
161 uint8_t channel)
162{
163 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
164 hdd_hostapd_state_t *pHostapdState =
165 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
166
167 hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
168 pHostapdState->bssState, channel,
169 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
170
171 /* Return if BSS is already started && wakelock is acquired */
172 if ((pHostapdState->bssState == BSS_START) &&
173 (atomic_read(&pHddCtx->sap_dfs_ref_cnt) >= 1))
174 return;
175
176 /* Acquire wakelock if we have at least one DFS channel in use */
177 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
178 if (atomic_inc_return(&pHddCtx->sap_dfs_ref_cnt) == 1) {
179 hddLog(LOGE, FL("DFS: preventing suspend (chan %d)"),
180 channel);
181 cdf_wake_lock_acquire(&pHddCtx->sap_dfs_wakelock,
182 WIFI_POWER_EVENT_WAKELOCK_DFS);
183 }
184 }
185}
186
187/**
188 * hdd_hostapd_channel_wakelock_deinit() - destroy the channel wakelock
189 *
190 * @pHddCtx: pointer to hdd context
191 *
192 * Return: None
193 */
194void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx)
195{
196 if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) {
197 /* Release wakelock */
198 cdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
199 WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
200 /* Reset the reference count */
201 atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
202 hddLog(LOGE, FL("DFS: allowing suspend"));
203 }
204
205 /* Destroy lock */
206 cdf_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock);
207}
208
209/**
210 * __hdd_hostapd_open() - hdd open function for hostapd interface
211 * This is called in response to ifconfig up
212 * @dev: pointer to net_device structure
213 *
214 * Return - 0 for success non-zero for failure
215 */
216static int __hdd_hostapd_open(struct net_device *dev)
217{
218 hdd_adapter_t *pAdapter = netdev_priv(dev);
219
220 ENTER();
221
222 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
223 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
224
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800225 if (cds_is_load_or_unload_in_progress()) {
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800226 hdd_err("Driver load/unload in progress, ignore, state: 0x%x",
227 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 goto done;
229 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800230
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231 /* Enable all Tx queues */
232 hddLog(LOG1, FL("Enabling queues"));
233 wlan_hdd_netif_queue_control(pAdapter,
234 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
235 WLAN_CONTROL_PATH);
236done:
237 EXIT();
238 return 0;
239}
240
241/**
242 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
243 * @dev: pointer to net device
244 *
245 * Return: 0 on success, error number otherwise
246 */
247static int hdd_hostapd_open(struct net_device *dev)
248{
249 int ret;
250
251 cds_ssr_protect(__func__);
252 ret = __hdd_hostapd_open(dev);
253 cds_ssr_unprotect(__func__);
254
255 return ret;
256}
257
258/**
259 * __hdd_hostapd_stop() - hdd stop function for hostapd interface
260 * This is called in response to ifconfig down
261 *
262 * @dev: pointer to net_device structure
263 *
264 * Return - 0 for success non-zero for failure
265 */
266static int __hdd_hostapd_stop(struct net_device *dev)
267{
268 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
269 ENTER();
270
271 /* Stop all tx queues */
272 hddLog(LOG1, FL("Disabling queues"));
273 wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
274 WLAN_CONTROL_PATH);
275
276 EXIT();
277 return 0;
278}
279
280/**
281 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
282 * @dev: pointer to net_device
283 *
284 * This is called in response to ifconfig down
285 *
286 * Return: 0 on success, error number otherwise
287 */
288int hdd_hostapd_stop(struct net_device *dev)
289{
290 int ret;
291
292 cds_ssr_protect(__func__);
293 ret = __hdd_hostapd_stop(dev);
294 cds_ssr_unprotect(__func__);
295
296 return ret;
297}
298
299/**
300 * __hdd_hostapd_uninit() - hdd uninit function
301 * This is called during the netdev unregister to uninitialize all data
302 * associated with the device.
303 *
304 * @dev: pointer to net_device structure
305 *
306 * Return: None
307 */
308static void __hdd_hostapd_uninit(struct net_device *dev)
309{
310 hdd_adapter_t *adapter = netdev_priv(dev);
311 hdd_context_t *hdd_ctx;
312
313 ENTER();
314
315 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
316 hddLog(LOGE, FL("Invalid magic"));
317 return;
318 }
319
320 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
321 if (NULL == hdd_ctx) {
322 hddLog(LOGE, FL("NULL hdd_ctx"));
323 return;
324 }
325
326 hdd_deinit_adapter(hdd_ctx, adapter, true);
327
328 /* after uninit our adapter structure will no longer be valid */
329 adapter->dev = NULL;
330 adapter->magic = 0;
331
332 EXIT();
333}
334
335/**
336 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
337 * @dev: pointer to net_device
338 *
339 * Return: 0 on success, error number otherwise
340 */
341static void hdd_hostapd_uninit(struct net_device *dev)
342{
343 cds_ssr_protect(__func__);
344 __hdd_hostapd_uninit(dev);
345 cds_ssr_unprotect(__func__);
346}
347
348/**
349 * __hdd_hostapd_change_mtu() - change mtu
350 * @dev: pointer to net_device
351 * @new_mtu: new mtu
352 *
353 * Return: 0 on success, error number otherwise
354 */
355static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
356{
357 return 0;
358}
359
360/**
361 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
362 * @dev: pointer to net_device
363 * @new_mtu: new mtu
364 *
365 * Return: 0 on success, error number otherwise
366 */
367static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
368{
369 int ret;
370
371 cds_ssr_protect(__func__);
372 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
373 cds_ssr_unprotect(__func__);
374
375 return ret;
376}
377
378#ifdef QCA_HT_2040_COEX
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530379QDF_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 uint8_t channel_type)
381{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530382 QDF_STATUS cdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383 void *hHal = NULL;
384
385 hddLog(LOGE, FL("change HT20/40 mode"));
386
387 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
388 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
389 if (NULL == hHal) {
390 hddLog(LOGE, FL("Hal ctx is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530391 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800392 }
393 cdf_ret_status =
394 sme_set_ht2040_mode(hHal, pHostapdAdapter->sessionId,
395 channel_type, true);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530396 if (cdf_ret_status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800397 hddLog(LOGE, FL("Failed to change HT20/40 mode"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530398 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 }
400 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530401 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402}
403#endif
404
405/**
406 * __hdd_hostapd_set_mac_address() -
407 * This function sets the user specified mac address using
408 * the command ifconfig wlanX hw ether <mac address>.
409 *
410 * @dev: pointer to the net device.
411 * @addr: pointer to the sockaddr.
412 *
413 * Return: 0 for success, non zero for failure
414 */
415static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
416{
417 struct sockaddr *psta_mac_addr = addr;
418 hdd_adapter_t *adapter;
419 hdd_context_t *hdd_ctx;
420 int ret = 0;
421
422 ENTER();
423
424 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
425 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
426 ret = wlan_hdd_validate_context(hdd_ctx);
427 if (0 != ret)
428 return ret;
429
430 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
431 EXIT();
432 return 0;
433}
434
435/**
436 * hdd_hostapd_set_mac_address() - set mac address
437 * @dev: pointer to net_device
438 * @addr: mac address
439 *
440 * Return: 0 on success, error number otherwise
441 */
442static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
443{
444 int ret;
445
446 cds_ssr_protect(__func__);
447 ret = __hdd_hostapd_set_mac_address(dev, addr);
448 cds_ssr_unprotect(__func__);
449
450 return ret;
451}
452
453void hdd_hostapd_inactivity_timer_cb(void *usrDataForCallback)
454{
455 struct net_device *dev = (struct net_device *)usrDataForCallback;
456 uint8_t we_custom_event[64];
457 union iwreq_data wrqu;
458#ifdef DISABLE_CONCURRENCY_AUTOSAVE
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530459 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 hdd_adapter_t *pHostapdAdapter;
461 hdd_ap_ctx_t *pHddApCtx;
462#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
463
464 /* event_name space-delimiter driver_module_name
465 * Format of the event is "AUTO-SHUT.indication" " " "module_name"
466 */
467 char *autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
468
469 /* For the NULL at the end */
470 int event_len = strlen(autoShutEvent) + 1;
471
472 ENTER();
473
474#ifdef DISABLE_CONCURRENCY_AUTOSAVE
475 if (cds_concurrent_open_sessions_running()) {
476 /*
477 * This timer routine is going to be called only when AP
478 * persona is up.
479 * If there are concurrent sessions running we do not want
480 * to shut down the Bss.Instead we run the timer again so
481 * that if Autosave is enabled next time and other session
482 was down only then we bring down AP
483 */
484 pHostapdAdapter = netdev_priv(dev);
485 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530486 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 cdf_mc_timer_start(&pHddApCtx->hdd_ap_inactivity_timer,
488 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
489 config->nAPAutoShutOff * 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530490 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800491 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
492 }
493 EXIT();
494 return;
495 }
496#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
497 memset(&we_custom_event, '\0', sizeof(we_custom_event));
498 memcpy(&we_custom_event, autoShutEvent, event_len);
499
500 memset(&wrqu, 0, sizeof(wrqu));
501 wrqu.data.length = event_len;
502
503 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
504 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
505
506 EXIT();
507}
508
509void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter,
510 void *usrDataForCallback)
511{
512 uint8_t staId = 0;
513 struct net_device *dev;
514 dev = (struct net_device *)usrDataForCallback;
515
516 hddLog(LOGE, FL("Clearing all the STA entry...."));
517 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
518 if (pHostapdAdapter->aStaInfo[staId].isUsed &&
519 (staId !=
520 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)) {
521 /* Disconnect all the stations */
522 hdd_softap_sta_disassoc(pHostapdAdapter,
523 &pHostapdAdapter->
524 aStaInfo[staId].macAddrSTA.
525 bytes[0]);
526 }
527 }
528}
529
530static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,
531 void *usrDataForCallback)
532{
533 struct net_device *dev;
534 hdd_context_t *pHddCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530535 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800536 dev = (struct net_device *)usrDataForCallback;
537 ENTER();
538
539 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
540 status = wlan_hdd_validate_context(pHddCtx);
541
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +0530542 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544
545 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
546#ifdef WLAN_FEATURE_MBSSID
547 status =
548 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(
549 pHostapdAdapter));
550#else
551 status =
552 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
553 pcds_context);
554#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530555 if (QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800556 hddLog(LOGE, FL("Deleting SAP/P2P link!!!!!!"));
557
558 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -0800559 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 pHostapdAdapter->sessionId);
561 }
562 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530563 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564}
565
566/**
567 * hdd_issue_stored_joinreq() - This function will trigger stations's
568 * cached connect request to proceed.
569 * @hdd_ctx: pointer to hdd context.
570 * @sta_adater: pointer to station adapter.
571 *
572 * This function will call SME to release station's stored/cached connect
573 * request to proceed.
574 *
575 * Return: none.
576 */
577static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
578 hdd_context_t *hdd_ctx)
579{
580 tHalHandle hal_handle;
581 uint32_t roam_id;
582
583 if (NULL == sta_adapter) {
584 hddLog(LOGE,
585 FL
586 ("Invalid station adapter, ignore issueing join req"));
587 return;
588 }
589 hal_handle = WLAN_HDD_GET_HAL_CTX(sta_adapter);
590
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800591 if (true == cds_is_sta_connection_pending()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
593 TRACE_CODE_HDD_ISSUE_JOIN_REQ,
594 sta_adapter->sessionId, roam_id));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530595 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 sme_issue_stored_joinreq(hal_handle,
597 &roam_id,
598 sta_adapter->sessionId)) {
599 /* change back to NotAssociated */
600 hdd_conn_set_connection_state(sta_adapter,
601 eConnectionState_NotConnected);
602 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800603 cds_change_sta_conn_pending_status(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 }
605}
606
Liangwei Dongd7be7772015-11-05 21:50:25 -0500607#ifdef WLAN_FEATURE_MBSSID
608static eCsrPhyMode
609hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter)
610{
611 return wlansap_get_phymode(WLAN_HDD_GET_SAP_CTX_PTR(hostapd_adapter));
612}
613#else
614static eCsrPhyMode
615hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter)
616{
617 return wlansap_get_phymode(
618 (WLAN_HDD_GET_CTX(hostapd_adapter))->pcds_context);
619}
620#endif
621
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800622/**
Wu Gao2c3a8002016-01-22 10:56:07 +0800623 * hdd_update_chandef() - Function to update channel width and center freq
624 * @hostapd_adapter: hostapd adapter
625 * @chandef: cfg80211 chan def
626 * @cb_mode: chan offset
627 *
628 * This function will be called to update channel width and center freq
629 *
630 * Return: None
631 */
632#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) || defined(WITH_BACKPORTS)
633static inline void
634hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
635 struct cfg80211_chan_def *chandef,
636 ePhyChanBondState cb_mode)
637{
638 uint16_t ch_width;
639 hdd_ap_ctx_t *phdd_ap_ctx;
640 uint8_t center_chan, chan;
641
642 phdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
643 ch_width = phdd_ap_ctx->sapConfig.acs_cfg.ch_width;
644
645 switch (ch_width) {
646 case eHT_CHANNEL_WIDTH_20MHZ:
647 case eHT_CHANNEL_WIDTH_40MHZ:
648 hdd_info("ch_width %d, won't update", ch_width);
649 break;
650 case eHT_CHANNEL_WIDTH_80MHZ:
651 chan = cds_freq_to_chan(chandef->chan->center_freq);
652 chandef->width = NL80211_CHAN_WIDTH_80;
653
654 switch (cb_mode) {
655 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
656 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
657 center_chan = chan + 2;
658 break;
659 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
660 center_chan = chan + 6;
661 break;
662 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
663 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
664 center_chan = chan - 2;
665 break;
666 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
667 center_chan = chan - 6;
668 break;
669 default:
670 center_chan = chan;
671 break;
672 }
673
674 chandef->center_freq1 = cds_chan_to_freq(center_chan);
675 break;
676 case eHT_CHANNEL_WIDTH_160MHZ:
677 default:
678 /* Todo, please add related codes if support 160MHZ or others */
679 hdd_err("unsupport ch_width %d", ch_width);
680 break;
681 }
682
683}
684#else
685static inline void
686hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
687 struct cfg80211_chan_def *chandef,
688 ePhyChanBondState cb_mode)
689{
690}
691#endif
692
693/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800694 * hdd_chan_change_notify() - Function to notify hostapd about channel change
695 * @hostapd_adapter hostapd adapter
696 * @dev: Net device structure
697 * @oper_chan: New operating channel
698 *
699 * This function is used to notify hostapd about the channel change
700 *
701 * Return: Success on intimating userspace
702 *
703 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530704QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800705 struct net_device *dev,
706 uint8_t oper_chan)
707{
708 struct ieee80211_channel *chan;
709 struct cfg80211_chan_def chandef;
710 enum nl80211_channel_type channel_type;
711 eCsrPhyMode phy_mode;
712 ePhyChanBondState cb_mode;
713 uint32_t freq;
714 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);
715
716 if (NULL == hal) {
717 hdd_err("hal is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530718 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 }
720
721 freq = cds_chan_to_freq(oper_chan);
722
723 chan = __ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);
724
725 if (!chan) {
726 hdd_err("Invalid input frequency for channel conversion");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530727 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728 }
729
Liangwei Dongd7be7772015-11-05 21:50:25 -0500730 phy_mode = hdd_sap_get_phymode(hostapd_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731
732 if (oper_chan <= 14)
733 cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
734 sme_get_channel_bonding_mode24_g(hal));
735 else
736 cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
737 sme_get_channel_bonding_mode5_g(hal));
738
739 switch (phy_mode) {
740 case eCSR_DOT11_MODE_11n:
741 case eCSR_DOT11_MODE_11n_ONLY:
742 case eCSR_DOT11_MODE_11ac:
743 case eCSR_DOT11_MODE_11ac_ONLY:
744 if (cb_mode == PHY_SINGLE_CHANNEL_CENTERED)
745 channel_type = NL80211_CHAN_HT20;
746 else if (cb_mode == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
747 channel_type = NL80211_CHAN_HT40MINUS;
748 else if (cb_mode == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
749 channel_type = NL80211_CHAN_HT40PLUS;
750 else
751 channel_type = NL80211_CHAN_HT40PLUS;
752 break;
753 default:
754 channel_type = NL80211_CHAN_NO_HT;
755 break;
756 }
757
Liangwei Dongd7be7772015-11-05 21:50:25 -0500758 hdd_info("%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d",
759 __func__, phy_mode, cb_mode, channel_type, oper_chan);
760
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761 cfg80211_chandef_create(&chandef, chan, channel_type);
762
Wu Gao2c3a8002016-01-22 10:56:07 +0800763 if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
764 (phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
765 hdd_update_chandef(hostapd_adapter, &chandef, cb_mode);
766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 cfg80211_ch_switch_notify(dev, &chandef);
768
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530769 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770}
771
772/**
773 * hdd_send_radar_event() - Function to send radar events to user space
774 * @hdd_context: HDD context
775 * @event: Type of radar event
776 * @dfs_info: Structure containing DFS channel and country
777 * @wdev: Wireless device structure
778 *
779 * This function is used to send radar events such as CAC start, CAC
780 * end etc., to userspace
781 *
782 * Return: Success on sending notifying userspace
783 *
784 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530785QDF_STATUS hdd_send_radar_event(hdd_context_t *hdd_context,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 eSapHddEvent event,
787 struct wlan_dfs_info dfs_info,
788 struct wireless_dev *wdev)
789{
790
791 struct sk_buff *vendor_event;
792 enum qca_nl80211_vendor_subcmds_index index;
793 uint32_t freq, ret;
794 uint32_t data_size;
795
796 if (!hdd_context) {
797 hddLog(LOGE, FL("HDD context is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530798 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 }
800
801 freq = cds_chan_to_freq(dfs_info.channel);
802
803 switch (event) {
804 case eSAP_DFS_CAC_START:
805 index =
806 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
807 data_size = sizeof(uint32_t);
808 break;
809 case eSAP_DFS_CAC_END:
810 index =
811 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
812 data_size = sizeof(uint32_t);
813 break;
814 case eSAP_DFS_RADAR_DETECT:
815 index =
816 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
817 data_size = sizeof(uint32_t);
818 break;
819 default:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530820 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821 }
822
823 vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
824 wdev,
825 data_size + NLMSG_HDRLEN,
826 index,
827 GFP_KERNEL);
828 if (!vendor_event) {
829 hddLog(LOGE,
830 FL("cfg80211_vendor_event_alloc failed for %d"), index);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530831 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832 }
833
834 ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
835
836 if (ret) {
837 hddLog(LOGE, FL("NL80211_ATTR_WIPHY_FREQ put fail"));
838 kfree_skb(vendor_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530839 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840 }
841
842 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530843 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800844}
845
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530846QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847 void *usrDataForCallback)
848{
849 hdd_adapter_t *pHostapdAdapter;
850 hdd_ap_ctx_t *pHddApCtx;
851 hdd_hostapd_state_t *pHostapdState;
852 struct net_device *dev;
853 eSapHddEvent sapEvent;
854 union iwreq_data wrqu;
855 uint8_t *we_custom_event_generic = NULL;
856 int we_event = 0;
857 int i = 0;
858 uint8_t staId;
Anurag Chouhance0dc992016-02-16 18:18:03 +0530859 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860 bool bWPSState;
861 bool bAuthRequired = true;
862 tpSap_AssocMacAddr pAssocStasArray = NULL;
863 char unknownSTAEvent[IW_CUSTOM_MAX + 1];
864 char maxAssocExceededEvent[IW_CUSTOM_MAX + 1];
865 uint8_t we_custom_start_event[64];
866 char *startBssEvent;
867 hdd_context_t *pHddCtx;
868 hdd_scaninfo_t *pScanInfo = NULL;
869 struct iw_michaelmicfailure msg;
870 uint8_t ignoreCAC = 0;
871 struct hdd_config *cfg = NULL;
872 struct wlan_dfs_info dfs_info;
873 uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
874 hdd_adapter_t *con_sap_adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530875 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876#if defined CONFIG_CNSS
877 int ret = 0;
878#endif
879
880 dev = (struct net_device *)usrDataForCallback;
881 if (!dev) {
882 hddLog(LOGE, FL("usrDataForCallback is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530883 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 }
885
886 pHostapdAdapter = netdev_priv(dev);
887
888 if ((NULL == pHostapdAdapter) ||
889 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) {
890 hddLog(LOGE, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530891 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 }
893
894 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
895 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
896
897 if (!pSapEvent) {
898 hddLog(LOGE, FL("pSapEvent is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530899 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900 }
901
902 sapEvent = pSapEvent->sapHddEventCode;
903 memset(&wrqu, '\0', sizeof(wrqu));
904 pHddCtx = (hdd_context_t *) (pHostapdAdapter->pHddCtx);
905
906 if (!pHddCtx) {
907 hddLog(LOGE, FL("HDD context is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530908 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 }
910
911 cfg = pHddCtx->config;
912
913 if (!cfg) {
914 hddLog(LOGE, FL("HDD config is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530915 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800916 }
917
918 dfs_info.channel = pHddApCtx->operatingChannel;
919 sme_get_country_code(pHddCtx->hHal, dfs_info.country_code, &cc_len);
920
921 switch (sapEvent) {
922 case eSAP_START_BSS_EVENT:
923 hddLog(LOG1,
924 FL("BSS status = %s, channel = %u, bc sta Id = %d"),
925 pSapEvent->sapevt.sapStartBssCompleteEvent.
926 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
927 pSapEvent->sapevt.sapStartBssCompleteEvent.
928 operatingChannel,
929 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
930
931 pHostapdAdapter->sessionId =
932 pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;
933
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530934 pHostapdState->qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 pSapEvent->sapevt.sapStartBssCompleteEvent.status;
Anurag Chouhance0dc992016-02-16 18:18:03 +0530936 qdf_status = qdf_event_set(&pHostapdState->cdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937
Anurag Chouhance0dc992016-02-16 18:18:03 +0530938 if (!QDF_IS_STATUS_SUCCESS(qdf_status)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530939 || pHostapdState->qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 hddLog(LOGE, ("ERROR: startbss event failed!!"));
941 goto stopbss;
942 } else {
943 sme_ch_avoid_update_req(pHddCtx->hHal);
944
945 pHddApCtx->uBCStaId =
946 pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
947
948 hdd_register_tx_flow_control(pHostapdAdapter,
949 hdd_softap_tx_resume_timer_expired_handler,
950 hdd_softap_tx_resume_cb);
951
952 /* @@@ need wep logic here to set privacy bit */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530953 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800954 hdd_softap_register_bc_sta(pHostapdAdapter,
955 pHddApCtx->uPrivacy);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530956 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800957 hddLog(LOGW, FL("Failed to register BC STA %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530958 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800959 hdd_stop_bss_link(pHostapdAdapter,
960 usrDataForCallback);
961 }
962 }
963
964 if (hdd_ipa_is_enabled(pHddCtx)) {
965 status = hdd_ipa_wlan_evt(pHostapdAdapter,
966 pHddApCtx->uBCStaId,
967 WLAN_AP_CONNECT,
968 pHostapdAdapter->dev->dev_addr);
969 if (status) {
970 hddLog(LOGE,
971 ("WLAN_AP_CONNECT event failed!!"));
972 goto stopbss;
973 }
974 }
975
976 if (0 !=
977 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
978 nAPAutoShutOff) {
979 /* AP Inactivity timer init and start */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530980 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 cdf_mc_timer_init(&pHddApCtx->
982 hdd_ap_inactivity_timer,
983 CDF_TIMER_TYPE_SW,
984 hdd_hostapd_inactivity_timer_cb,
985 dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530986 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987 hddLog(LOGE,
988 FL("Failed to init inactivity timer"));
989
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530990 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991 cdf_mc_timer_start(&pHddApCtx->
992 hdd_ap_inactivity_timer,
993 (WLAN_HDD_GET_CTX
994 (pHostapdAdapter))->config->
995 nAPAutoShutOff * 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530996 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800997 hddLog(LOGE,
998 FL("Failed to init inactivity timer"));
999
1000 }
1001#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1002 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1003#endif
1004 pHddApCtx->operatingChannel =
1005 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
1006
1007 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1008 pHddApCtx->
1009 operatingChannel);
1010
1011 pHostapdState->bssState = BSS_START;
1012 hdd_wlan_green_ap_start_bss(pHddCtx);
1013
1014 /* Set group key / WEP key every time when BSS is restarted */
1015 if (pHddApCtx->groupKey.keyLength) {
1016 status = wlansap_set_key_sta(
1017#ifdef WLAN_FEATURE_MBSSID
1018 WLAN_HDD_GET_SAP_CTX_PTR
1019 (pHostapdAdapter),
1020#else
1021 (WLAN_HDD_GET_CTX
1022 (pHostapdAdapter))->
1023 pcds_context,
1024#endif
1025 &pHddApCtx->groupKey);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301026 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027 hddLog(LOGE, FL("wlansap_set_key_sta failed"));
1028 } else {
1029 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
1030 if (!pHddApCtx->wepKey[i].keyLength)
1031 continue;
1032
1033 status = wlansap_set_key_sta(
1034#ifdef WLAN_FEATURE_MBSSID
1035 WLAN_HDD_GET_SAP_CTX_PTR
1036 (pHostapdAdapter),
1037#else
1038 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
1039 pcds_context,
1040#endif
1041 &pHddApCtx->
1042 wepKey[i]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301043 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 hddLog(LOGE,
1045 FL("set_key failed idx %d"), i);
1046 }
1047 }
1048 }
1049
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301050 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001051 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301052 mutex_unlock(&pHddCtx->dfs_lock);
1053
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054 wlansap_get_dfs_ignore_cac(pHddCtx->hHal, &ignoreCAC);
1055
1056 /* DFS requirement: DO NOT transmit during CAC. */
1057 if ((CHANNEL_STATE_DFS !=
1058 cds_get_channel_state(pHddApCtx->operatingChannel))
1059 || ignoreCAC
1060 || pHddCtx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
1061 pHddApCtx->dfs_cac_block_tx = false;
1062 else
1063 pHddApCtx->dfs_cac_block_tx = true;
1064
1065 hddLog(LOG3, "The value of dfs_cac_block_tx[%d] for ApCtx[%p]",
1066 pHddApCtx->dfs_cac_block_tx, pHddApCtx);
1067
1068 if ((CHANNEL_STATE_DFS ==
1069 cds_get_channel_state(pHddApCtx->operatingChannel))
1070 && (pHddCtx->config->IsSapDfsChSifsBurstEnabled == 0)) {
1071
1072 hddLog(LOG1,
1073 FL("Set SIFS Burst disable for DFS channel %d"),
1074 pHddApCtx->operatingChannel);
1075
1076 if (wma_cli_set_command(pHostapdAdapter->sessionId,
1077 WMI_PDEV_PARAM_BURST_ENABLE,
1078 0, PDEV_CMD)) {
1079 hddLog(LOGE,
1080 FL("Failed to Set SIFS Burst %d"),
1081 pHddApCtx->operatingChannel);
1082 }
1083 }
1084 /* Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled */
1085 startBssEvent = "SOFTAP.enabled";
1086 memset(&we_custom_start_event, '\0',
1087 sizeof(we_custom_start_event));
1088 memcpy(&we_custom_start_event, startBssEvent,
1089 strlen(startBssEvent));
1090 memset(&wrqu, 0, sizeof(wrqu));
1091 wrqu.data.length = strlen(startBssEvent);
1092 we_event = IWEVCUSTOM;
1093 we_custom_event_generic = we_custom_start_event;
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001094 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001095 /* Send SCC/MCC Switching event to IPA */
1096 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1097 break; /* Event will be sent after Switch-Case stmt */
1098
1099 case eSAP_STOP_BSS_EVENT:
1100 hddLog(LOG1, FL("BSS stop status = %s"),
1101 pSapEvent->sapevt.sapStopBssCompleteEvent.
1102 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1103
1104 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1105 pHddApCtx->operatingChannel);
1106
1107 hdd_wlan_green_ap_stop_bss(pHddCtx);
1108
1109 /* Free up Channel List incase if it is set */
1110#ifdef WLAN_FEATURE_MBSSID
1111 sap_cleanup_channel_list(WLAN_HDD_GET_SAP_CTX_PTR
1112 (pHostapdAdapter));
1113#else
1114 sap_cleanup_channel_list();
1115#endif
1116 /* Invalidate the channel info. */
1117 pHddApCtx->operatingChannel = 0;
1118 if (hdd_ipa_is_enabled(pHddCtx)) {
1119 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1120 pHddApCtx->uBCStaId,
1121 WLAN_AP_DISCONNECT,
1122 pHostapdAdapter->dev->dev_addr);
1123 if (status) {
1124 hddLog(LOGE,
1125 ("WLAN_AP_DISCONNECT event failed!!"));
1126 goto stopbss;
1127 }
1128 }
1129
1130 /* reset the dfs_cac_status and dfs_cac_block_tx flag only when
1131 * the last BSS is stopped
1132 */
1133 con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter, true);
1134 if (!con_sap_adapter) {
1135 pHddApCtx->dfs_cac_block_tx = true;
1136 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1137 }
1138 if (pHddCtx->config->conc_custom_rule2 &&
1139 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
1140 hdd_adapter_t *sta_adapter = hdd_get_adapter(pHddCtx,
1141 WLAN_HDD_INFRA_STATION);
1142 hddLog(LOG2,
1143 FL("P2PGO is going down now"));
1144 hdd_issue_stored_joinreq(sta_adapter, pHddCtx);
1145 }
1146 goto stopbss;
1147
1148 case eSAP_DFS_CAC_START:
1149 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_START_IND,
1150 &dfs_info,
1151 sizeof(struct wlan_dfs_info));
1152 pHddCtx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301153 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001154 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_START,
1155 dfs_info, &pHostapdAdapter->wdev)) {
1156 hddLog(LOGE, FL("Unable to indicate CAC start NL event"));
1157 } else {
1158 hdd_info("Sent CAC start to user space");
1159 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301160
1161 mutex_lock(&pHddCtx->dfs_lock);
1162 pHddCtx->dfs_radar_found = false;
1163 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001164 break;
1165 case eSAP_DFS_CAC_INTERRUPTED:
1166 /*
1167 * The CAC timer did not run completely and a radar was detected
1168 * during the CAC time. This new state will keep the tx path
1169 * blocked since we do not want any transmission on the DFS
1170 * channel. CAC end will only be reported here since the user
1171 * space applications are waiting on CAC end for their state
1172 * management.
1173 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301174 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001175 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1176 dfs_info, &pHostapdAdapter->wdev)) {
1177 hdd_err("Unable to indicate CAC end (interrupted) event");
1178 } else {
1179 hdd_info("Sent CAC end (interrupted) to user space");
1180 }
1181 break;
1182 case eSAP_DFS_CAC_END:
1183 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_END_IND,
1184 &dfs_info,
1185 sizeof(struct wlan_dfs_info));
1186 pHddApCtx->dfs_cac_block_tx = false;
1187 pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301188 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001189 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1190 dfs_info, &pHostapdAdapter->wdev)) {
1191 hddLog(LOGE, FL("Unable to indicate CAC end NL event"));
1192 } else {
1193 hdd_info("Sent CAC end to user space");
1194 }
1195 break;
1196
1197 case eSAP_DFS_RADAR_DETECT:
1198 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_RADAR_DETECT_IND,
1199 &dfs_info,
1200 sizeof(struct wlan_dfs_info));
1201 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301202 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
1204 dfs_info, &pHostapdAdapter->wdev)) {
1205 hddLog(LOGE, FL("Unable to indicate Radar detect NL event"));
1206 } else {
1207 hdd_info("Sent radar detected to user space");
1208 }
1209 break;
1210
1211 case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1212 wlan_hdd_send_svc_nlink_msg
1213 (WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
1214 sizeof(struct wlan_dfs_info));
1215 break;
1216
1217 case eSAP_STA_SET_KEY_EVENT:
1218 /* TODO:
1219 * forward the message to hostapd once implementation
1220 * is done for now just print
1221 */
1222 hddLog(LOG1, FL("SET Key: configured status = %s"),
1223 pSapEvent->sapevt.sapStationSetKeyCompleteEvent.
1224 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 case eSAP_STA_MIC_FAILURE_EVENT:
1227 {
1228 memset(&msg, '\0', sizeof(msg));
1229 msg.src_addr.sa_family = ARPHRD_ETHER;
1230 memcpy(msg.src_addr.sa_data,
1231 &pSapEvent->sapevt.sapStationMICFailureEvent.
1232 staMac, CDF_MAC_ADDR_SIZE);
1233 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
1234 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
1235 if (pSapEvent->sapevt.sapStationMICFailureEvent.
1236 multicast == eSAP_TRUE)
1237 msg.flags = IW_MICFAILURE_GROUP;
1238 else
1239 msg.flags = IW_MICFAILURE_PAIRWISE;
1240 memset(&wrqu, 0, sizeof(wrqu));
1241 wrqu.data.length = sizeof(msg);
1242 we_event = IWEVMICHAELMICFAILURE;
1243 we_custom_event_generic = (uint8_t *) &msg;
1244 }
1245 /* inform mic failure to nl80211 */
1246 cfg80211_michael_mic_failure(dev,
1247 pSapEvent->
1248 sapevt.sapStationMICFailureEvent.
1249 staMac.bytes,
1250 ((pSapEvent->sapevt.
1251 sapStationMICFailureEvent.
1252 multicast ==
1253 eSAP_TRUE) ?
1254 NL80211_KEYTYPE_GROUP :
1255 NL80211_KEYTYPE_PAIRWISE),
1256 pSapEvent->sapevt.
1257 sapStationMICFailureEvent.keyId,
1258 pSapEvent->sapevt.
1259 sapStationMICFailureEvent.TSC,
1260 GFP_KERNEL);
1261 break;
1262
1263 case eSAP_STA_ASSOC_EVENT:
1264 case eSAP_STA_REASSOC_EVENT:
1265 wrqu.addr.sa_family = ARPHRD_ETHER;
1266 memcpy(wrqu.addr.sa_data,
1267 &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.
1268 staMac, CDF_MAC_ADDR_SIZE);
1269 hddLog(LOG1, " associated " MAC_ADDRESS_STR,
1270 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1271 we_event = IWEVREGISTERED;
1272
1273#ifdef WLAN_FEATURE_MBSSID
1274 wlansap_get_wps_state(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
1275 &bWPSState);
1276#else
1277 wlansap_get_wps_state((WLAN_HDD_GET_CTX(pHostapdAdapter))->
1278 pcds_context, &bWPSState);
1279#endif
1280
1281 if ((eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
1282 (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
1283 pHddApCtx->ucEncryptType)
1284 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
1285 pHddApCtx->ucEncryptType)) {
1286 bAuthRequired = false;
1287 }
1288
1289 if (bAuthRequired || bWPSState == true) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301290 qdf_status = hdd_softap_register_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291 pHostapdAdapter,
1292 true,
1293 pHddApCtx->uPrivacy,
1294 pSapEvent->sapevt.
1295 sapStationAssocReassocCompleteEvent.
1296 staId, 0, 0,
1297 (struct cdf_mac_addr *)
1298 wrqu.addr.sa_data,
1299 pSapEvent->sapevt.
1300 sapStationAssocReassocCompleteEvent.
1301 wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301302 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303 hddLog(LOGW,
1304 FL("Failed to register STA %d "
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301305 MAC_ADDRESS_STR ""), qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1307 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301308 qdf_status = hdd_softap_register_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001309 pHostapdAdapter,
1310 false,
1311 pHddApCtx->uPrivacy,
1312 pSapEvent->sapevt.
1313 sapStationAssocReassocCompleteEvent.
1314 staId, 0, 0,
1315 (struct cdf_mac_addr *)
1316 wrqu.addr.sa_data,
1317 pSapEvent->sapevt.
1318 sapStationAssocReassocCompleteEvent.
1319 wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301320 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321 hddLog(LOGW,
1322 FL("Failed to register STA %d "
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301323 MAC_ADDRESS_STR ""), qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001324 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1325 }
1326
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301327 staId =
1328 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301329 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301330 pHostapdAdapter->aStaInfo[staId].nss =
1331 pSapEvent->sapevt.
1332 sapStationAssocReassocCompleteEvent.
1333 chan_info.nss;
1334 pHostapdAdapter->aStaInfo[staId].rate_flags =
1335 pSapEvent->sapevt.
1336 sapStationAssocReassocCompleteEvent.
1337 chan_info.rate_flags;
1338 }
1339
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 if (hdd_ipa_is_enabled(pHddCtx)) {
1341 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1342 pSapEvent->sapevt.
1343 sapStationAssocReassocCompleteEvent.
1344 staId, WLAN_CLIENT_CONNECT_EX,
1345 pSapEvent->sapevt.
1346 sapStationAssocReassocCompleteEvent.
1347 staMac.bytes);
1348 if (status) {
1349 hddLog(LOGE,
1350 FL("WLAN_CLIENT_CONNECT_EX event failed"));
1351 goto stopbss;
1352 }
1353 }
1354
1355#ifdef QCA_PKT_PROTO_TRACE
1356 /* Peer associated, update into trace buffer */
1357 if (pHddCtx->config->gEnableDebugLog) {
1358 cds_pkt_trace_buf_update("HA:ASSOC");
1359 }
1360#endif /* QCA_PKT_PROTO_TRACE */
1361
1362#ifdef MSM_PLATFORM
1363 /* start timer in sap/p2p_go */
1364 if (pHddApCtx->bApActive == false) {
1365 spin_lock_bh(&pHddCtx->bus_bw_lock);
1366 pHostapdAdapter->prev_tx_packets =
1367 pHostapdAdapter->stats.tx_packets;
1368 pHostapdAdapter->prev_rx_packets =
1369 pHostapdAdapter->stats.rx_packets;
1370 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1371 hdd_start_bus_bw_compute_timer(pHostapdAdapter);
1372 }
1373#endif
1374 pHddApCtx->bApActive = true;
1375 /* Stop AP inactivity timer */
1376 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
1377 CDF_TIMER_STATE_RUNNING) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301378 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379 cdf_mc_timer_stop(&pHddApCtx->
1380 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301381 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001382 hddLog(LOGE,
1383 FL("Failed to start inactivity timer"));
1384 }
1385 }
1386#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1387 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1388#endif
1389 cdf_wake_lock_timeout_acquire(&pHddCtx->sap_wake_lock,
1390 HDD_SAP_WAKE_LOCK_DURATION,
1391 WIFI_POWER_EVENT_WAKELOCK_SAP);
1392 {
1393 struct station_info staInfo;
1394 uint16_t iesLen =
1395 pSapEvent->sapevt.
1396 sapStationAssocReassocCompleteEvent.iesLen;
1397
1398 memset(&staInfo, 0, sizeof(staInfo));
1399 if (iesLen <= MAX_ASSOC_IND_IE_LEN) {
1400 staInfo.assoc_req_ies =
1401 (const u8 *)&pSapEvent->sapevt.
1402 sapStationAssocReassocCompleteEvent.ies[0];
1403 staInfo.assoc_req_ies_len = iesLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001404 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001405 cfg80211_new_sta(dev,
1406 (const u8 *)&pSapEvent->sapevt.
1407 sapStationAssocReassocCompleteEvent.
1408 staMac.bytes[0], &staInfo,
1409 GFP_KERNEL);
1410 } else {
1411 hddLog(LOGE,
1412 FL("Assoc Ie length is too long"));
1413 }
1414 }
1415
1416 pScanInfo = &pHostapdAdapter->scan_info;
1417 /* Lets do abort scan to ensure smooth authentication for client */
1418 if ((pScanInfo != NULL) && pScanInfo->mScanPending) {
1419 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
1420 eCSR_SCAN_ABORT_DEFAULT);
1421 }
1422 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1423 /* send peer status indication to oem app */
1424 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1425 sapStationAssocReassocCompleteEvent.
1426 staMac, ePeerConnected,
1427 pSapEvent->sapevt.
1428 sapStationAssocReassocCompleteEvent.
1429 timingMeasCap,
1430 pHostapdAdapter->
1431 sessionId,
1432 &pSapEvent->sapevt.
1433 sapStationAssocReassocCompleteEvent.
1434 chan_info);
1435 }
1436 hdd_wlan_green_ap_add_sta(pHddCtx);
1437 break;
1438
1439 case eSAP_STA_DISASSOC_EVENT:
1440 memcpy(wrqu.addr.sa_data,
1441 &pSapEvent->sapevt.sapStationDisassocCompleteEvent.
1442 staMac, CDF_MAC_ADDR_SIZE);
1443 hddLog(LOG1, " disassociated " MAC_ADDRESS_STR,
1444 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1445
Anurag Chouhance0dc992016-02-16 18:18:03 +05301446 qdf_status = qdf_event_set(&pHostapdState->cdf_event);
1447 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001448 hddLog(LOGE, "ERR: Station Deauth event Set failed");
1449
1450 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
1451 eSAP_USR_INITATED_DISASSOC)
1452 hddLog(LOG1, " User initiated disassociation");
1453 else
1454 hddLog(LOG1, " MAC initiated disassociation");
1455 we_event = IWEVEXPIRED;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301456 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001457 hdd_softap_get_sta_id(pHostapdAdapter,
1458 &pSapEvent->sapevt.
1459 sapStationDisassocCompleteEvent.staMac,
1460 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301461 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001462 hddLog(LOGE, FL("ERROR: HDD Failed to find sta id!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301463 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001464 }
1465#ifdef IPA_OFFLOAD
1466 if (hdd_ipa_is_enabled(pHddCtx)) {
1467 status = hdd_ipa_wlan_evt(pHostapdAdapter, staId,
1468 WLAN_CLIENT_DISCONNECT,
1469 pSapEvent->sapevt.
1470 sapStationDisassocCompleteEvent.
1471 staMac.bytes);
1472
1473 if (status) {
1474 hddLog(LOGE,
1475 ("ERROR: WLAN_CLIENT_DISCONNECT event failed!!"));
1476 goto stopbss;
1477 }
1478 }
1479#endif
1480#ifdef QCA_PKT_PROTO_TRACE
1481 /* Peer dis-associated, update into trace buffer */
1482 if (pHddCtx->config->gEnableDebugLog) {
1483 cds_pkt_trace_buf_update("HA:DISASC");
1484 }
1485#endif /* QCA_PKT_PROTO_TRACE */
1486 hdd_softap_deregister_sta(pHostapdAdapter, staId);
1487
1488 pHddApCtx->bApActive = false;
1489 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1490 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
1491 if (pHostapdAdapter->aStaInfo[i].isUsed
1492 && i !=
1493 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
1494 uBCStaId) {
1495 pHddApCtx->bApActive = true;
1496 break;
1497 }
1498 }
1499 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1500
1501 /* Start AP inactivity timer if no stations associated with it */
1502 if ((0 !=
1503 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1504 nAPAutoShutOff)) {
1505 if (pHddApCtx->bApActive == false) {
1506 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
1507 CDF_TIMER_STATE_STOPPED) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301508 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509 cdf_mc_timer_start(&pHddApCtx->
1510 hdd_ap_inactivity_timer,
1511 (WLAN_HDD_GET_CTX
1512 (pHostapdAdapter))->
1513 config->
1514 nAPAutoShutOff *
1515 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301516 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 hddLog(LOGE,
1518 FL("Failed to init AP inactivity timer"));
1519 } else
1520 CDF_ASSERT
1521 (cdf_mc_timer_get_current_state
1522 (&pHddApCtx->
1523 hdd_ap_inactivity_timer) ==
1524 CDF_TIMER_STATE_STOPPED);
1525 }
1526 }
1527#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1528 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1529#endif
1530
1531 cfg80211_del_sta(dev,
1532 (const u8 *)&pSapEvent->sapevt.
1533 sapStationDisassocCompleteEvent.staMac.
1534 bytes[0], GFP_KERNEL);
1535
1536 /* Update the beacon Interval if it is P2P GO */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301537 qdf_status = cds_change_mcc_go_beacon_interval(pHostapdAdapter);
1538 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 hddLog(LOGE, FL("failed to update Beacon interval %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301540 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 }
1542 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1543 /* send peer status indication to oem app */
1544 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1545 sapStationDisassocCompleteEvent.
1546 staMac, ePeerDisconnected,
1547 0,
1548 pHostapdAdapter->
1549 sessionId, NULL);
1550 }
1551#ifdef MSM_PLATFORM
1552 /*stop timer in sap/p2p_go */
1553 if (pHddApCtx->bApActive == false) {
1554 spin_lock_bh(&pHddCtx->bus_bw_lock);
1555 pHostapdAdapter->prev_tx_packets = 0;
1556 pHostapdAdapter->prev_rx_packets = 0;
1557 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1558 hdd_stop_bus_bw_compute_timer(pHostapdAdapter);
1559 }
1560#endif
1561 hdd_wlan_green_ap_del_sta(pHddCtx);
1562 break;
1563
1564 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1565 {
1566 static const char *message =
1567 "MLMEWPSPBCPROBEREQ.indication";
1568 union iwreq_data wreq;
1569
1570 down(&pHddApCtx->semWpsPBCOverlapInd);
1571 pHddApCtx->WPSPBCProbeReq.probeReqIELen =
1572 pSapEvent->sapevt.sapPBCProbeReqEvent.
1573 WPSPBCProbeReq.probeReqIELen;
1574
1575 cdf_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE,
1576 pSapEvent->sapevt.sapPBCProbeReqEvent.
1577 WPSPBCProbeReq.probeReqIE,
1578 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1579
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001580 cdf_copy_macaddr(&pHddApCtx->WPSPBCProbeReq.peer_macaddr,
1581 &pSapEvent->sapevt.sapPBCProbeReqEvent.
1582 WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 hddLog(LOG1, "WPS PBC probe req " MAC_ADDRESS_STR,
1584 MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001585 peer_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001586 memset(&wreq, 0, sizeof(wreq));
1587 wreq.data.length = strlen(message); /* This is length of message */
1588 wireless_send_event(dev, IWEVCUSTOM, &wreq,
1589 (char *)message);
1590
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301591 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 }
1593 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1594 pAssocStasArray =
1595 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1596 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) { /* List of associated stations */
1597 for (i = 0;
1598 i <
1599 pSapEvent->sapevt.sapAssocStaListEvent.
1600 noOfAssocSta; i++) {
1601 hddLog(LOG1,
1602 "Associated Sta Num %d:assocId=%d, staId=%d, staMac="
1603 MAC_ADDRESS_STR, i + 1,
1604 pAssocStasArray->assocId,
1605 pAssocStasArray->staId,
1606 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
1607 bytes));
1608 pAssocStasArray++;
1609 }
1610 }
1611 cdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas); /* Release caller allocated memory here */
1612 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301613 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001614 case eSAP_REMAIN_CHAN_READY:
1615 hdd_remain_chan_ready_handler(pHostapdAdapter,
1616 pSapEvent->sapevt.sap_roc_ind.scan_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301617 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618 case eSAP_SEND_ACTION_CNF:
1619 hdd_send_action_cnf(pHostapdAdapter,
1620 (eSAP_STATUS_SUCCESS ==
1621 pSapEvent->sapevt.sapActionCnf.
1622 actionSendSuccess) ? true : false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301623 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 case eSAP_UNKNOWN_STA_JOIN:
1625 snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
1626 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1627 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1628 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1629 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1630 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1631 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1632 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1633 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1634 wrqu.data.pointer = unknownSTAEvent;
1635 wrqu.data.length = strlen(unknownSTAEvent);
1636 we_custom_event_generic = (uint8_t *) unknownSTAEvent;
1637 hddLog(LOGE, "%s", unknownSTAEvent);
1638 break;
1639
1640 case eSAP_MAX_ASSOC_EXCEEDED:
1641 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
1642 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1643 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1644 " one or more devices to enable the new device connection",
1645 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1646 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1647 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1648 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1649 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1650 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
1651 bytes[5]);
1652 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1653 wrqu.data.pointer = maxAssocExceededEvent;
1654 wrqu.data.length = strlen(maxAssocExceededEvent);
1655 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
1656 hddLog(LOG1, "%s", maxAssocExceededEvent);
1657 break;
1658 case eSAP_STA_ASSOC_IND:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301659 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001660
1661 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
1662 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
1663 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301664 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665
1666 case eSAP_MAC_TRIG_STOP_BSS_EVENT:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301667 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301669 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670 hddLog(LOGW, FL("hdd_stop_bss_link failed %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301671 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301673 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674
1675 case eSAP_CHANNEL_CHANGE_EVENT:
1676 hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event"));
1677 /* Prevent suspend for new channel */
1678 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1679 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1680 /* Allow suspend for old channel */
1681 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1682 pHddApCtx->operatingChannel);
1683 /* SME/PE is already updated for new operation channel. So update
1684 * HDD layer also here. This resolves issue in AP-AP mode where
1685 * AP1 channel is changed due to RADAR then CAC is going on and
1686 * START_BSS on new channel has not come to HDD. At this case if
1687 * AP2 is start it needs current operation channel for MCC DFS
1688 * restiction
1689 */
1690 pHddApCtx->operatingChannel =
1691 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1692 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1693 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1694 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1695 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1696 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1697 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1698 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1699 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1700 pHddApCtx->sapConfig.acs_cfg.ch_width =
1701 pSapEvent->sapevt.sap_ch_selected.ch_width;
1702
1703 /* Indicate operating channel change to hostapd
1704 * only for non driver override acs
1705 */
1706 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
1707 pHddCtx->config->force_sap_acs)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301708 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001709 else
1710 return hdd_chan_change_notify(pHostapdAdapter, dev,
1711 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1712
1713#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1714 case eSAP_ACS_SCAN_SUCCESS_EVENT:
1715 pHddCtx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1716 hddLog(LOG1, FL("Reusing Last ACS scan result for %d sec"),
1717 ACS_SCAN_EXPIRY_TIMEOUT_S);
1718 cdf_mc_timer_stop(&pHddCtx->skip_acs_scan_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301719 qdf_status = cdf_mc_timer_start(&pHddCtx->skip_acs_scan_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 ACS_SCAN_EXPIRY_TIMEOUT_S *
1721 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301722 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 hddLog(LOGE,
1724 FL("Failed to start ACS scan expiry timer"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301725 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001726#endif
1727
1728 case eSAP_DFS_NOL_GET:
1729 hddLog(LOG1,
1730 FL("Received eSAP_DFS_NOL_GET event"));
1731#if defined CONFIG_CNSS
1732 /* get the dfs nol from cnss */
1733 ret =
1734 cnss_wlan_get_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1735 pDfsList,
1736 pSapEvent->sapevt.sapDfsNolInfo.
1737 sDfsList);
1738
1739 if (ret > 0) {
1740 hddLog(LOG2,
1741 FL("Get %d bytes of dfs nol from cnss"), ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301742 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743 } else {
1744 hddLog(LOG2,
1745 FL("No dfs nol entry in CNSS, ret: %d"), ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301746 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747 }
1748#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301749 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001750#endif
1751 case eSAP_DFS_NOL_SET:
1752 hddLog(LOG1, FL("Received eSAP_DFS_NOL_SET event"));
1753#if defined CONFIG_CNSS
1754 /* set the dfs nol to cnss */
1755 ret =
1756 cnss_wlan_set_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1757 pDfsList,
1758 pSapEvent->sapevt.sapDfsNolInfo.
1759 sDfsList);
1760
1761 if (ret) {
1762 hddLog(LOG2,
1763 FL("Failed to set dfs nol - ret: %d"),
1764 ret);
1765 } else {
1766 hddLog(LOG2, FL(" Set %d bytes dfs nol to cnss"),
1767 pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
1768 }
1769#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301770 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301772 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001773 case eSAP_ACS_CHANNEL_SELECTED:
1774 hddLog(LOG1, FL("ACS Completed for wlan%d"),
1775 pHostapdAdapter->dev->ifindex);
1776 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
1777 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
1778 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1779 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1780 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1781 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1782 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1783 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1784 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1785 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1786 pHddApCtx->sapConfig.acs_cfg.ch_width =
1787 pSapEvent->sapevt.sap_ch_selected.ch_width;
1788 /* send vendor event to hostapd only for hostapd based acs*/
1789 if (!pHddCtx->config->force_sap_acs)
1790 wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301791 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301792 case eSAP_ECSA_CHANGE_CHAN_IND:
1793 hddLog(LOG1,
1794 FL("Channel change indication from peer for channel %d"),
1795 pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
1796 if (hdd_softap_set_channel_change(dev,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301797 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
1798 CH_WIDTH_MAX))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301799 return QDF_STATUS_E_FAILURE;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301800 else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301801 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301802
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803 default:
1804 hddLog(LOG1, "SAP message is not handled");
1805 goto stopbss;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301806 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807 }
1808 wireless_send_event(dev, we_event, &wrqu,
1809 (char *)we_custom_event_generic);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301810 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811
1812stopbss:
1813 {
1814 uint8_t we_custom_event[64];
1815 char *stopBssEvent = "STOP-BSS.response"; /* 17 */
1816 int event_len = strlen(stopBssEvent);
1817
1818 hddLog(LOG1, FL("BSS stop status = %s"),
1819 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1820 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1821
1822 /* Change the BSS state now since, as we are shutting things down,
1823 * we don't want interfaces to become re-enabled */
1824 pHostapdState->bssState = BSS_STOP;
1825
1826 if (0 !=
1827 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1828 nAPAutoShutOff) {
1829 if (CDF_TIMER_STATE_RUNNING ==
1830 pHddApCtx->hdd_ap_inactivity_timer.state) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301831 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001832 cdf_mc_timer_stop(&pHddApCtx->
1833 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301834 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 hddLog(LOGE,
1836 FL("Failed to stop AP inactivity timer"));
1837 }
1838 }
1839
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301840 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 cdf_mc_timer_destroy(&pHddApCtx->
1842 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301843 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001844 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1845 }
1846#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1847 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1848#endif
1849
1850 /* Stop the pkts from n/w stack as we are going to free all of
1851 * the TX WMM queues for all STAID's */
1852 hdd_hostapd_stop(dev);
1853
1854 /* reclaim all resources allocated to the BSS */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301855 qdf_status = hdd_softap_stop_bss(pHostapdAdapter);
1856 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857 hddLog(LOGW,
1858 FL("hdd_softap_stop_bss failed %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301859 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 }
1861
1862 /* once the event is set, structure dev/pHostapdAdapter should
1863 * not be touched since they are now subject to being deleted
1864 * by another thread */
1865 if (eSAP_STOP_BSS_EVENT == sapEvent)
Anurag Chouhance0dc992016-02-16 18:18:03 +05301866 qdf_event_set(&pHostapdState->cdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867
1868 /* notify userspace that the BSS has stopped */
1869 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1870 memcpy(&we_custom_event, stopBssEvent, event_len);
1871 memset(&wrqu, 0, sizeof(wrqu));
1872 wrqu.data.length = event_len;
1873 we_event = IWEVCUSTOM;
1874 we_custom_event_generic = we_custom_event;
1875 wireless_send_event(dev, we_event, &wrqu,
1876 (char *)we_custom_event_generic);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001877 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001878 /* Send SCC/MCC Switching event to IPA */
1879 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1880 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301881 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882}
1883
1884int hdd_softap_unpack_ie(tHalHandle halHandle,
1885 eCsrEncryptionType *pEncryptType,
1886 eCsrEncryptionType *mcEncryptType,
1887 eCsrAuthType *pAuthType,
1888 bool *pMFPCapable,
1889 bool *pMFPRequired,
1890 uint16_t gen_ie_len, uint8_t *gen_ie)
1891{
1892 tDot11fIERSN dot11RSNIE;
1893 tDot11fIEWPA dot11WPAIE;
1894
1895 uint8_t *pRsnIe;
1896 uint16_t RSNIeLen;
1897
1898 if (NULL == halHandle) {
1899 hddLog(LOGE, FL("Error haHandle returned NULL"));
1900 return -EINVAL;
1901 }
1902 /* Validity checks */
1903 if ((gen_ie_len < CDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
1904 || (gen_ie_len >
1905 CDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
1906 return -EINVAL;
1907 /* Type check */
1908 if (gen_ie[0] == DOT11F_EID_RSN) {
1909 /* Validity checks */
1910 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
1911 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301912 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001913 }
1914 /* Skip past the EID byte and length byte */
1915 pRsnIe = gen_ie + 2;
1916 RSNIeLen = gen_ie_len - 2;
1917 /* Unpack the RSN IE */
1918 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1919 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
1920 pRsnIe, RSNIeLen, &dot11RSNIE);
1921 /* Copy out the encryption and authentication types */
1922 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
1923 dot11RSNIE.pwise_cipher_suite_count);
1924 hddLog(LOG1, FL("authentication suite count: %d"),
1925 dot11RSNIE.akm_suite_count);
1926 /*Here we have followed the apple base code,
1927 but probably I suspect we can do something different */
1928 /* dot11RSNIE.akm_suite_count */
1929 /* Just translate the FIRST one */
1930 *pAuthType =
1931 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suites[0]);
1932 /* dot11RSNIE.pwise_cipher_suite_count */
1933 *pEncryptType =
1934 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1935 pwise_cipher_suites[0]);
1936 /* dot11RSNIE.gp_cipher_suite_count */
1937 *mcEncryptType =
1938 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1939 gp_cipher_suite);
1940 /* Set the PMKSA ID Cache for this interface */
1941 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1942 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
1943 /* Calling csr_roam_set_pmkid_cache to configure the PMKIDs into the cache */
1944 } else if (gen_ie[0] == DOT11F_EID_WPA) {
1945 /* Validity checks */
1946 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
1947 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301948 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001949 }
1950 /* Skip past the EID byte and length byte - and four byte WiFi OUI */
1951 pRsnIe = gen_ie + 2 + 4;
1952 RSNIeLen = gen_ie_len - (2 + 4);
1953 /* Unpack the WPA IE */
1954 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1955 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
1956 pRsnIe, RSNIeLen, &dot11WPAIE);
1957 /* Copy out the encryption and authentication types */
1958 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
1959 dot11WPAIE.unicast_cipher_count);
1960 hddLog(LOG1, FL("WPA authentication suite count: %d"),
1961 dot11WPAIE.auth_suite_count);
1962 /* dot11WPAIE.auth_suite_count */
1963 /* Just translate the FIRST one */
1964 *pAuthType =
1965 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
1966 /* dot11WPAIE.unicast_cipher_count */
1967 *pEncryptType =
1968 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1969 unicast_ciphers[0]);
1970 /* dot11WPAIE.unicast_cipher_count */
1971 *mcEncryptType =
1972 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1973 multicast_cipher);
1974 *pMFPCapable = false;
1975 *pMFPRequired = false;
1976 } else {
1977 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301978 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301980 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981}
1982
1983/**
1984 * hdd_softap_set_channel_change() -
1985 * This function to support SAP channel change with CSA IE
1986 * set in the beacons.
1987 *
1988 * @dev: pointer to the net device.
1989 * @target_channel: target channel number.
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301990 * @target_bw: Target bandwidth to move.
1991 * If no bandwidth is specified, the value is CH_WIDTH_MAX
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 *
1993 * Return: 0 for success, non zero for failure
1994 */
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301995int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
1996 phy_ch_width target_bw)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301998 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 int ret = 0;
2000 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2001 hdd_context_t *pHddCtx = NULL;
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302002 hdd_adapter_t *sta_adapter;
2003 hdd_station_ctx_t *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002004
2005#ifndef WLAN_FEATURE_MBSSID
2006 v_CONTEXT_t p_cds_context =
2007 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2008#endif
2009
2010 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2011 ret = wlan_hdd_validate_context(pHddCtx);
2012 if (ret) {
2013 hddLog(LOGE, FL("invalid HDD context"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014 return ret;
2015 }
2016
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +05302017 ret = hdd_validate_channel_and_bandwidth(pHostapdAdapter,
2018 target_channel, target_bw);
2019 if (ret) {
2020 hdd_err("Invalid CH and BW combo");
2021 return ret;
2022 }
2023
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302024 sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
2025 /*
2026 * conc_custom_rule1:
2027 * Force SCC for SAP + STA
2028 * if STA is already connected then we shouldn't allow
2029 * channel switch in SAP interface.
2030 */
2031 if (sta_adapter && pHddCtx->config->conc_custom_rule1) {
2032 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
2033 if (hdd_conn_is_connected(sta_ctx)) {
2034 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
2035 return -EBUSY;
2036 }
2037 }
2038
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302039 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040 if (pHddCtx->dfs_radar_found == true) {
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302041 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002042 hddLog(LOGE, FL("Channel switch in progress!!"));
2043 return -EBUSY;
2044 }
2045 /*
2046 * Set the dfs_radar_found flag to mimic channel change
2047 * when a radar is found. This will enable synchronizing
2048 * SAP and HDD states similar to that of radar indication.
2049 * Suspend the netif queues to stop queuing Tx frames
2050 * from upper layers. netif queues will be resumed
2051 * once the channel change is completed and SAP will
2052 * post eSAP_START_BSS_EVENT success event to HDD.
2053 */
2054 pHddCtx->dfs_radar_found = true;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302055 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 /*
2057 * Post the Channel Change request to SAP.
2058 */
2059 status = wlansap_set_channel_change_with_csa(
2060#ifdef WLAN_FEATURE_MBSSID
2061 WLAN_HDD_GET_SAP_CTX_PTR
2062 (pHostapdAdapter),
2063#else
2064 p_cds_context,
2065#endif
2066 (uint32_t)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302067 target_channel,
2068 target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002069
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302070 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002071 hddLog(LOGE,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302072 FL("SAP set channel failed for channel = %d, bw:%d"),
2073 target_channel, target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002074 /*
2075 * If channel change command fails then clear the
2076 * radar found flag and also restart the netif
2077 * queues.
2078 */
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302079 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302081 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002082
2083 ret = -EINVAL;
2084 }
2085
2086 return ret;
2087}
2088
2089int
2090static __iw_softap_set_ini_cfg(struct net_device *dev,
2091 struct iw_request_info *info,
2092 union iwreq_data *wrqu, char *extra)
2093{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302094 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095 int ret = 0; /* success */
2096 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2097 hdd_context_t *pHddCtx;
2098
2099 if (pAdapter == NULL) {
2100 hddLog(LOGE, FL("pAdapter is NULL!"));
2101 return -EINVAL;
2102 }
2103
2104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2105 ret = wlan_hdd_validate_context(pHddCtx);
2106 if (ret != 0) {
2107 hddLog(LOGE, FL("HDD context is not valid"));
2108 return ret;
2109 }
2110
2111 hddLog(LOG1, FL("Received data %s"), extra);
2112
2113 vstatus = hdd_execute_global_config_command(pHddCtx, extra);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302114 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002115 ret = -EINVAL;
2116 }
2117
2118 return ret;
2119}
2120
2121int
2122static iw_softap_set_ini_cfg(struct net_device *dev,
2123 struct iw_request_info *info,
2124 union iwreq_data *wrqu, char *extra)
2125{
2126 int ret;
2127
2128 cds_ssr_protect(__func__);
2129 ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
2130 cds_ssr_unprotect(__func__);
2131
2132 return ret;
2133}
2134
2135int
2136static __iw_softap_get_ini_cfg(struct net_device *dev,
2137 struct iw_request_info *info,
2138 union iwreq_data *wrqu, char *extra)
2139{
2140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2141 hdd_context_t *pHddCtx;
2142 int ret = 0;
2143
2144 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2145 ret = wlan_hdd_validate_context(pHddCtx);
2146 if (ret != 0) {
2147 hddLog(LOGE, FL("HDD context is not valid"));
2148 return ret;
2149 }
2150 hddLog(LOG1, FL("Printing CLD global INI Config"));
2151 hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN);
2152 wrqu->data.length = strlen(extra) + 1;
2153
2154 return 0;
2155}
2156
2157int
2158static iw_softap_get_ini_cfg(struct net_device *dev,
2159 struct iw_request_info *info,
2160 union iwreq_data *wrqu, char *extra)
2161{
2162 int ret;
2163
2164 cds_ssr_protect(__func__);
2165 ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
2166 cds_ssr_unprotect(__func__);
2167
2168 return ret;
2169}
2170
Govind Singha471e5e2015-10-12 17:11:14 +05302171/**
2172 * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
2173 * @dev: device upon which the ioctl was received
2174 * @info: ioctl request information
2175 * @wrqu: ioctl request data
2176 * @extra: ioctl extra data
2177 *
2178 * Return: 0 on success, non-zero on error
2179 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
2181 struct iw_request_info *info,
2182 union iwreq_data *wrqu, char *extra)
2183{
Govind Singha471e5e2015-10-12 17:11:14 +05302184 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2185 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186 int *value = (int *)extra;
2187 int sub_cmd = value[0];
Govind Singha471e5e2015-10-12 17:11:14 +05302188 hdd_context_t *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002189
Govind Singha471e5e2015-10-12 17:11:14 +05302190 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2191 ret = wlan_hdd_validate_context(hdd_ctx);
2192 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002193 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002194
2195 switch (sub_cmd) {
2196#ifdef DEBUG
2197 case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
2198 hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
2199 value[1], value[2]);
Govind Singha471e5e2015-10-12 17:11:14 +05302200 ret = wma_cli_set2_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201 GEN_PARAM_CRASH_INJECT,
2202 value[1], value[2],
2203 GEN_CMD);
2204 break;
2205#endif
2206 case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
2207 hdd_info("WE_DUMP_DP_TRACE: %d %d",
2208 value[1], value[2]);
2209 if (value[1] == DUMP_DP_TRACE)
2210 cdf_dp_trace_dump_all(value[2]);
2211 break;
Govind Singha471e5e2015-10-12 17:11:14 +05302212 case QCSAP_ENABLE_FW_PROFILE:
2213 hddLog(LOG1, "QCSAP_ENABLE_FW_PROFILE: %d %d",
2214 value[1], value[2]);
2215 ret = wma_cli_set2_command(adapter->sessionId,
2216 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2217 value[1], value[2], DBG_CMD);
2218 break;
2219 case QCSAP_SET_FW_PROFILE_HIST_INTVL:
2220 hddLog(LOG1, "QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
2221 value[1], value[2]);
2222 ret = wma_cli_set2_command(adapter->sessionId,
2223 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2224 value[1], value[2], DBG_CMD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225 default:
2226 hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
2227 break;
2228 }
2229
2230out:
2231 return ret;
2232}
2233
2234static int iw_softap_set_two_ints_getnone(struct net_device *dev,
2235 struct iw_request_info *info,
2236 union iwreq_data *wrqu, char *extra)
2237{
2238 int ret;
2239
2240 cds_ssr_protect(__func__);
2241 ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
2242 cds_ssr_unprotect(__func__);
2243
2244 return ret;
2245}
2246
2247static void print_mac_list(struct cdf_mac_addr *macList, uint8_t size)
2248{
2249 int i;
2250 uint8_t *macArray;
2251
2252 for (i = 0; i < size; i++) {
2253 macArray = (macList + i)->bytes;
2254 pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n",
2255 i, MAC_ADDR_ARRAY(macArray));
2256 }
2257 return;
2258}
2259
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302260static QDF_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261{
2262 eSapMacAddrACL acl_mode;
2263 struct cdf_mac_addr MacList[MAX_ACL_MAC_ADDRESS];
2264 uint8_t listnum;
2265 void *p_cds_gctx = NULL;
2266
2267#ifdef WLAN_FEATURE_MBSSID
2268 p_cds_gctx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter);
2269#else
2270 p_cds_gctx = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2271#endif
2272 cdf_mem_zero(&MacList[0], sizeof(MacList));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302273 if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(p_cds_gctx, &acl_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002274 pr_info("******** ACL MODE *********\n");
2275 switch (acl_mode) {
2276 case eSAP_ACCEPT_UNLESS_DENIED:
2277 pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
2278 break;
2279 case eSAP_DENY_UNLESS_ACCEPTED:
2280 pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
2281 break;
2282 case eSAP_SUPPORT_ACCEPT_AND_DENY:
2283 pr_info("ACL Mode = ACCEPT_AND_DENY\n");
2284 break;
2285 case eSAP_ALLOW_ALL:
2286 pr_info("ACL Mode = ALLOW_ALL\n");
2287 break;
2288 default:
2289 pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302290 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002291 }
2292 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302293 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002294 }
2295
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302296 if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002297 &MacList[0],
2298 &listnum)) {
2299 pr_info("******* WHITE LIST ***********\n");
2300 if (listnum <= MAX_ACL_MAC_ADDRESS)
2301 print_mac_list(&MacList[0], listnum);
2302 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302303 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 }
2305
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302306 if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 &MacList[0],
2308 &listnum)) {
2309 pr_info("******* BLACK LIST ***********\n");
2310 if (listnum <= MAX_ACL_MAC_ADDRESS)
2311 print_mac_list(&MacList[0], listnum);
2312 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302313 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002314 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302315 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002316}
2317
2318int
2319static __iw_softap_setparam(struct net_device *dev,
2320 struct iw_request_info *info,
2321 union iwreq_data *wrqu, char *extra)
2322{
2323 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2324 tHalHandle hHal;
2325 int *value = (int *)extra;
2326 int sub_cmd = value[0];
2327 int set_value = value[1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302328 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329 int ret = 0; /* success */
2330 v_CONTEXT_t p_cds_context;
2331 hdd_context_t *hdd_ctx;
2332
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302333 ENTER();
2334
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002335 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2336 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302337 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002339
2340 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2341 if (!hHal) {
2342 hddLog(LOGE, FL("Hal ctx is null"));
2343 return -EINVAL;
2344 }
2345
2346 p_cds_context = hdd_ctx->pcds_context;
2347 if (!p_cds_context) {
2348 hddLog(LOGE, FL("cds ctx is null"));
2349 return -ENOENT;
2350 }
2351
2352 switch (sub_cmd) {
2353 case QCASAP_SET_RADAR_DBG:
2354 hddLog(LOG1, FL("QCASAP_SET_RADAR_DBG called with: value: %d"),
2355 set_value);
2356 wlan_sap_enable_phy_error_logs(hHal, (bool) set_value);
2357 break;
2358
2359 case QCSAP_PARAM_CLR_ACL:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302360 if (QDF_STATUS_SUCCESS != wlansap_clear_acl(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002361#ifdef WLAN_FEATURE_MBSSID
2362 WLAN_HDD_GET_SAP_CTX_PTR
2363 (pHostapdAdapter)
2364#else
2365 p_cds_context
2366#endif
2367 )) {
2368 ret = -EIO;
2369 }
2370 break;
2371
2372 case QCSAP_PARAM_ACL_MODE:
2373 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
2374 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
2375 hddLog(LOGE, FL("Invalid ACL Mode value %d"),
2376 set_value);
2377 ret = -EINVAL;
2378 } else {
2379#ifdef WLAN_FEATURE_MBSSID
2380 wlansap_set_mode(WLAN_HDD_GET_SAP_CTX_PTR
2381 (pHostapdAdapter), set_value);
2382#else
2383 wlansap_set_mode(p_cds_context, set_value);
2384#endif
2385
2386 }
2387 break;
2388
2389 case QCSAP_PARAM_SET_CHANNEL_CHANGE:
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302390 if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) ||
2391 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 hddLog(LOG1,
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302393 "SET Channel Change to new channel= %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002394 set_value);
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302395 ret = hdd_softap_set_channel_change(dev, set_value,
2396 CH_WIDTH_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002397 } else {
2398 hddLog(LOGE,
2399 FL("Channel Change Failed, Device in test mode"));
2400 ret = -EINVAL;
2401 }
2402 break;
2403 case QCSAP_PARAM_AUTO_CHANNEL:
2404 if (set_value == 0 || set_value == 1)
2405 (WLAN_HDD_GET_CTX(
2406 pHostapdAdapter))->config->force_sap_acs =
2407 set_value;
2408 else
2409 ret = -EINVAL;
2410 break;
2411
2412 case QCSAP_PARAM_MAX_ASSOC:
2413 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
2414 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"),
2415 set_value);
2416 ret = -EINVAL;
2417 } else {
2418 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) {
2419 hddLog(LOGW,
2420 FL("setMaxAssoc %d > max allowed %d."),
2421 set_value,
2422 WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
2423 hddLog(LOGW,
2424 FL("Setting it to max allowed and continuing"));
2425 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
2426 }
2427 status = sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
2428 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302429 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002430 hddLog(LOGE,
2431 FL("setMaxAssoc failure, status %d"),
2432 status);
2433 ret = -EIO;
2434 }
2435 }
2436 break;
2437
2438 case QCSAP_PARAM_HIDE_SSID:
2439 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302440 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002441 status =
2442 sme_hide_ssid(hHal, pHostapdAdapter->sessionId,
2443 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302444 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002445 hddLog(LOGE, FL("QCSAP_PARAM_HIDE_SSID failed"));
2446 return status;
2447 }
2448 break;
2449 }
2450 case QCSAP_PARAM_SET_MC_RATE:
2451 {
2452 tSirRateUpdateInd rateUpdate = {0};
2453 struct hdd_config *pConfig = hdd_ctx->config;
2454
2455 hddLog(LOG1, "MC Target rate %d", set_value);
Srinivas Girigowdaafede182015-11-18 22:36:12 -08002456 cdf_copy_macaddr(&rateUpdate.bssid,
2457 &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002458 rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1;
2459 rateUpdate.dev_mode = pHostapdAdapter->device_mode;
2460 rateUpdate.mcastDataRate24GHz = set_value;
2461 rateUpdate.mcastDataRate24GHzTxFlag = 1;
2462 rateUpdate.mcastDataRate5GHz = set_value;
2463 rateUpdate.bcastDataRate = -1;
2464 status = sme_send_rate_update_ind(hHal, &rateUpdate);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302465 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002466 hddLog(LOGE, FL("SET_MC_RATE failed"));
2467 ret = -1;
2468 }
2469 break;
2470 }
2471
2472 case QCSAP_PARAM_SET_TXRX_FW_STATS:
2473 {
2474 hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
2475 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2476 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
2477 set_value, VDEV_CMD);
2478 break;
2479 }
2480 /* Firmware debug log */
2481 case QCSAP_DBGLOG_LOG_LEVEL:
2482 {
2483 hddLog(LOG1, "QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
2484 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2485 WMI_DBGLOG_LOG_LEVEL,
2486 set_value, DBG_CMD);
2487 break;
2488 }
2489
2490 case QCSAP_DBGLOG_VAP_ENABLE:
2491 {
2492 hddLog(LOG1, "QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
2493 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2494 WMI_DBGLOG_VAP_ENABLE,
2495 set_value, DBG_CMD);
2496 break;
2497 }
2498
2499 case QCSAP_DBGLOG_VAP_DISABLE:
2500 {
2501 hddLog(LOG1, "QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
2502 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2503 WMI_DBGLOG_VAP_DISABLE,
2504 set_value, DBG_CMD);
2505 break;
2506 }
2507
2508 case QCSAP_DBGLOG_MODULE_ENABLE:
2509 {
2510 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
2511 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2512 WMI_DBGLOG_MODULE_ENABLE,
2513 set_value, DBG_CMD);
2514 break;
2515 }
2516
2517 case QCSAP_DBGLOG_MODULE_DISABLE:
2518 {
2519 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
2520 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2521 WMI_DBGLOG_MODULE_DISABLE,
2522 set_value, DBG_CMD);
2523 break;
2524 }
2525
2526 case QCSAP_DBGLOG_MOD_LOG_LEVEL:
2527 {
2528 hddLog(LOG1, "QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
2529 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2530 WMI_DBGLOG_MOD_LOG_LEVEL,
2531 set_value, DBG_CMD);
2532 break;
2533 }
2534
2535 case QCSAP_DBGLOG_TYPE:
2536 {
2537 hddLog(LOG1, "QCSAP_DBGLOG_TYPE val %d", set_value);
2538 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2539 WMI_DBGLOG_TYPE,
2540 set_value, DBG_CMD);
2541 break;
2542 }
2543 case QCSAP_DBGLOG_REPORT_ENABLE:
2544 {
2545 hddLog(LOG1, "QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
2546 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2547 WMI_DBGLOG_REPORT_ENABLE,
2548 set_value, DBG_CMD);
2549 break;
2550 }
2551 case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
2552 {
2553 cds_set_mcc_latency(pHostapdAdapter, set_value);
2554 break;
2555 }
2556
2557 case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
2558 {
2559 hddLog(LOG1,
2560 FL("iwpriv cmd to set MCC quota value %dms"),
2561 set_value);
2562 ret = cds_go_set_mcc_p2p_quota(pHostapdAdapter,
2563 set_value);
2564 break;
2565 }
2566
2567 case QCASAP_TXRX_FWSTATS_RESET:
2568 {
2569 hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
2570 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2571 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
2572 set_value, VDEV_CMD);
2573 break;
2574 }
2575
2576 case QCSAP_PARAM_RTSCTS:
2577 {
2578 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2579 WMI_VDEV_PARAM_ENABLE_RTSCTS,
2580 set_value, VDEV_CMD);
2581 if (ret) {
2582 hddLog(LOGE, "FAILED TO SET RTSCTS at SAP");
2583 ret = -EIO;
2584 }
2585 break;
2586 }
2587 case QCASAP_SET_11N_RATE:
2588 {
2589 uint8_t preamble = 0, nss = 0, rix = 0;
2590 tsap_Config_t *pConfig =
2591 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2592
2593 hddLog(LOG1, "SET_HT_RATE val %d", set_value);
2594
2595 if (set_value != 0xff) {
2596 rix = RC_2_RATE_IDX(set_value);
2597 if (set_value & 0x80) {
2598 if (pConfig->SapHw_mode ==
2599 eCSR_DOT11_MODE_11b
2600 || pConfig->SapHw_mode ==
2601 eCSR_DOT11_MODE_11b_ONLY
2602 || pConfig->SapHw_mode ==
2603 eCSR_DOT11_MODE_11g
2604 || pConfig->SapHw_mode ==
2605 eCSR_DOT11_MODE_11g_ONLY
2606 || pConfig->SapHw_mode ==
2607 eCSR_DOT11_MODE_abg
2608 || pConfig->SapHw_mode ==
2609 eCSR_DOT11_MODE_11a) {
2610 hddLog(LOGE,
2611 "Not valid mode for HT");
2612 ret = -EIO;
2613 break;
2614 }
2615 preamble = WMI_RATE_PREAMBLE_HT;
2616 nss = HT_RC_2_STREAMS(set_value) - 1;
2617 } else if (set_value & 0x10) {
2618 if (pConfig->SapHw_mode ==
2619 eCSR_DOT11_MODE_11a) {
2620 hddLog(LOGE, "Not valid for cck");
2621 ret = -EIO;
2622 break;
2623 }
2624 preamble = WMI_RATE_PREAMBLE_CCK;
2625 /* Enable Short preamble always
2626 * for CCK except 1mbps
2627 */
2628 if (rix != 0x3)
2629 rix |= 0x4;
2630 } else {
2631 if (pConfig->SapHw_mode ==
2632 eCSR_DOT11_MODE_11b
2633 || pConfig->SapHw_mode ==
2634 eCSR_DOT11_MODE_11b_ONLY) {
2635 hddLog(LOGE, "Not valid for OFDM");
2636 ret = -EIO;
2637 break;
2638 }
2639 preamble = WMI_RATE_PREAMBLE_OFDM;
2640 }
2641 set_value = (preamble << 6) | (nss << 4) | rix;
2642 }
2643 hddLog(LOG1, "SET_HT_RATE val %d rix %d preamble %x nss %d",
2644 set_value, rix, preamble, nss);
2645 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2646 WMI_VDEV_PARAM_FIXED_RATE,
2647 set_value, VDEV_CMD);
2648 break;
2649 }
2650
2651 case QCASAP_SET_VHT_RATE:
2652 {
2653 uint8_t preamble = 0, nss = 0, rix = 0;
2654 tsap_Config_t *pConfig =
2655 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2656
2657 if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
2658 pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
2659 hddLog(LOGE,
2660 FL("SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d"),
2661 pConfig->SapHw_mode, pConfig->channel);
2662 ret = -EIO;
2663 break;
2664 }
2665
2666 if (set_value != 0xff) {
2667 rix = RC_2_RATE_IDX_11AC(set_value);
2668 preamble = WMI_RATE_PREAMBLE_VHT;
2669 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
2670
2671 set_value = (preamble << 6) | (nss << 4) | rix;
2672 }
2673 hddLog(LOG1, "SET_VHT_RATE val %d rix %d preamble %x nss %d",
2674 set_value, rix, preamble, nss);
2675
2676 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2677 WMI_VDEV_PARAM_FIXED_RATE,
2678 set_value, VDEV_CMD);
2679 break;
2680 }
2681
2682 case QCASAP_SHORT_GI:
2683 {
2684 hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value);
2685
2686 /* same as 40MHZ */
2687 ret = sme_update_ht_config(hHal, pHostapdAdapter->sessionId,
2688 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
2689 set_value);
2690 if (ret)
2691 hddLog(LOGE,
2692 "Failed to set ShortGI value ret(%d)", ret);
2693 break;
2694 }
2695
2696 case QCSAP_SET_AMPDU:
2697 {
2698 hddLog(LOG1, "QCSAP_SET_AMPDU %d", set_value);
2699 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2700 GEN_VDEV_PARAM_AMPDU,
2701 set_value, GEN_CMD);
2702 break;
2703 }
2704
2705 case QCSAP_SET_AMSDU:
2706 {
2707 hddLog(LOG1, "QCSAP_SET_AMSDU %d", set_value);
2708 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2709 GEN_VDEV_PARAM_AMSDU,
2710 set_value, GEN_CMD);
2711 break;
2712 }
2713 case QCSAP_GTX_HT_MCS:
2714 {
2715 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
2716 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2717 WMI_VDEV_PARAM_GTX_HT_MCS,
2718 set_value, GTX_CMD);
2719 break;
2720 }
2721
2722 case QCSAP_GTX_VHT_MCS:
2723 {
2724 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
2725 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2726 WMI_VDEV_PARAM_GTX_VHT_MCS,
2727 set_value, GTX_CMD);
2728 break;
2729 }
2730
2731 case QCSAP_GTX_USRCFG:
2732 {
2733 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
2734 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2735 WMI_VDEV_PARAM_GTX_USR_CFG,
2736 set_value, GTX_CMD);
2737 break;
2738 }
2739
2740 case QCSAP_GTX_THRE:
2741 {
2742 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
2743 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2744 WMI_VDEV_PARAM_GTX_THRE,
2745 set_value, GTX_CMD);
2746 break;
2747 }
2748
2749 case QCSAP_GTX_MARGIN:
2750 {
2751 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
2752 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2753 WMI_VDEV_PARAM_GTX_MARGIN,
2754 set_value, GTX_CMD);
2755 break;
2756 }
2757
2758 case QCSAP_GTX_STEP:
2759 {
2760 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
2761 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2762 WMI_VDEV_PARAM_GTX_STEP,
2763 set_value, GTX_CMD);
2764 break;
2765 }
2766
2767 case QCSAP_GTX_MINTPC:
2768 {
2769 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
2770 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2771 WMI_VDEV_PARAM_GTX_MINTPC,
2772 set_value, GTX_CMD);
2773 break;
2774 }
2775
2776 case QCSAP_GTX_BWMASK:
2777 {
2778 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
2779 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2780 WMI_VDEV_PARAM_GTX_BW_MASK,
2781 set_value, GTX_CMD);
2782 break;
2783 }
2784
2785#ifdef QCA_PKT_PROTO_TRACE
2786 case QCASAP_SET_DEBUG_LOG:
2787 {
2788 hdd_context_t *pHddCtx =
2789 WLAN_HDD_GET_CTX(pHostapdAdapter);
2790
2791 hddLog(LOG1, "QCASAP_SET_DEBUG_LOG val %d", set_value);
2792 /* Trace buffer dump only */
2793 if (CDS_PKT_TRAC_DUMP_CMD == set_value) {
2794 cds_pkt_trace_buf_dump();
2795 break;
2796 }
2797 pHddCtx->config->gEnableDebugLog = set_value;
2798 break;
2799 }
2800#endif /* QCA_PKT_PROTO_TRACE */
2801
2802 case QCASAP_SET_TM_LEVEL:
2803 {
2804 hddLog(LOG1, "Set Thermal Mitigation Level %d", set_value);
2805 (void)sme_set_thermal_level(hHal, set_value);
2806 break;
2807 }
2808
2809 case QCASAP_SET_DFS_IGNORE_CAC:
2810 {
2811 hddLog(LOG1, "Set Dfs ignore CAC %d", set_value);
2812
2813 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2814 return -EINVAL;
2815
2816 ret = wlansap_set_dfs_ignore_cac(hHal, set_value);
2817 break;
2818 }
2819
2820 case QCASAP_SET_DFS_TARGET_CHNL:
2821 {
2822 hddLog(LOG1, "Set Dfs target channel %d", set_value);
2823
2824 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2825 return -EINVAL;
2826
2827 ret = wlansap_set_dfs_target_chnl(hHal, set_value);
2828 break;
2829 }
2830
2831 case QCASAP_SET_DFS_NOL:
2832 wlansap_set_dfs_nol(
2833#ifdef WLAN_FEATURE_MBSSID
2834 WLAN_HDD_GET_SAP_CTX_PTR
2835 (pHostapdAdapter),
2836#else
2837 p_cds_context,
2838#endif
2839 (eSapDfsNolType) set_value);
2840 break;
2841
2842 case QCASAP_SET_RADAR_CMD:
2843 {
2844 hdd_context_t *pHddCtx =
2845 WLAN_HDD_GET_CTX(pHostapdAdapter);
2846 uint8_t ch =
2847 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
2848 operatingChannel;
2849 bool isDfsch;
2850
2851 isDfsch = (CHANNEL_STATE_DFS ==
2852 cds_get_channel_state(ch));
2853
2854 hddLog(LOG1, FL("Set QCASAP_SET_RADAR_CMD val %d"), set_value);
2855
2856 if (!pHddCtx->dfs_radar_found && isDfsch) {
2857 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2858 WMA_VDEV_DFS_CONTROL_CMDID,
2859 set_value, VDEV_CMD);
2860 } else {
2861 hddLog(LOGE,
2862 FL("Ignore, radar_found: %d, dfs_channel: %d"),
2863 pHddCtx->dfs_radar_found, isDfsch);
2864 }
2865 break;
2866 }
2867 case QCASAP_TX_CHAINMASK_CMD:
2868 {
2869 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD val %d", set_value);
2870 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2871 WMI_PDEV_PARAM_TX_CHAIN_MASK,
2872 set_value, PDEV_CMD);
2873 break;
2874 }
2875
2876 case QCASAP_RX_CHAINMASK_CMD:
2877 {
2878 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD val %d", set_value);
2879 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2880 WMI_PDEV_PARAM_RX_CHAIN_MASK,
2881 set_value, PDEV_CMD);
2882 break;
2883 }
2884
2885 case QCASAP_NSS_CMD:
2886 {
2887 hddLog(LOG1, "QCASAP_NSS_CMD val %d", set_value);
2888 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2889 WMI_VDEV_PARAM_NSS,
2890 set_value, VDEV_CMD);
2891 break;
2892 }
2893
2894 case QCSAP_IPA_UC_STAT:
2895 {
2896 /* If input value is non-zero get stats */
2897 switch (set_value) {
2898 case 1:
2899 hdd_ipa_uc_stat_request(pHostapdAdapter, set_value);
2900 break;
2901 case 3:
2902 hdd_ipa_uc_rt_debug_host_dump(
2903 WLAN_HDD_GET_CTX(pHostapdAdapter));
2904 break;
2905 default:
2906 /* place holder for stats clean up
2907 * Stats clean not implemented yet on firmware and ipa
2908 */
2909 break;
2910 }
2911 return ret;
2912 }
2913
2914 case QCASAP_SET_PHYMODE:
2915 {
2916 hdd_context_t *phddctx =
2917 WLAN_HDD_GET_CTX(pHostapdAdapter);
2918
2919 ret =
2920 wlan_hdd_update_phymode(dev, hHal, set_value,
2921 phddctx);
2922 break;
2923 }
2924 case QCASAP_DUMP_STATS:
2925 {
2926 hddLog(LOG1, "QCASAP_DUMP_STATS val %d", set_value);
2927 hdd_wlan_dump_stats(pHostapdAdapter, set_value);
2928 break;
2929 }
2930 case QCASAP_CLEAR_STATS:
2931 {
2932 hdd_context_t *hdd_ctx =
2933 WLAN_HDD_GET_CTX(pHostapdAdapter);
2934 hddLog(LOG1, "QCASAP_CLEAR_STATS val %d", set_value);
2935 switch (set_value) {
2936 case WLAN_HDD_STATS:
2937 memset(&pHostapdAdapter->stats, 0,
2938 sizeof(pHostapdAdapter->stats));
2939 memset(&pHostapdAdapter->hdd_stats, 0,
2940 sizeof(pHostapdAdapter->hdd_stats));
2941 break;
2942 case WLAN_TXRX_HIST_STATS:
2943 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
2944 break;
2945 case WLAN_HDD_NETIF_OPER_HISTORY:
2946 wlan_hdd_clear_netif_queue_history(hdd_ctx);
2947 break;
2948 default:
2949 ol_txrx_clear_stats(set_value);
2950 }
2951 break;
2952 }
Govind Singha471e5e2015-10-12 17:11:14 +05302953 case QCSAP_START_FW_PROFILING:
2954 hddLog(LOG1, "QCSAP_START_FW_PROFILING %d", set_value);
2955 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2956 WMI_WLAN_PROFILE_TRIGGER_CMDID,
2957 set_value, DBG_CMD);
2958 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002959 default:
2960 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
2961 sub_cmd, set_value);
2962 ret = -EINVAL;
2963 break;
2964 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302965 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002966 return ret;
2967}
2968
2969int
2970static iw_softap_setparam(struct net_device *dev,
2971 struct iw_request_info *info,
2972 union iwreq_data *wrqu, char *extra)
2973{
2974 int ret;
2975
2976 cds_ssr_protect(__func__);
2977 ret = __iw_softap_setparam(dev, info, wrqu, extra);
2978 cds_ssr_unprotect(__func__);
2979
2980 return ret;
2981}
2982
2983int
2984static __iw_softap_getparam(struct net_device *dev,
2985 struct iw_request_info *info,
2986 union iwreq_data *wrqu, char *extra)
2987{
2988 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2989 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2990 int *value = (int *)extra;
2991 int sub_cmd = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302992 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002993 int ret;
2994 hdd_context_t *hdd_ctx;
2995
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302996 ENTER();
2997
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002998 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2999 ret = wlan_hdd_validate_context(hdd_ctx);
3000 if (0 != ret)
3001 return ret;
3002
3003 switch (sub_cmd) {
3004 case QCSAP_PARAM_MAX_ASSOC:
3005 status =
3006 sme_cfg_get_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
3007 (uint32_t *) value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303008 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003009 hddLog(LOGE,
3010 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),
3011 status);
3012 ret = -EIO;
3013 }
3014 break;
3015
3016 case QCSAP_PARAM_AUTO_CHANNEL:
3017 *value = (WLAN_HDD_GET_CTX
3018 (pHostapdAdapter))->config->force_sap_acs;
3019 break;
3020
3021 case QCSAP_PARAM_GET_WLAN_DBG:
3022 {
3023 cdf_trace_display();
3024 *value = 0;
3025 break;
3026 }
3027
3028 case QCSAP_PARAM_RTSCTS:
3029 {
3030 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3031 WMI_VDEV_PARAM_ENABLE_RTSCTS,
3032 VDEV_CMD);
3033 break;
3034 }
3035
3036 case QCASAP_SHORT_GI:
3037 {
3038 *value = (int)sme_get_ht_config(hHal,
3039 pHostapdAdapter->
3040 sessionId,
3041 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
3042 break;
3043 }
3044
3045 case QCSAP_GTX_HT_MCS:
3046 {
3047 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
3048 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3049 WMI_VDEV_PARAM_GTX_HT_MCS,
3050 GTX_CMD);
3051 break;
3052 }
3053
3054 case QCSAP_GTX_VHT_MCS:
3055 {
3056 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
3057 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3058 WMI_VDEV_PARAM_GTX_VHT_MCS,
3059 GTX_CMD);
3060 break;
3061 }
3062
3063 case QCSAP_GTX_USRCFG:
3064 {
3065 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
3066 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3067 WMI_VDEV_PARAM_GTX_USR_CFG,
3068 GTX_CMD);
3069 break;
3070 }
3071
3072 case QCSAP_GTX_THRE:
3073 {
3074 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
3075 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3076 WMI_VDEV_PARAM_GTX_THRE,
3077 GTX_CMD);
3078 break;
3079 }
3080
3081 case QCSAP_GTX_MARGIN:
3082 {
3083 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
3084 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3085 WMI_VDEV_PARAM_GTX_MARGIN,
3086 GTX_CMD);
3087 break;
3088 }
3089
3090 case QCSAP_GTX_STEP:
3091 {
3092 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
3093 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3094 WMI_VDEV_PARAM_GTX_STEP,
3095 GTX_CMD);
3096 break;
3097 }
3098
3099 case QCSAP_GTX_MINTPC:
3100 {
3101 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
3102 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3103 WMI_VDEV_PARAM_GTX_MINTPC,
3104 GTX_CMD);
3105 break;
3106 }
3107
3108 case QCSAP_GTX_BWMASK:
3109 {
3110 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
3111 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3112 WMI_VDEV_PARAM_GTX_BW_MASK,
3113 GTX_CMD);
3114 break;
3115 }
3116
3117 case QCASAP_GET_DFS_NOL:
3118 {
3119 wlansap_get_dfs_nol(
3120#ifdef WLAN_FEATURE_MBSSID
3121 WLAN_HDD_GET_SAP_CTX_PTR
3122 (pHostapdAdapter)
3123#else
3124 pHddCtx->pcds_context
3125#endif
3126 );
3127 }
3128 break;
3129
3130 case QCSAP_GET_ACL:
3131 {
3132 hddLog(LOG1, FL("QCSAP_GET_ACL"));
3133 if (hdd_print_acl(pHostapdAdapter) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303134 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003135 hddLog(LOGE,
3136 FL
3137 ("QCSAP_GET_ACL returned Error: not completed"));
3138 }
3139 *value = 0;
3140 break;
3141 }
3142
3143 case QCASAP_TX_CHAINMASK_CMD:
3144 {
3145 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD");
3146 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3147 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3148 PDEV_CMD);
3149 break;
3150 }
3151
3152 case QCASAP_RX_CHAINMASK_CMD:
3153 {
3154 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD");
3155 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3156 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3157 PDEV_CMD);
3158 break;
3159 }
3160
3161 case QCASAP_NSS_CMD:
3162 {
3163 hddLog(LOG1, "QCASAP_NSS_CMD");
3164 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3165 WMI_VDEV_PARAM_NSS,
3166 VDEV_CMD);
3167 break;
3168 }
3169 case QCASAP_GET_TEMP_CMD:
3170 {
3171 hddLog(LOG1, "QCASAP_GET_TEMP_CMD");
3172 ret = wlan_hdd_get_temperature(pHostapdAdapter, value);
3173 break;
3174 }
Govind Singha471e5e2015-10-12 17:11:14 +05303175 case QCSAP_GET_FW_PROFILE_DATA:
3176 hddLog(LOG1, "QCSAP_GET_FW_PROFILE_DATA");
3177 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3178 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
3179 0, DBG_CMD);
3180 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003181 default:
3182 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
3183 ret = -EINVAL;
3184 break;
3185
3186 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303187 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003188 return ret;
3189}
3190
3191int
3192static iw_softap_getparam(struct net_device *dev,
3193 struct iw_request_info *info,
3194 union iwreq_data *wrqu, char *extra)
3195{
3196 int ret;
3197
3198 cds_ssr_protect(__func__);
3199 ret = __iw_softap_getparam(dev, info, wrqu, extra);
3200 cds_ssr_unprotect(__func__);
3201
3202 return ret;
3203}
3204
3205/* Usage:
3206 BLACK_LIST = 0
3207 WHITE_LIST = 1
3208 ADD MAC = 0
3209 REMOVE MAC = 1
3210
3211 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3212 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3213 while using this ioctl
3214
3215 Syntax:
3216 iwpriv softap.0 modify_acl
3217 <6 octet mac addr> <list type> <cmd type>
3218
3219 Examples:
3220 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
3221 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
3222 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
3223 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
3224 */
3225static
3226int __iw_softap_modify_acl(struct net_device *dev,
3227 struct iw_request_info *info,
3228 union iwreq_data *wrqu, char *extra)
3229{
3230 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3231#ifndef WLAN_FEATURE_MBSSID
3232 v_CONTEXT_t cds_ctx;
3233#endif
3234 uint8_t *value = (uint8_t *) extra;
3235 uint8_t pPeerStaMac[CDF_MAC_ADDR_SIZE];
3236 int listType, cmd, i;
3237 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303238 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003239 hdd_context_t *hdd_ctx;
3240
3241 ENTER();
3242
3243 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3244 ret = wlan_hdd_validate_context(hdd_ctx);
3245 if (0 != ret)
3246 return ret;
3247
3248#ifndef WLAN_FEATURE_MBSSID
3249 cds_ctx = hdd_ctx->pcds_context;
3250 if (NULL == cds_ctx) {
3251 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3252 "%s: Vos Context is NULL", __func__);
3253 return -EINVAL;
3254 }
3255#endif
3256
3257 for (i = 0; i < CDF_MAC_ADDR_SIZE; i++)
3258 pPeerStaMac[i] = *(value + i);
3259
3260 listType = (int)(*(value + i));
3261 i++;
3262 cmd = (int)(*(value + i));
3263
3264 hddLog(LOG1, FL("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d"),
3265 MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
3266
3267#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303268 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003269 wlansap_modify_acl(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
3270 pPeerStaMac, (eSapACLType) listType,
3271 (eSapACLCmdType) cmd);
3272#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303273 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274 wlansap_modify_acl(p_cds_context, pPeerStaMac,
3275 (eSapACLType) listType, (eSapACLCmdType) cmd);
3276#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303277 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 hddLog(LOGE, FL("Modify ACL failed"));
3279 ret = -EIO;
3280 }
3281 EXIT();
3282 return ret;
3283}
3284
3285static
3286int iw_softap_modify_acl(struct net_device *dev,
3287 struct iw_request_info *info,
3288 union iwreq_data *wrqu, char *extra)
3289{
3290 int ret;
3291
3292 cds_ssr_protect(__func__);
3293 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
3294 cds_ssr_unprotect(__func__);
3295
3296 return ret;
3297}
3298
3299int
3300static __iw_softap_getchannel(struct net_device *dev,
3301 struct iw_request_info *info,
3302 union iwreq_data *wrqu, char *extra)
3303{
3304 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3305 hdd_context_t *hdd_ctx;
3306 int *value = (int *)extra;
3307 int ret;
3308
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303309 ENTER();
3310
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003311 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3312 ret = wlan_hdd_validate_context(hdd_ctx);
3313 if (0 != ret)
3314 return ret;
3315
3316 *value = 0;
3317 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3318 *value = (WLAN_HDD_GET_AP_CTX_PTR(
3319 pHostapdAdapter))->operatingChannel;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303320 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003321 return 0;
3322}
3323
3324int
3325static iw_softap_getchannel(struct net_device *dev,
3326 struct iw_request_info *info,
3327 union iwreq_data *wrqu, char *extra)
3328{
3329 int ret;
3330
3331 cds_ssr_protect(__func__);
3332 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
3333 cds_ssr_unprotect(__func__);
3334
3335 return ret;
3336}
3337
3338int
3339static __iw_softap_set_max_tx_power(struct net_device *dev,
3340 struct iw_request_info *info,
3341 union iwreq_data *wrqu, char *extra)
3342{
3343 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3344 hdd_context_t *hdd_ctx;
3345 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3346 int *value = (int *)extra;
3347 int set_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003348 int ret;
Srinivas Girigowda97215232015-09-24 12:26:28 -07003349 struct cdf_mac_addr bssid = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
3350 struct cdf_mac_addr selfMac = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003351
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303352 ENTER();
3353
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003354 if (NULL == value)
3355 return -ENOMEM;
3356
3357 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3358 ret = wlan_hdd_validate_context(hdd_ctx);
3359 if (0 != ret)
3360 return ret;
3361
3362 /* Assign correct slef MAC address */
Srinivas Girigowda97215232015-09-24 12:26:28 -07003363 cdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
3364 cdf_copy_macaddr(&selfMac, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003365
3366 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303367 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 sme_set_max_tx_power(hHal, bssid, selfMac, set_value)) {
3369 hddLog(LOGE, FL("Setting maximum tx power failed"));
3370 return -EIO;
3371 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303372 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003373 return 0;
3374}
3375
3376int
3377static iw_softap_set_max_tx_power(struct net_device *dev,
3378 struct iw_request_info *info,
3379 union iwreq_data *wrqu, char *extra)
3380{
3381 int ret;
3382
3383 cds_ssr_protect(__func__);
3384 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
3385 cds_ssr_unprotect(__func__);
3386
3387 return ret;
3388}
3389
3390int
3391static __iw_softap_set_tx_power(struct net_device *dev,
3392 struct iw_request_info *info,
3393 union iwreq_data *wrqu, char *extra)
3394{
3395 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3396 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3397 hdd_context_t *hdd_ctx;
3398 int *value = (int *)extra;
3399 int set_value;
Srinivas Girigowda97215232015-09-24 12:26:28 -07003400 struct cdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401 int ret;
3402
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303403 ENTER();
3404
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003405 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3406 ret = wlan_hdd_validate_context(hdd_ctx);
3407 if (0 != ret)
3408 return ret;
3409
3410 if (NULL == value)
3411 return -ENOMEM;
3412
Srinivas Girigowda97215232015-09-24 12:26:28 -07003413 cdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003414
3415 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303416 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003417 sme_set_tx_power(hHal, pHostapdAdapter->sessionId, bssid,
3418 pHostapdAdapter->device_mode, set_value)) {
3419 hddLog(LOGE, FL("Setting tx power failed"));
3420 return -EIO;
3421 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303422 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003423 return 0;
3424}
3425
3426int
3427static iw_softap_set_tx_power(struct net_device *dev,
3428 struct iw_request_info *info,
3429 union iwreq_data *wrqu, char *extra)
3430{
3431 int ret;
3432
3433 cds_ssr_protect(__func__);
3434 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
3435 cds_ssr_unprotect(__func__);
3436
3437 return ret;
3438}
3439
3440#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
3441
3442int
3443static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
3444 struct iw_request_info *info,
3445 union iwreq_data *wrqu, char *extra)
3446{
3447 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3448 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
3449 hdd_context_t *hdd_ctx;
3450 char *buf;
3451 int cnt = 0;
3452 int left;
3453 int ret;
3454 /* maclist_index must be u32 to match userspace */
3455 u32 maclist_index;
3456
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303457 ENTER();
3458
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 /*
3460 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
3461 * number, and even numbered iocts are supposed to have "set"
3462 * semantics. Hence the wireless extensions support in the kernel
3463 * won't correctly copy the result to userspace, so the ioctl
3464 * handler itself must copy the data. Output format is 32-bit
3465 * record length, followed by 0 or more 6-byte STA MAC addresses.
3466 *
3467 * Further note that due to the incorrect semantics, the "iwpriv"
3468 * userspace application is unable to correctly invoke this API,
3469 * hence it is not registered in the hostapd_private_args. This
3470 * API can only be invoked by directly invoking the ioctl() system
3471 * call.
3472 */
3473
3474 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3475 ret = wlan_hdd_validate_context(hdd_ctx);
3476 if (0 != ret)
3477 return ret;
3478
3479 /* make sure userspace allocated a reasonable buffer size */
3480 if (wrqu->data.length < sizeof(maclist_index)) {
3481 hddLog(LOG1, FL("invalid userspace buffer"));
3482 return -EINVAL;
3483 }
3484
3485 /* allocate local buffer to build the response */
3486 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
3487 if (!buf) {
3488 hddLog(LOG1, FL("failed to allocate response buffer"));
3489 return -ENOMEM;
3490 }
3491
3492 /* start indexing beyond where the record count will be written */
3493 maclist_index = sizeof(maclist_index);
3494 left = wrqu->data.length - maclist_index;
3495
3496 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
3497 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= CDF_MAC_ADDR_SIZE)) {
3498 if ((pStaInfo[cnt].isUsed) &&
3499 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
3500 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
3501 CDF_MAC_ADDR_SIZE);
3502 maclist_index += CDF_MAC_ADDR_SIZE;
3503 left -= CDF_MAC_ADDR_SIZE;
3504 }
3505 cnt++;
3506 }
3507 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
3508
3509 *((u32 *) buf) = maclist_index;
3510 wrqu->data.length = maclist_index;
3511 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
3512 hddLog(LOG1, FL("failed to copy response to user buffer"));
3513 ret = -EFAULT;
3514 }
3515 kfree(buf);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303516 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003517 return ret;
3518}
3519
3520int
3521static iw_softap_getassoc_stamacaddr(struct net_device *dev,
3522 struct iw_request_info *info,
3523 union iwreq_data *wrqu, char *extra)
3524{
3525 int ret;
3526
3527 cds_ssr_protect(__func__);
3528 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
3529 cds_ssr_unprotect(__func__);
3530
3531 return ret;
3532}
3533
3534/* Usage:
3535 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3536 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3537 while using this ioctl
3538
3539 Syntax:
3540 iwpriv softap.0 disassoc_sta <6 octet mac address>
3541
3542 e.g.
3543 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
3544 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
3545 */
3546
3547int
3548static __iw_softap_disassoc_sta(struct net_device *dev,
3549 struct iw_request_info *info,
3550 union iwreq_data *wrqu, char *extra)
3551{
3552 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3553 hdd_context_t *hdd_ctx;
3554 uint8_t *peerMacAddr;
3555 int ret;
3556
3557 ENTER();
3558
Mukul Sharma744420f2015-11-02 19:49:13 +05303559 if (!capable(CAP_NET_ADMIN)) {
3560 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3561 FL("permission check failed"));
3562 return -EPERM;
3563 }
3564
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003565 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3566 ret = wlan_hdd_validate_context(hdd_ctx);
3567 if (0 != ret)
3568 return ret;
3569
3570 /* iwpriv tool or framework calls this ioctl with
3571 * data passed in extra (less than 16 octets);
3572 */
3573 peerMacAddr = (uint8_t *) (extra);
3574
3575 hddLog(LOG1, FL("data " MAC_ADDRESS_STR),
3576 MAC_ADDR_ARRAY(peerMacAddr));
3577 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
3578 EXIT();
3579 return 0;
3580}
3581
3582int
3583static iw_softap_disassoc_sta(struct net_device *dev,
3584 struct iw_request_info *info,
3585 union iwreq_data *wrqu, char *extra)
3586{
3587 int ret;
3588
3589 cds_ssr_protect(__func__);
3590 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
3591 cds_ssr_unprotect(__func__);
3592
3593 return ret;
3594}
3595
Govind Singha471e5e2015-10-12 17:11:14 +05303596/**
3597 * iw_get_char_setnone() - Generic "get char" private ioctl handler
3598 * @dev: device upon which the ioctl was received
3599 * @info: ioctl request information
3600 * @wrqu: ioctl request data
3601 * @extra: ioctl extra data
3602 *
3603 * Return: 0 on success, non-zero on error
3604 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003605static int __iw_get_char_setnone(struct net_device *dev,
3606 struct iw_request_info *info,
3607 union iwreq_data *wrqu, char *extra)
3608{
3609 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Govind Singha471e5e2015-10-12 17:11:14 +05303610 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003611 int sub_cmd = wrqu->data.flags;
3612 hdd_context_t *hdd_ctx;
3613
3614 ENTER();
3615
3616 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Govind Singha471e5e2015-10-12 17:11:14 +05303617 ret = wlan_hdd_validate_context(hdd_ctx);
3618 if (ret != 0)
3619 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003620
3621 switch (sub_cmd) {
3622 case QCSAP_GET_STATS:
3623 hdd_wlan_get_stats(adapter, &(wrqu->data.length),
3624 extra, WE_MAX_STR_LEN);
3625 break;
Govind Singha471e5e2015-10-12 17:11:14 +05303626 case QCSAP_LIST_FW_PROFILE:
3627 hdd_wlan_list_fw_profile(&(wrqu->data.length),
3628 extra, WE_MAX_STR_LEN);
3629 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003630 }
3631
3632 EXIT();
Govind Singha471e5e2015-10-12 17:11:14 +05303633 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003634}
3635
3636static int iw_get_char_setnone(struct net_device *dev,
3637 struct iw_request_info *info,
3638 union iwreq_data *wrqu, char *extra)
3639{
3640 int ret;
3641
3642 cds_ssr_protect(__func__);
3643 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
3644 cds_ssr_unprotect(__func__);
3645
3646 return ret;
3647}
3648
3649static int wlan_hdd_set_force_acs_ch_range(struct net_device *dev,
3650 struct iw_request_info *info,
3651 union iwreq_data *wrqu, char *extra)
3652{
3653 hdd_adapter_t *adapter = (netdev_priv(dev));
3654 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3655 int *value = (int *)extra;
3656
Hanumantha Reddy Pothula3b8c0a52015-11-05 10:59:21 +05303657 if (!capable(CAP_NET_ADMIN)) {
3658 hddLog(LOGE, FL("permission check failed"));
3659 return -EPERM;
3660 }
3661
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003662 if (wlan_hdd_validate_operation_channel(adapter, value[0]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303663 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003664 wlan_hdd_validate_operation_channel(adapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303665 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003666 return -EINVAL;
3667 } else {
3668 hdd_ctx->config->force_sap_acs_st_ch = value[0];
3669 hdd_ctx->config->force_sap_acs_end_ch = value[1];
3670 }
3671
3672 return 0;
3673}
3674
3675static int iw_softap_set_force_acs_ch_range(struct net_device *dev,
3676 struct iw_request_info *info,
3677 union iwreq_data *wrqu, char *extra)
3678{
3679 int ret;
3680 cds_ssr_protect(__func__);
3681 ret = wlan_hdd_set_force_acs_ch_range(dev, info, wrqu, extra);
3682 cds_ssr_unprotect(__func__);
3683 return ret;
3684}
3685
3686static int __iw_softap_get_channel_list(struct net_device *dev,
3687 struct iw_request_info *info,
3688 union iwreq_data *wrqu, char *extra)
3689{
3690 uint32_t num_channels = 0;
3691 uint8_t i = 0;
3692 uint8_t bandStartChannel = RF_CHAN_1;
3693 uint8_t bandEndChannel = RF_CHAN_184;
3694 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3695 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3696 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
3697 eCsrBand curBand = eCSR_BAND_ALL;
3698 hdd_context_t *hdd_ctx;
3699 int ret;
3700
3701 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3702 ret = wlan_hdd_validate_context(hdd_ctx);
3703 if (0 != ret)
3704 return ret;
3705
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303706 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &curBand)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003707 hddLog(LOGE, FL("not able get the current frequency band"));
3708 return -EIO;
3709 }
3710 wrqu->data.length = sizeof(tChannelListInfo);
3711 ENTER();
3712
3713 if (eCSR_BAND_24 == curBand) {
3714 bandStartChannel = RF_CHAN_1;
3715 bandEndChannel = RF_CHAN_14;
3716 } else if (eCSR_BAND_5G == curBand) {
3717 bandStartChannel = RF_CHAN_36;
3718 bandEndChannel = RF_CHAN_184;
3719 }
3720
3721 hddLog(LOG1, FL("curBand = %d, StartChannel = %hu, EndChannel = %hu "),
3722 curBand, bandStartChannel, bandEndChannel);
3723
3724 for (i = bandStartChannel; i <= bandEndChannel; i++) {
Amar Singhal7a1726a2015-10-14 16:28:11 -07003725 if ((CHANNEL_STATE_ENABLE == CDS_CHANNEL_STATE(i)) ||
3726 (CHANNEL_STATE_DFS == CDS_CHANNEL_STATE(i))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003727 channel_list->channels[num_channels] =
Amar Singhal7a1726a2015-10-14 16:28:11 -07003728 CDS_CHANNEL_NUM(i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003729 num_channels++;
3730 }
3731 }
3732
3733 hddLog(LOG1, FL(" number of channels %d"), num_channels);
3734
3735 if (num_channels > IW_MAX_FREQUENCIES) {
3736 num_channels = IW_MAX_FREQUENCIES;
3737 }
3738
3739 channel_list->num_channels = num_channels;
3740 EXIT();
3741
3742 return 0;
3743}
3744
3745int iw_softap_get_channel_list(struct net_device *dev,
3746 struct iw_request_info *info,
3747 union iwreq_data *wrqu, char *extra)
3748{
3749 int ret;
3750
3751 cds_ssr_protect(__func__);
3752 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
3753 cds_ssr_unprotect(__func__);
3754
3755 return ret;
3756}
3757
3758static
3759int __iw_get_genie(struct net_device *dev,
3760 struct iw_request_info *info,
3761 union iwreq_data *wrqu, char *extra)
3762{
3763 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3764 hdd_context_t *hdd_ctx;
3765 int ret;
3766#ifndef WLAN_FEATURE_MBSSID
3767 v_CONTEXT_t cds_ctx;
3768#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303769 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003770 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
3771 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
3772
3773 ENTER();
3774
3775 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3776 ret = wlan_hdd_validate_context(hdd_ctx);
3777 if (0 != ret)
3778 return ret;
3779
3780#ifndef WLAN_FEATURE_MBSSID
3781 cds_ctx = hdd_ctx->pcds_context;
3782 if (NULL == cds_ctx) {
3783 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3784 "%s: vos context is not valid ", __func__);
3785 return -EINVAL;
3786 }
3787#endif
3788
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003789 /*
3790 * Actually retrieve the RSN IE from CSR.
3791 * (We previously sent it down in the CSR Roam Profile.)
3792 */
3793 status = wlan_sap_getstation_ie_information(
3794#ifdef WLAN_FEATURE_MBSSID
3795 WLAN_HDD_GET_SAP_CTX_PTR
3796 (pHostapdAdapter),
3797#else
3798 cds_ctx,
3799#endif
3800 &length, genIeBytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303801 if (status == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003802 length = CDF_MIN(length, DOT11F_IE_RSN_MAX_LEN);
3803 if (wrqu->data.length < length ||
3804 copy_to_user(wrqu->data.pointer, (void *)genIeBytes, length)) {
3805 hddLog(LOG1, FL("failed to copy data to user buffer"));
3806 return -EFAULT;
3807 }
3808 wrqu->data.length = length;
3809 hddLog(LOG1, FL(" RSN IE of %d bytes returned"),
3810 wrqu->data.length);
3811 } else {
3812 wrqu->data.length = 0;
3813 hddLog(LOG1, FL(" RSN IE failed to populate"));
3814 }
3815
3816 EXIT();
3817 return 0;
3818}
3819
3820static
3821int iw_get_genie(struct net_device *dev,
3822 struct iw_request_info *info,
3823 union iwreq_data *wrqu, char *extra)
3824{
3825 int ret;
3826
3827 cds_ssr_protect(__func__);
3828 ret = __iw_get_genie(dev, info, wrqu, extra);
3829 cds_ssr_unprotect(__func__);
3830
3831 return ret;
3832}
3833
3834static
3835int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3836 struct iw_request_info *info,
3837 union iwreq_data *wrqu, char *extra)
3838{
3839 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3840 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
3841 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3842 hdd_context_t *hdd_ctx;
3843 int ret;
3844
3845 ENTER();
3846
3847 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3848 ret = wlan_hdd_validate_context(hdd_ctx);
3849 if (0 != ret)
3850 return ret;
3851
3852 hddLog(LOG1, FL("get_WPSPBCProbeReqIEs ioctl"));
3853 memset((void *)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
3854
3855 WPSPBCProbeReqIEs.probeReqIELen =
3856 pHddApCtx->WPSPBCProbeReq.probeReqIELen;
3857 cdf_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
3858 pHddApCtx->WPSPBCProbeReq.probeReqIE,
3859 WPSPBCProbeReqIEs.probeReqIELen);
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003860 cdf_copy_macaddr(&WPSPBCProbeReqIEs.macaddr,
3861 &pHddApCtx->WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003862 if (copy_to_user(wrqu->data.pointer,
3863 (void *)&WPSPBCProbeReqIEs,
3864 sizeof(WPSPBCProbeReqIEs))) {
3865 hddLog(LOG1, FL("failed to copy data to user buffer"));
3866 return -EFAULT;
3867 }
3868 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003869 hdd_info("Macaddress : " MAC_ADDRESS_STR,
3870 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871 up(&pHddApCtx->semWpsPBCOverlapInd);
3872 EXIT();
3873 return 0;
3874}
3875
3876static
3877int iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3878 struct iw_request_info *info,
3879 union iwreq_data *wrqu, char *extra)
3880{
3881 int ret;
3882
3883 cds_ssr_protect(__func__);
3884 ret = __iw_get_wpspbc_probe_req_ies(dev, info, wrqu, extra);
3885 cds_ssr_unprotect(__func__);
3886
3887 return ret;
3888}
3889
3890/**
3891 * __iw_set_auth_hostap() -
3892 * This function sets the auth type received from the wpa_supplicant.
3893 *
3894 * @dev: pointer to the net device.
3895 * @info: pointer to the iw_request_info.
3896 * @wrqu: pointer to the iwreq_data.
3897 * @extra: pointer to the data.
3898 *
3899 * Return: 0 for success, non zero for failure
3900 */
3901static
3902int __iw_set_auth_hostap(struct net_device *dev, struct iw_request_info *info,
3903 union iwreq_data *wrqu, char *extra)
3904{
3905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3906 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3907 hdd_context_t *hdd_ctx;
3908 int ret;
3909
3910 ENTER();
3911
3912 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3913 ret = wlan_hdd_validate_context(hdd_ctx);
3914 if (0 != ret)
3915 return ret;
3916
3917 switch (wrqu->param.flags & IW_AUTH_INDEX) {
3918 case IW_AUTH_TKIP_COUNTERMEASURES:
3919 {
3920 if (wrqu->param.value) {
3921 hddLog(LOG2,
3922 "Counter Measure started %d", wrqu->param.value);
3923 pWextState->mTKIPCounterMeasures =
3924 TKIP_COUNTER_MEASURE_STARTED;
3925 } else {
3926 hddLog(LOG2,
3927 "Counter Measure stopped=%d", wrqu->param.value);
3928 pWextState->mTKIPCounterMeasures =
3929 TKIP_COUNTER_MEASURE_STOPED;
3930 }
3931
3932 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
3933 wrqu->param.
3934 value);
3935 }
3936 break;
3937
3938 default:
3939
3940 hddLog(LOGW, FL("called with unsupported auth type %d"),
3941 wrqu->param.flags & IW_AUTH_INDEX);
3942 break;
3943 }
3944
3945 EXIT();
3946 return 0;
3947}
3948
3949/**
3950 * iw_set_auth_hostap() - Wrapper function to protect __iw_set_auth_hostap
3951 * from the SSR.
3952 *
3953 * @dev - Pointer to the net device.
3954 * @info - Pointer to the iw_request_info.
3955 * @wrqu - Pointer to the iwreq_data.
3956 * @extra - Pointer to the data.
3957 *
3958 * Return: 0 for success, non zero for failure.
3959 */
3960static int
3961iw_set_auth_hostap(struct net_device *dev,
3962 struct iw_request_info *info,
3963 union iwreq_data *wrqu, char *extra)
3964{
3965 int ret;
3966
3967 cds_ssr_protect(__func__);
3968 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
3969 cds_ssr_unprotect(__func__);
3970
3971 return ret;
3972}
3973
3974/**
3975 * __iw_set_ap_encodeext() - set ap encode
3976 *
3977 * @dev - Pointer to the net device.
3978 * @info - Pointer to the iw_request_info.
3979 * @wrqu - Pointer to the iwreq_data.
3980 * @extra - Pointer to the data.
3981 *
3982 * Return: 0 for success, non zero for failure.
3983 */
3984static int __iw_set_ap_encodeext(struct net_device *dev,
3985 struct iw_request_info *info,
3986 union iwreq_data *wrqu, char *extra)
3987{
3988 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3989#ifndef WLAN_FEATURE_MBSSID
3990 v_CONTEXT_t cds_ctx;
3991#endif
3992 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3993 hdd_context_t *hdd_ctx;
3994 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303995 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003996 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
3997 int key_index;
3998 struct iw_point *encoding = &wrqu->encoding;
3999 tCsrRoamSetKey setKey;
4000 int i;
4001
4002 ENTER();
4003
4004 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4005 ret = wlan_hdd_validate_context(hdd_ctx);
4006 if (0 != ret)
4007 return ret;
4008
4009#ifndef WLAN_FEATURE_MBSSID
4010 cds_ctx = hdd_ctx->pcds_context;
4011 if (NULL == cds_ctx) {
4012 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4013 "%s: pVosContext is NULL", __func__);
4014 return -EINVAL;
4015 }
4016#endif
4017
4018 key_index = encoding->flags & IW_ENCODE_INDEX;
4019
4020 if (key_index > 0) {
4021 /*Convert from 1-based to 0-based keying */
4022 key_index--;
4023 }
4024 if (!ext->key_len)
4025 return ret;
4026
4027 cdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
4028
4029 setKey.keyId = key_index;
4030 setKey.keyLength = ext->key_len;
4031
4032 if (ext->key_len <= CSR_MAX_KEY_LEN) {
4033 cdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
4034 }
4035
4036 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4037 /*Key direction for group is RX only */
4038 setKey.keyDirection = eSIR_RX_ONLY;
4039 cdf_set_macaddr_broadcast(&setKey.peerMac);
4040 } else {
4041
4042 setKey.keyDirection = eSIR_TX_RX;
4043 cdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
4044 CDF_MAC_ADDR_SIZE);
4045 }
4046 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
4047 setKey.keyDirection = eSIR_TX_DEFAULT;
4048 cdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
4049 CDF_MAC_ADDR_SIZE);
4050 }
4051
4052 /*For supplicant pae role is zero */
4053 setKey.paeRole = 0;
4054
4055 switch (ext->alg) {
4056 case IW_ENCODE_ALG_NONE:
4057 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4058 break;
4059
4060 case IW_ENCODE_ALG_WEP:
4061 setKey.encType =
4062 (ext->key_len ==
4063 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4064 pHddApCtx->uPrivacy = 1;
4065 hddLog(LOG1, FL("uPrivacy=%d"), pHddApCtx->uPrivacy);
4066 break;
4067
4068 case IW_ENCODE_ALG_TKIP:
4069 {
4070 uint8_t *pKey = &setKey.Key[0];
4071
4072 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4073
4074 cdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
4075
4076 /*Supplicant sends the 32bytes key in this order
4077
4078 |--------------|----------|----------|
4079 | Tk1 |TX-MIC | RX Mic |
4080 |||--------------|----------|----------|
4081 <---16bytes---><--8bytes--><--8bytes-->
4082
4083 */
4084 /*Sme expects the 32 bytes key to be in the below order
4085
4086 |--------------|----------|----------|
4087 | Tk1 |RX-MIC | TX Mic |
4088 |||--------------|----------|----------|
4089 <---16bytes---><--8bytes--><--8bytes-->
4090 */
4091 /* Copy the Temporal Key 1 (TK1) */
4092 cdf_mem_copy(pKey, ext->key, 16);
4093
4094 /*Copy the rx mic first */
4095 cdf_mem_copy(&pKey[16], &ext->key[24], 8);
4096
4097 /*Copy the tx mic */
4098 cdf_mem_copy(&pKey[24], &ext->key[16], 8);
4099
4100 }
4101 break;
4102
4103 case IW_ENCODE_ALG_CCMP:
4104 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4105 break;
4106
4107 default:
4108 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4109 break;
4110 }
4111
4112 hddLog(LOG1, FL(":EncryptionType:%d key_len:%d, KeyId:%d"),
4113 setKey.encType, setKey.keyLength, setKey.keyId);
4114 for (i = 0; i < ext->key_len; i++)
4115 hddLog(LOG1, "%02x", setKey.Key[i]);
4116
4117#ifdef WLAN_FEATURE_MBSSID
4118 vstatus =
4119 wlansap_set_key_sta(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
4120 &setKey);
4121#else
4122 vstatus = wlansap_set_key_sta(cds_ctx, &setKey);
4123#endif
4124
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304125 if (vstatus != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004126 hddLog(LOGE, FL("wlansap_set_key_sta failed, status= %d"),
4127 vstatus);
4128 ret = -EINVAL;
4129 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304130 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004131 return ret;
4132}
4133
4134/**
4135 * iw_set_ap_encodeext() - Wrapper function to protect __iw_set_ap_encodeext
4136 * from the SSR.
4137 *
4138 * @dev - Pointer to the net device.
4139 * @info - Pointer to the iw_request_info.
4140 * @wrqu - Pointer to the iwreq_data.
4141 * @extra - Pointer to the data.
4142 *
4143 * Return: 0 for success, non zero for failure.
4144 */
4145static int iw_set_ap_encodeext(struct net_device *dev,
4146 struct iw_request_info *info,
4147 union iwreq_data *wrqu, char *extra)
4148{
4149 int ret;
4150
4151 cds_ssr_protect(__func__);
4152 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
4153 cds_ssr_unprotect(__func__);
4154
4155 return ret;
4156}
4157
4158/**
4159 * __iw_set_ap_mlme() - set ap mlme
4160 * @dev: pointer to net_device
4161 * @info: pointer to iw_request_info
4162 * @wrqu; pointer to iwreq_data
4163 * @extra: extra
4164 *
4165 * Return; 0 on success, error number otherwise
4166 */
4167static int __iw_set_ap_mlme(struct net_device *dev,
4168 struct iw_request_info *info,
4169 union iwreq_data *wrqu, char *extra)
4170{
4171 return 0;
4172}
4173
4174/**
4175 * iw_set_ap_mlme() - SSR wrapper for __iw_set_ap_mlme
4176 * @dev: pointer to net_device
4177 * @info: pointer to iw_request_info
4178 * @wrqu; pointer to iwreq_data
4179 * @extra: extra
4180 *
4181 * Return; 0 on success, error number otherwise
4182 */
4183static int iw_set_ap_mlme(struct net_device *dev,
4184 struct iw_request_info *info,
4185 union iwreq_data *wrqu,
4186 char *extra)
4187{
4188 int ret;
4189
4190 cds_ssr_protect(__func__);
4191 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
4192 cds_ssr_unprotect(__func__);
4193
4194 return ret;
4195}
4196
4197/**
4198 * __iw_get_ap_rts_threshold() - get ap rts threshold
4199 * @dev - Pointer to the net device.
4200 * @info - Pointer to the iw_request_info.
4201 * @wrqu - Pointer to the iwreq_data.
4202 * @extra - Pointer to the data.
4203 *
4204 * Return: 0 for success, non zero for failure.
4205 */
4206static int __iw_get_ap_rts_threshold(struct net_device *dev,
4207 struct iw_request_info *info,
4208 union iwreq_data *wrqu, char *extra) {
4209
4210 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4211 int ret;
4212 hdd_context_t *hdd_ctx;
4213
4214 ENTER();
4215
4216 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4217 ret = wlan_hdd_validate_context(hdd_ctx);
4218 if (0 != ret)
4219 return ret;
4220 ret = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
4221
4222 return ret;
4223}
4224
4225/**
4226 * iw_get_ap_rts_threshold() - Wrapper function to protect
4227 * __iw_get_ap_rts_threshold from the SSR.
4228 * @dev - Pointer to the net device.
4229 * @info - Pointer to the iw_request_info.
4230 * @wrqu - Pointer to the iwreq_data.
4231 * @extra - Pointer to the data.
4232 *
4233 * Return: 0 for success, non zero for failure.
4234 */
4235static int iw_get_ap_rts_threshold(struct net_device *dev,
4236 struct iw_request_info *info,
4237 union iwreq_data *wrqu, char *extra)
4238{
4239 int ret;
4240
4241 cds_ssr_protect(__func__);
4242 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
4243 cds_ssr_unprotect(__func__);
4244
4245 return ret;
4246}
4247
4248/**
4249 * __iw_get_ap_frag_threshold() - get ap fragmentation threshold
4250 * @dev - Pointer to the net device.
4251 * @info - Pointer to the iw_request_info.
4252 * @wrqu - Pointer to the iwreq_data.
4253 * @extra - Pointer to the data.
4254 *
4255 * Return: 0 for success, non zero for failure.
4256 */
4257static int __iw_get_ap_frag_threshold(struct net_device *dev,
4258 struct iw_request_info *info,
4259 union iwreq_data *wrqu, char *extra) {
4260
4261 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4262 hdd_context_t *hdd_ctx;
4263 int ret = 0;
4264
4265 ENTER();
4266
4267 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4268 ret = wlan_hdd_validate_context(hdd_ctx);
4269 if (0 != ret)
4270 return ret;
4271
4272 ret = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
4273
4274 return ret;
4275}
4276
4277/**
4278 * iw_get_ap_frag_threshold() - Wrapper function to protect
4279 * __iw_get_ap_frag_threshold from the SSR.
4280 * @dev - Pointer to the net device.
4281 * @info - Pointer to the iw_request_info.
4282 * @wrqu - Pointer to the iwreq_data.
4283 * @extra - Pointer to the data.
4284 *
4285 * Return: 0 for success, non zero for failure.
4286 */
4287static int iw_get_ap_frag_threshold(struct net_device *dev,
4288 struct iw_request_info *info,
4289 union iwreq_data *wrqu, char *extra)
4290{
4291 int ret;
4292
4293 cds_ssr_protect(__func__);
4294 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
4295 cds_ssr_unprotect(__func__);
4296
4297 return ret;
4298}
4299
4300/**
4301 * __iw_get_ap_freq() - get ap frequency
4302 * @dev - Pointer to the net device.
4303 * @info - Pointer to the iw_request_info.
4304 * @wrqu - Pointer to the iwreq_data.
4305 * @extra - Pointer to the data.
4306 *
4307 * Return: 0 for success, non zero for failure.
4308 */
4309static int __iw_get_ap_freq(struct net_device *dev,
4310 struct iw_request_info *info, struct iw_freq *fwrq,
4311 char *extra) {
4312 uint32_t status = false, channel = 0, freq = 0;
4313 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4314 hdd_context_t *hdd_ctx;
4315 tHalHandle hHal;
4316 hdd_hostapd_state_t *pHostapdState;
4317 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4318 int ret;
4319
4320 ENTER();
4321
4322 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4323 ret = wlan_hdd_validate_context(hdd_ctx);
4324 if (0 != ret)
4325 return ret;
4326
4327 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4328 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
4329
4330 if (pHostapdState->bssState == BSS_STOP) {
4331 if (sme_cfg_get_int(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304332 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004333 return -EIO;
4334 } else {
4335 status = hdd_wlan_get_freq(channel, &freq);
4336 if (true == status) {
4337 /* Set Exponent parameter as 6 (MHZ) in struct
4338 * iw_freq * iwlist & iwconfig command
4339 * shows frequency into proper
4340 * format (2.412 GHz instead of 246.2 MHz)
4341 */
4342 fwrq->m = freq;
4343 fwrq->e = MHZ;
4344 }
4345 }
4346 } else {
4347 channel = pHddApCtx->operatingChannel;
4348 status = hdd_wlan_get_freq(channel, &freq);
4349 if (true == status) {
4350 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
4351 * iwlist & iwconfig command shows frequency into proper
4352 * format (2.412 GHz instead of 246.2 MHz)*/
4353 fwrq->m = freq;
4354 fwrq->e = MHZ;
4355 }
4356 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304357 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004358 return 0;
4359}
4360
4361/**
4362 * iw_get_ap_freq() - Wrapper function to protect
4363 * __iw_get_ap_freq from the SSR.
4364 * @dev - Pointer to the net device.
4365 * @info - Pointer to the iw_request_info.
4366 * @wrqu - Pointer to the iwreq_data.
4367 * @extra - Pointer to the data.
4368 *
4369 * Return: 0 for success, non zero for failure.
4370 */
4371static int iw_get_ap_freq(struct net_device *dev,
4372 struct iw_request_info *info,
4373 struct iw_freq *wrqu, char *extra)
4374{
4375 int ret;
4376
4377 cds_ssr_protect(__func__);
4378 ret = __iw_get_ap_freq(dev, info, wrqu, extra);
4379 cds_ssr_unprotect(__func__);
4380
4381 return ret;
4382}
4383
4384/**
4385 * __iw_get_mode() - get mode
4386 * @dev - Pointer to the net device.
4387 * @info - Pointer to the iw_request_info.
4388 * @wrqu - Pointer to the iwreq_data.
4389 * @extra - Pointer to the data.
4390 *
4391 * Return: 0 for success, non zero for failure.
4392 */
4393static int __iw_get_mode(struct net_device *dev,
4394 struct iw_request_info *info,
4395 union iwreq_data *wrqu, char *extra) {
4396
4397 hdd_adapter_t *adapter;
4398 hdd_context_t *hdd_ctx;
4399 int ret;
4400
4401 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4402 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4403 ret = wlan_hdd_validate_context(hdd_ctx);
4404 if (0 != ret)
4405 return ret;
4406
4407 wrqu->mode = IW_MODE_MASTER;
4408
4409 return ret;
4410}
4411
4412/**
4413 * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR.
4414 * @dev - Pointer to the net device.
4415 * @info - Pointer to the iw_request_info.
4416 * @wrqu - Pointer to the iwreq_data.
4417 * @extra - Pointer to the data.
4418 *
4419 * Return: 0 for success, non zero for failure.
4420 */
4421static int iw_get_mode(struct net_device *dev,
4422 struct iw_request_info *info,
4423 union iwreq_data *wrqu, char *extra)
4424{
4425 int ret;
4426
4427 cds_ssr_protect(__func__);
4428 ret = __iw_get_mode(dev, info, wrqu, extra);
4429 cds_ssr_unprotect(__func__);
4430
4431 return ret;
4432}
4433
4434static int
4435__iw_softap_setwpsie(struct net_device *dev,
4436 struct iw_request_info *info,
4437 union iwreq_data *wrqu, char *extra)
4438{
4439 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4440#ifndef WLAN_FEATURE_MBSSID
4441 v_CONTEXT_t cds_ctx;
4442#endif
4443 hdd_hostapd_state_t *pHostapdState;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304444 QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004445 uint8_t *wps_genie;
4446 uint8_t *fwps_genie;
4447 uint8_t *pos;
4448 tpSap_WPSIE pSap_WPSIe;
4449 uint8_t WPSIeType;
4450 uint16_t length;
4451 struct iw_point s_priv_data;
4452 hdd_context_t *hdd_ctx;
4453 int ret;
4454
4455 ENTER();
4456
Mukul Sharmaa42b0622015-11-02 19:57:31 +05304457 if (!capable(CAP_NET_ADMIN)) {
4458 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4459 FL("permission check failed"));
4460 return -EPERM;
4461 }
4462
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004463 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4464 ret = wlan_hdd_validate_context(hdd_ctx);
4465 if (0 != ret)
4466 return ret;
4467
4468#ifndef WLAN_FEATURE_MBSSID
4469 cds_ctx = hdd_ctx->pcds_context;
4470 if (NULL == cds_ctx) {
4471 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4472 "%s: HDD context is not valid ", __func__);
4473 return -EINVAL;
4474 }
4475#endif
4476
4477 /* helper function to get iwreq_data with compat handling. */
4478 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
4479 return -EINVAL;
4480 }
4481
4482 if ((NULL == s_priv_data.pointer) ||
4483 (s_priv_data.length < QCSAP_MAX_WSC_IE)) {
4484 return -EINVAL;
4485 }
4486
4487 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
4488 s_priv_data.length);
4489
4490 if (NULL == wps_genie) {
4491 hddLog(LOG1, FL("failed to alloc mem and copy data"));
4492 return -EFAULT;
4493 }
4494
4495 fwps_genie = wps_genie;
4496
4497 pSap_WPSIe = cdf_mem_malloc(sizeof(tSap_WPSIE));
4498 if (NULL == pSap_WPSIe) {
4499 hddLog(LOGE, "CDF unable to allocate memory");
4500 kfree(fwps_genie);
4501 return -ENOMEM;
4502 }
4503 cdf_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
4504
4505 hddLog(LOG1, FL("WPS IE type[0x%X] IE[0x%X], LEN[%d]"),
4506 wps_genie[0], wps_genie[1], wps_genie[2]);
4507 WPSIeType = wps_genie[0];
4508 if (wps_genie[0] == eQC_WPS_BEACON_IE) {
4509 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
4510 wps_genie = wps_genie + 1;
4511 switch (wps_genie[0]) {
4512 case DOT11F_EID_WPA:
4513 if (wps_genie[1] < 2 + 4) {
4514 cdf_mem_free(pSap_WPSIe);
4515 kfree(fwps_genie);
4516 return -EINVAL;
4517 } else if (memcmp(&wps_genie[2],
4518 "\x00\x50\xf2\x04", 4) == 0) {
4519 hddLog(LOG1, FL("Set WPS BEACON IE(len %d)"),
4520 wps_genie[1] + 2);
4521 pos = &wps_genie[6];
4522 while (((size_t) pos -
4523 (size_t) &wps_genie[6]) <
4524 (wps_genie[1] - 4)) {
4525 switch ((uint16_t) (*pos << 8) |
4526 *(pos + 1)) {
4527 case HDD_WPS_ELEM_VERSION:
4528 pos += 4;
4529 pSap_WPSIe->sapwpsie.
4530 sapWPSBeaconIE.Version =
4531 *pos;
4532 hddLog(LOG1, "WPS version %d",
4533 pSap_WPSIe->sapwpsie.
4534 sapWPSBeaconIE.Version);
4535 pSap_WPSIe->sapwpsie.
4536 sapWPSBeaconIE.
4537 FieldPresent |=
4538 WPS_BEACON_VER_PRESENT;
4539 pos += 1;
4540 break;
4541
4542 case HDD_WPS_ELEM_WPS_STATE:
4543 pos += 4;
4544 pSap_WPSIe->sapwpsie.
4545 sapWPSBeaconIE.wpsState =
4546 *pos;
4547 hddLog(LOG1, "WPS State %d",
4548 pSap_WPSIe->sapwpsie.
4549 sapWPSBeaconIE.wpsState);
4550 pSap_WPSIe->sapwpsie.
4551 sapWPSBeaconIE.
4552 FieldPresent |=
4553 WPS_BEACON_STATE_PRESENT;
4554 pos += 1;
4555 break;
4556 case HDD_WPS_ELEM_APSETUPLOCK:
4557 pos += 4;
4558 pSap_WPSIe->sapwpsie.
4559 sapWPSBeaconIE.
4560 APSetupLocked = *pos;
4561 hddLog(LOG1, "AP setup lock %d",
4562 pSap_WPSIe->sapwpsie.
4563 sapWPSBeaconIE.
4564 APSetupLocked);
4565 pSap_WPSIe->sapwpsie.
4566 sapWPSBeaconIE.
4567 FieldPresent |=
4568 WPS_BEACON_APSETUPLOCK_PRESENT;
4569 pos += 1;
4570 break;
4571 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4572 pos += 4;
4573 pSap_WPSIe->sapwpsie.
4574 sapWPSBeaconIE.
4575 SelectedRegistra = *pos;
4576 hddLog(LOG1,
4577 "Selected Registra %d",
4578 pSap_WPSIe->sapwpsie.
4579 sapWPSBeaconIE.
4580 SelectedRegistra);
4581 pSap_WPSIe->sapwpsie.
4582 sapWPSBeaconIE.
4583 FieldPresent |=
4584 WPS_BEACON_SELECTEDREGISTRA_PRESENT;
4585 pos += 1;
4586 break;
4587 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4588 pos += 4;
4589 pSap_WPSIe->sapwpsie.
4590 sapWPSBeaconIE.
4591 DevicePasswordID =
4592 (*pos << 8) | *(pos + 1);
4593 hddLog(LOG1, "Password ID: %x",
4594 pSap_WPSIe->sapwpsie.
4595 sapWPSBeaconIE.
4596 DevicePasswordID);
4597 pSap_WPSIe->sapwpsie.
4598 sapWPSBeaconIE.
4599 FieldPresent |=
4600 WPS_BEACON_DEVICEPASSWORDID_PRESENT;
4601 pos += 2;
4602 break;
4603 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4604 pos +=
4605 4;
4606 pSap_WPSIe->sapwpsie.
4607 sapWPSBeaconIE.
4608 SelectedRegistraCfgMethod =
4609 (*pos << 8) | *(pos + 1);
4610 hddLog(LOG1,
4611 "Select Registra Config Methods: %x",
4612 pSap_WPSIe->sapwpsie.
4613 sapWPSBeaconIE.
4614 SelectedRegistraCfgMethod);
4615 pSap_WPSIe->sapwpsie.
4616 sapWPSBeaconIE.
4617 FieldPresent |=
4618 WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
4619 pos += 2;
4620 break;
4621
4622 case HDD_WPS_ELEM_UUID_E:
4623 pos += 2;
4624 length = *pos << 8 | *(pos + 1);
4625 pos += 2;
4626 cdf_mem_copy(pSap_WPSIe->
4627 sapwpsie.
4628 sapWPSBeaconIE.
4629 UUID_E, pos,
4630 length);
4631 pSap_WPSIe->sapwpsie.
4632 sapWPSBeaconIE.
4633 FieldPresent |=
4634 WPS_BEACON_UUIDE_PRESENT;
4635 pos += length;
4636 break;
4637 case HDD_WPS_ELEM_RF_BANDS:
4638 pos += 4;
4639 pSap_WPSIe->sapwpsie.
4640 sapWPSBeaconIE.RFBand =
4641 *pos;
4642 hddLog(LOG1, "RF band: %d",
4643 pSap_WPSIe->sapwpsie.
4644 sapWPSBeaconIE.RFBand);
4645 pSap_WPSIe->sapwpsie.
4646 sapWPSBeaconIE.
4647 FieldPresent |=
4648 WPS_BEACON_RF_BANDS_PRESENT;
4649 pos += 1;
4650 break;
4651
4652 default:
4653 hddLog(LOGW,
4654 "UNKNOWN TLV in WPS IE(%x)",
4655 (*pos << 8 |
4656 *(pos + 1)));
4657 cdf_mem_free(pSap_WPSIe);
4658 kfree(fwps_genie);
4659 return -EINVAL;
4660 }
4661 }
4662 } else {
4663 hddLog(LOGE, FL("WPS IE Mismatch %X"),
4664 wps_genie[0]);
4665 }
4666 break;
4667
4668 default:
4669 hddLog(LOGE, FL("Set UNKNOWN IE %X"), wps_genie[0]);
4670 cdf_mem_free(pSap_WPSIe);
4671 kfree(fwps_genie);
4672 return 0;
4673 }
4674 } else if (wps_genie[0] == eQC_WPS_PROBE_RSP_IE) {
4675 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
4676 wps_genie = wps_genie + 1;
4677 switch (wps_genie[0]) {
4678 case DOT11F_EID_WPA:
4679 if (wps_genie[1] < 2 + 4) {
4680 cdf_mem_free(pSap_WPSIe);
4681 kfree(fwps_genie);
4682 return -EINVAL;
4683 } else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4)
4684 == 0) {
4685 hddLog(LOG1, FL("Set WPS PROBE RSP IE(len %d)"),
4686 wps_genie[1] + 2);
4687 pos = &wps_genie[6];
4688 while (((size_t) pos -
4689 (size_t) &wps_genie[6]) <
4690 (wps_genie[1] - 4)) {
4691 switch ((uint16_t) (*pos << 8) |
4692 *(pos + 1)) {
4693 case HDD_WPS_ELEM_VERSION:
4694 pos += 4;
4695 pSap_WPSIe->sapwpsie.
4696 sapWPSProbeRspIE.Version =
4697 *pos;
4698 hddLog(LOG1, "WPS version %d",
4699 pSap_WPSIe->sapwpsie.
4700 sapWPSProbeRspIE.
4701 Version);
4702 pSap_WPSIe->sapwpsie.
4703 sapWPSProbeRspIE.
4704 FieldPresent |=
4705 WPS_PROBRSP_VER_PRESENT;
4706 pos += 1;
4707 break;
4708
4709 case HDD_WPS_ELEM_WPS_STATE:
4710 pos += 4;
4711 pSap_WPSIe->sapwpsie.
4712 sapWPSProbeRspIE.wpsState =
4713 *pos;
4714 hddLog(LOG1, "WPS State %d",
4715 pSap_WPSIe->sapwpsie.
4716 sapWPSProbeRspIE.
4717 wpsState);
4718 pSap_WPSIe->sapwpsie.
4719 sapWPSProbeRspIE.
4720 FieldPresent |=
4721 WPS_PROBRSP_STATE_PRESENT;
4722 pos += 1;
4723 break;
4724 case HDD_WPS_ELEM_APSETUPLOCK:
4725 pos += 4;
4726 pSap_WPSIe->sapwpsie.
4727 sapWPSProbeRspIE.
4728 APSetupLocked = *pos;
4729 hddLog(LOG1, "AP setup lock %d",
4730 pSap_WPSIe->sapwpsie.
4731 sapWPSProbeRspIE.
4732 APSetupLocked);
4733 pSap_WPSIe->sapwpsie.
4734 sapWPSProbeRspIE.
4735 FieldPresent |=
4736 WPS_PROBRSP_APSETUPLOCK_PRESENT;
4737 pos += 1;
4738 break;
4739 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4740 pos += 4;
4741 pSap_WPSIe->sapwpsie.
4742 sapWPSProbeRspIE.
4743 SelectedRegistra = *pos;
4744 hddLog(LOG1,
4745 "Selected Registra %d",
4746 pSap_WPSIe->sapwpsie.
4747 sapWPSProbeRspIE.
4748 SelectedRegistra);
4749 pSap_WPSIe->sapwpsie.
4750 sapWPSProbeRspIE.
4751 FieldPresent |=
4752 WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
4753 pos += 1;
4754 break;
4755 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4756 pos += 4;
4757 pSap_WPSIe->sapwpsie.
4758 sapWPSProbeRspIE.
4759 DevicePasswordID =
4760 (*pos << 8) | *(pos + 1);
4761 hddLog(LOG1, "Password ID: %d",
4762 pSap_WPSIe->sapwpsie.
4763 sapWPSProbeRspIE.
4764 DevicePasswordID);
4765 pSap_WPSIe->sapwpsie.
4766 sapWPSProbeRspIE.
4767 FieldPresent |=
4768 WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
4769 pos += 2;
4770 break;
4771 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4772 pos +=
4773 4;
4774 pSap_WPSIe->sapwpsie.
4775 sapWPSProbeRspIE.
4776 SelectedRegistraCfgMethod =
4777 (*pos << 8) | *(pos + 1);
4778 hddLog(LOG1,
4779 "Select Registra Config Methods: %x",
4780 pSap_WPSIe->sapwpsie.
4781 sapWPSProbeRspIE.
4782 SelectedRegistraCfgMethod);
4783 pSap_WPSIe->sapwpsie.
4784 sapWPSProbeRspIE.
4785 FieldPresent |=
4786 WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
4787 pos += 2;
4788 break;
4789 case HDD_WPS_ELEM_RSP_TYPE:
4790 pos += 4;
4791 pSap_WPSIe->sapwpsie.
4792 sapWPSProbeRspIE.
4793 ResponseType = *pos;
4794 hddLog(LOG1,
4795 "Config Methods: %d",
4796 pSap_WPSIe->sapwpsie.
4797 sapWPSProbeRspIE.
4798 ResponseType);
4799 pSap_WPSIe->sapwpsie.
4800 sapWPSProbeRspIE.
4801 FieldPresent |=
4802 WPS_PROBRSP_RESPONSETYPE_PRESENT;
4803 pos += 1;
4804 break;
4805 case HDD_WPS_ELEM_UUID_E:
4806 pos += 2;
4807 length = *pos << 8 | *(pos + 1);
4808 pos += 2;
4809 cdf_mem_copy(pSap_WPSIe->
4810 sapwpsie.
4811 sapWPSProbeRspIE.
4812 UUID_E, pos,
4813 length);
4814 pSap_WPSIe->sapwpsie.
4815 sapWPSProbeRspIE.
4816 FieldPresent |=
4817 WPS_PROBRSP_UUIDE_PRESENT;
4818 pos += length;
4819 break;
4820
4821 case HDD_WPS_ELEM_MANUFACTURER:
4822 pos += 2;
4823 length = *pos << 8 | *(pos + 1);
4824 pos += 2;
4825 pSap_WPSIe->sapwpsie.
4826 sapWPSProbeRspIE.
4827 Manufacture.num_name =
4828 length;
4829 cdf_mem_copy(pSap_WPSIe->
4830 sapwpsie.
4831 sapWPSProbeRspIE.
4832 Manufacture.name,
4833 pos, length);
4834 pSap_WPSIe->sapwpsie.
4835 sapWPSProbeRspIE.
4836 FieldPresent |=
4837 WPS_PROBRSP_MANUFACTURE_PRESENT;
4838 pos += length;
4839 break;
4840
4841 case HDD_WPS_ELEM_MODEL_NAME:
4842 pos += 2;
4843 length = *pos << 8 | *(pos + 1);
4844 pos += 2;
4845 pSap_WPSIe->sapwpsie.
4846 sapWPSProbeRspIE.ModelName.
4847 num_text = length;
4848 cdf_mem_copy(pSap_WPSIe->
4849 sapwpsie.
4850 sapWPSProbeRspIE.
4851 ModelName.text,
4852 pos, length);
4853 pSap_WPSIe->sapwpsie.
4854 sapWPSProbeRspIE.
4855 FieldPresent |=
4856 WPS_PROBRSP_MODELNAME_PRESENT;
4857 pos += length;
4858 break;
4859 case HDD_WPS_ELEM_MODEL_NUM:
4860 pos += 2;
4861 length = *pos << 8 | *(pos + 1);
4862 pos += 2;
4863 pSap_WPSIe->sapwpsie.
4864 sapWPSProbeRspIE.
4865 ModelNumber.num_text =
4866 length;
4867 cdf_mem_copy(pSap_WPSIe->
4868 sapwpsie.
4869 sapWPSProbeRspIE.
4870 ModelNumber.text,
4871 pos, length);
4872 pSap_WPSIe->sapwpsie.
4873 sapWPSProbeRspIE.
4874 FieldPresent |=
4875 WPS_PROBRSP_MODELNUMBER_PRESENT;
4876 pos += length;
4877 break;
4878 case HDD_WPS_ELEM_SERIAL_NUM:
4879 pos += 2;
4880 length = *pos << 8 | *(pos + 1);
4881 pos += 2;
4882 pSap_WPSIe->sapwpsie.
4883 sapWPSProbeRspIE.
4884 SerialNumber.num_text =
4885 length;
4886 cdf_mem_copy(pSap_WPSIe->
4887 sapwpsie.
4888 sapWPSProbeRspIE.
4889 SerialNumber.text,
4890 pos, length);
4891 pSap_WPSIe->sapwpsie.
4892 sapWPSProbeRspIE.
4893 FieldPresent |=
4894 WPS_PROBRSP_SERIALNUMBER_PRESENT;
4895 pos += length;
4896 break;
4897 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
4898 pos += 4;
4899 pSap_WPSIe->sapwpsie.
4900 sapWPSProbeRspIE.
4901 PrimaryDeviceCategory =
4902 (*pos << 8 | *(pos + 1));
4903 hddLog(LOG1,
4904 "primary dev category: %d",
4905 pSap_WPSIe->sapwpsie.
4906 sapWPSProbeRspIE.
4907 PrimaryDeviceCategory);
4908 pos += 2;
4909
4910 cdf_mem_copy(pSap_WPSIe->
4911 sapwpsie.
4912 sapWPSProbeRspIE.
4913 PrimaryDeviceOUI,
4914 pos,
4915 HDD_WPS_DEVICE_OUI_LEN);
4916 hddLog(LOG1,
4917 "primary dev oui: %02x, %02x, %02x, %02x",
4918 pos[0], pos[1], pos[2],
4919 pos[3]);
4920 pos += 4;
4921 pSap_WPSIe->sapwpsie.
4922 sapWPSProbeRspIE.
4923 DeviceSubCategory =
4924 (*pos << 8 | *(pos + 1));
4925 hddLog(LOG1,
4926 "primary dev sub category: %d",
4927 pSap_WPSIe->sapwpsie.
4928 sapWPSProbeRspIE.
4929 DeviceSubCategory);
4930 pos += 2;
4931 pSap_WPSIe->sapwpsie.
4932 sapWPSProbeRspIE.
4933 FieldPresent |=
4934 WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
4935 break;
4936 case HDD_WPS_ELEM_DEVICE_NAME:
4937 pos += 2;
4938 length = *pos << 8 | *(pos + 1);
4939 pos += 2;
4940 pSap_WPSIe->sapwpsie.
4941 sapWPSProbeRspIE.DeviceName.
4942 num_text = length;
4943 cdf_mem_copy(pSap_WPSIe->
4944 sapwpsie.
4945 sapWPSProbeRspIE.
4946 DeviceName.text,
4947 pos, length);
4948 pos += length;
4949 pSap_WPSIe->sapwpsie.
4950 sapWPSProbeRspIE.
4951 FieldPresent |=
4952 WPS_PROBRSP_DEVICENAME_PRESENT;
4953 break;
4954 case HDD_WPS_ELEM_CONFIG_METHODS:
4955 pos += 4;
4956 pSap_WPSIe->sapwpsie.
4957 sapWPSProbeRspIE.
4958 ConfigMethod =
4959 (*pos << 8) | *(pos + 1);
4960 hddLog(LOG1,
4961 "Config Methods: %d",
4962 pSap_WPSIe->sapwpsie.
4963 sapWPSProbeRspIE.
4964 SelectedRegistraCfgMethod);
4965 pos += 2;
4966 pSap_WPSIe->sapwpsie.
4967 sapWPSProbeRspIE.
4968 FieldPresent |=
4969 WPS_PROBRSP_CONFIGMETHODS_PRESENT;
4970 break;
4971
4972 case HDD_WPS_ELEM_RF_BANDS:
4973 pos += 4;
4974 pSap_WPSIe->sapwpsie.
4975 sapWPSProbeRspIE.RFBand =
4976 *pos;
4977 hddLog(LOG1, "RF band: %d",
4978 pSap_WPSIe->sapwpsie.
4979 sapWPSProbeRspIE.RFBand);
4980 pos += 1;
4981 pSap_WPSIe->sapwpsie.
4982 sapWPSProbeRspIE.
4983 FieldPresent |=
4984 WPS_PROBRSP_RF_BANDS_PRESENT;
4985 break;
4986 } /* switch */
4987 }
4988 } else {
4989 hddLog(LOGE,
4990 FL("WPS IE Mismatch %X"), wps_genie[0]);
4991 }
4992
4993 } /* switch */
4994 }
4995#ifdef WLAN_FEATURE_MBSSID
4996 cdf_ret_status =
4997 wlansap_set_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
4998 pSap_WPSIe);
4999#else
5000 cdf_ret_status = wlansap_set_wps_ie(p_cds_context, pSap_WPSIe);
5001#endif
5002 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5003 if (pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE) {
5004#ifdef WLAN_FEATURE_MBSSID
5005 wlansap_update_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
5006#else
5007 wlansap_update_wps_ie(p_cds_context);
5008#endif
5009 }
5010
5011 cdf_mem_free(pSap_WPSIe);
5012 kfree(fwps_genie);
5013 EXIT();
5014 return cdf_ret_status;
5015}
5016
5017static int iw_softap_setwpsie(struct net_device *dev,
5018 struct iw_request_info *info,
5019 union iwreq_data *wrqu,
5020 char *extra)
5021{
5022 int ret;
5023
5024 cds_ssr_protect(__func__);
5025 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
5026 cds_ssr_unprotect(__func__);
5027
5028 return ret;
5029}
5030
5031static int
5032__iw_softap_stopbss(struct net_device *dev,
5033 struct iw_request_info *info,
5034 union iwreq_data *wrqu, char *extra)
5035{
5036 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305037 QDF_STATUS status = QDF_STATUS_SUCCESS;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305038 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005039 hdd_context_t *hdd_ctx;
5040
5041 ENTER();
5042
5043 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5044 status = wlan_hdd_validate_context(hdd_ctx);
5045 if (0 != status)
5046 return status;
5047
5048 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
5049 hdd_hostapd_state_t *pHostapdState =
5050 WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5051
Anurag Chouhance0dc992016-02-16 18:18:03 +05305052 qdf_event_reset(&pHostapdState->cdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005053#ifdef WLAN_FEATURE_MBSSID
5054 status =
5055 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
5056#else
5057 status =
5058 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
5059 pcds_context);
5060#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305061 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05305062 qdf_status =
5063 qdf_wait_single_event(&pHostapdState->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005064 cdf_stop_bss_event,
5065 10000);
5066
Anurag Chouhance0dc992016-02-16 18:18:03 +05305067 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005068 hddLog(LOGE,
5069 FL("wait for single_event failed!!"));
5070 CDF_ASSERT(0);
5071 }
5072 }
5073 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08005074 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005075 pHostapdAdapter->sessionId);
5076 }
5077 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305078 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005079}
5080
5081static int iw_softap_stopbss(struct net_device *dev,
5082 struct iw_request_info *info,
5083 union iwreq_data *wrqu,
5084 char *extra)
5085{
5086 int ret;
5087
5088 cds_ssr_protect(__func__);
5089 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
5090 cds_ssr_unprotect(__func__);
5091
5092 return ret;
5093}
5094
5095static int
5096__iw_softap_version(struct net_device *dev,
5097 struct iw_request_info *info,
5098 union iwreq_data *wrqu, char *extra)
5099{
5100 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5101 hdd_context_t *hdd_ctx;
5102 int ret;
5103
5104 ENTER();
5105
5106 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5107 ret = wlan_hdd_validate_context(hdd_ctx);
5108 if (0 != ret)
5109 return ret;
5110
5111 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
5112 EXIT();
5113 return 0;
5114}
5115
5116static int iw_softap_version(struct net_device *dev,
5117 struct iw_request_info *info,
5118 union iwreq_data *wrqu,
5119 char *extra)
5120{
5121 int ret;
5122
5123 cds_ssr_protect(__func__);
5124 ret = __iw_softap_version(dev, info, wrqu, extra);
5125 cds_ssr_unprotect(__func__);
5126
5127 return ret;
5128}
5129
5130static
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305131QDF_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, uint8_t *pBuf,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005132 int buf_len) {
5133 uint8_t i;
5134 uint8_t maxSta = 0;
5135 int len = 0;
5136 const char sta_info_header[] = "staId staAddress";
5137 hdd_context_t *hdd_ctx;
5138
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305139 ENTER();
5140
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005141 if (NULL == pAdapter) {
5142 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
5143 "%s: Adapter is NULL", __func__);
5144 return -EINVAL;
5145 }
5146
5147 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5148 if (0 != wlan_hdd_validate_context(hdd_ctx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305149 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005150
5151 len = scnprintf(pBuf, buf_len, sta_info_header);
5152 pBuf += len;
5153 buf_len -= len;
5154
5155 maxSta = hdd_ctx->config->maxNumberOfPeers;
5156
5157 for (i = 0; i <= maxSta; i++) {
5158 if (pAdapter->aStaInfo[i].isUsed) {
5159 len =
5160 scnprintf(pBuf, buf_len,
5161 "%5d .%02x:%02x:%02x:%02x:%02x:%02x",
5162 pAdapter->aStaInfo[i].ucSTAId,
5163 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
5164 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
5165 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
5166 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
5167 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
5168 pAdapter->aStaInfo[i].macAddrSTA.
5169 bytes[5]);
5170 pBuf += len;
5171 buf_len -= len;
5172 }
5173 if (WE_GET_STA_INFO_SIZE > buf_len) {
5174 break;
5175 }
5176 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305177 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305178 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005179}
5180
5181static int __iw_softap_get_sta_info(struct net_device *dev,
5182 struct iw_request_info *info,
5183 union iwreq_data *wrqu, char *extra)
5184{
5185 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305186 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005187 hdd_context_t *hdd_ctx;
5188 int ret;
5189
5190 ENTER();
5191
5192 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5193 ret = wlan_hdd_validate_context(hdd_ctx);
5194 if (0 != ret)
5195 return ret;
5196
5197 status =
5198 hdd_softap_get_sta_info(pHostapdAdapter, extra,
5199 WE_SAP_MAX_STA_INFO);
5200
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305201 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005202 hddLog(LOGE, FL("Failed to get sta info: %d"), status);
5203 return -EINVAL;
5204 }
5205 wrqu->data.length = strlen(extra);
5206 EXIT();
5207 return 0;
5208}
5209
5210static int iw_softap_get_sta_info(struct net_device *dev,
5211 struct iw_request_info *info,
5212 union iwreq_data *wrqu,
5213 char *extra)
5214{
5215 int ret;
5216
5217 cds_ssr_protect(__func__);
5218 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
5219 cds_ssr_unprotect(__func__);
5220
5221 return ret;
5222}
5223
5224/**
5225 * __iw_set_ap_genie() - set ap wpa/rsn ie
5226 *
5227 * @dev - Pointer to the net device.
5228 * @info - Pointer to the iw_request_info.
5229 * @wrqu - Pointer to the iwreq_data.
5230 * @extra - Pointer to the data.
5231 *
5232 * Return: 0 for success, non zero for failure.
5233 */
5234static int __iw_set_ap_genie(struct net_device *dev,
5235 struct iw_request_info *info,
5236 union iwreq_data *wrqu, char *extra) {
5237
5238 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5239#ifndef WLAN_FEATURE_MBSSID
5240 v_CONTEXT_t cds_ctx;
5241#endif
5242 hdd_context_t *hdd_ctx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305243 QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005244 uint8_t *genie = (uint8_t *)extra;
5245 int ret;
5246
5247 ENTER();
5248
5249 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5250 ret = wlan_hdd_validate_context(hdd_ctx);
5251 if (0 != ret)
5252 return ret;
5253
5254#ifndef WLAN_FEATURE_MBSSID
5255 cds_ctx = hdd_ctx->pcds_context;
5256 if (NULL == cds_ctx) {
5257 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
5258 "%s: CDF Context is NULL", __func__);
5259 return -EINVAL;
5260 }
5261#endif
5262
5263 if (!wrqu->data.length) {
5264 EXIT();
5265 return 0;
5266 }
5267
5268 switch (genie[0]) {
5269 case DOT11F_EID_WPA:
5270 case DOT11F_EID_RSN:
5271 if ((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) {
5272 hdd_softap_deregister_bc_sta(pHostapdAdapter);
5273 hdd_softap_register_bc_sta(pHostapdAdapter, 1);
5274 }
5275 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
5276#ifdef WLAN_FEATURE_MBSSID
5277 cdf_ret_status =
5278 wlansap_set_wparsn_ies(WLAN_HDD_GET_SAP_CTX_PTR
5279 (pHostapdAdapter), genie,
5280 wrqu->data.length);
5281#else
5282 cdf_ret_status =
5283 wlansap_set_wparsn_ies(cds_ctx, genie,
5284 wrqu->data.length);
5285#endif
5286 break;
5287
5288 default:
5289 hddLog(LOGE, FL("Set UNKNOWN IE %X"), genie[0]);
5290 cdf_ret_status = 0;
5291 }
5292
5293 EXIT();
5294 return cdf_ret_status;
5295}
5296
5297/**
5298 * iw_set_ap_genie() - Wrapper function to protect __iw_set_ap_genie
5299 * from the SSR.
5300 *
5301 * @dev - Pointer to the net device.
5302 * @info - Pointer to the iw_request_info.
5303 * @wrqu - Pointer to the iwreq_data.
5304 * @extra - Pointer to the data.
5305 *
5306 * Return: 0 for success, non zero for failure.
5307 */
5308static int
5309iw_set_ap_genie(struct net_device *dev,
5310 struct iw_request_info *info,
5311 union iwreq_data *wrqu, char *extra)
5312{
5313 int ret;
5314
5315 cds_ssr_protect(__func__);
5316 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
5317 cds_ssr_unprotect(__func__);
5318
5319 return ret;
5320}
5321
5322static
5323int __iw_get_softap_linkspeed(struct net_device *dev,
5324 struct iw_request_info *info,
5325 union iwreq_data *wrqu, char *extra)
5326{
5327 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
5328 hdd_context_t *hdd_ctx;
5329 char *pLinkSpeed = (char *)extra;
5330 uint32_t link_speed = 0;
5331 int len = sizeof(uint32_t) + 1;
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005332 struct cdf_mac_addr macAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005333 char pmacAddress[MAC_ADDRESS_STR_LEN + 1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305334 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005335 int rc, valid, i;
5336
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305337 ENTER();
5338
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005339 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5340 valid = wlan_hdd_validate_context(hdd_ctx);
5341 if (0 != valid)
5342 return valid;
5343
5344 hddLog(LOG1, FL("wrqu->data.length(%d)"), wrqu->data.length);
5345
5346 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
5347 if (copy_from_user((void *)pmacAddress,
5348 wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
5349 hddLog(LOG1, FL("failed to copy data to user buffer"));
5350 return -EFAULT;
5351 }
5352 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
5353
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005354 if (!mac_pton(pmacAddress, macAddress.bytes)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005355 hddLog(LOGE, FL("String to Hex conversion Failed"));
5356 return -EINVAL;
5357 }
5358 }
5359 /* If no mac address is passed and/or its length is less than 17,
5360 * link speed for first connected client will be returned.
5361 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305362 if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005363 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
5364 if (pHostapdAdapter->aStaInfo[i].isUsed &&
5365 (!cdf_is_macaddr_broadcast
5366 (&pHostapdAdapter->aStaInfo[i].macAddrSTA))) {
5367 cdf_copy_macaddr(
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005368 &macAddress,
5369 &pHostapdAdapter->aStaInfo[i].
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005370 macAddrSTA);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305371 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005372 break;
5373 }
5374 }
5375 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305376 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005377 hddLog(LOGE, FL("Invalid peer macaddress"));
5378 return -EINVAL;
5379 }
5380 status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter,
5381 macAddress);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305382 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005383 hddLog(LOGE, FL("Unable to retrieve SME linkspeed"));
5384 return -EINVAL;
5385 }
5386
5387 link_speed = pHostapdAdapter->ls_stats.estLinkSpeed;
5388
5389 /* linkspeed in units of 500 kbps */
5390 link_speed = link_speed / 500;
5391 wrqu->data.length = len;
5392 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
5393 if ((rc < 0) || (rc >= len)) {
5394 /* encoding or length error? */
5395 hddLog(LOGE, FL("Unable to encode link speed"));
5396 return -EIO;
5397 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305398 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005399 return 0;
5400}
5401
5402static int
5403iw_get_softap_linkspeed(struct net_device *dev,
5404 struct iw_request_info *info,
5405 union iwreq_data *wrqu,
5406 char *extra)
5407{
5408 int ret;
5409
5410 cds_ssr_protect(__func__);
5411 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
5412 cds_ssr_unprotect(__func__);
5413
5414 return ret;
5415}
5416
5417static const iw_handler hostapd_handler[] = {
5418 (iw_handler) NULL, /* SIOCSIWCOMMIT */
5419 (iw_handler) NULL, /* SIOCGIWNAME */
5420 (iw_handler) NULL, /* SIOCSIWNWID */
5421 (iw_handler) NULL, /* SIOCGIWNWID */
5422 (iw_handler) NULL, /* SIOCSIWFREQ */
5423 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
5424 (iw_handler) NULL, /* SIOCSIWMODE */
5425 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
5426 (iw_handler) NULL, /* SIOCSIWSENS */
5427 (iw_handler) NULL, /* SIOCGIWSENS */
5428 (iw_handler) NULL, /* SIOCSIWRANGE */
5429 (iw_handler) NULL, /* SIOCGIWRANGE */
5430 (iw_handler) NULL, /* SIOCSIWPRIV */
5431 (iw_handler) NULL, /* SIOCGIWPRIV */
5432 (iw_handler) NULL, /* SIOCSIWSTATS */
5433 (iw_handler) NULL, /* SIOCGIWSTATS */
5434 (iw_handler) NULL, /* SIOCSIWSPY */
5435 (iw_handler) NULL, /* SIOCGIWSPY */
5436 (iw_handler) NULL, /* SIOCSIWTHRSPY */
5437 (iw_handler) NULL, /* SIOCGIWTHRSPY */
5438 (iw_handler) NULL, /* SIOCSIWAP */
5439 (iw_handler) NULL, /* SIOCGIWAP */
5440 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
5441 (iw_handler) NULL, /* SIOCGIWAPLIST */
5442 (iw_handler) NULL, /* SIOCSIWSCAN */
5443 (iw_handler) NULL, /* SIOCGIWSCAN */
5444 (iw_handler) NULL, /* SIOCSIWESSID */
5445 (iw_handler) NULL, /* SIOCGIWESSID */
5446 (iw_handler) NULL, /* SIOCSIWNICKN */
5447 (iw_handler) NULL, /* SIOCGIWNICKN */
5448 (iw_handler) NULL, /* -- hole -- */
5449 (iw_handler) NULL, /* -- hole -- */
5450 (iw_handler) NULL, /* SIOCSIWRATE */
5451 (iw_handler) NULL, /* SIOCGIWRATE */
5452 (iw_handler) NULL, /* SIOCSIWRTS */
5453 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
5454 (iw_handler) NULL, /* SIOCSIWFRAG */
5455 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
5456 (iw_handler) NULL, /* SIOCSIWTXPOW */
5457 (iw_handler) NULL, /* SIOCGIWTXPOW */
5458 (iw_handler) NULL, /* SIOCSIWRETRY */
5459 (iw_handler) NULL, /* SIOCGIWRETRY */
5460 (iw_handler) NULL, /* SIOCSIWENCODE */
5461 (iw_handler) NULL, /* SIOCGIWENCODE */
5462 (iw_handler) NULL, /* SIOCSIWPOWER */
5463 (iw_handler) NULL, /* SIOCGIWPOWER */
5464 (iw_handler) NULL, /* -- hole -- */
5465 (iw_handler) NULL, /* -- hole -- */
5466 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
5467 (iw_handler) NULL, /* SIOCGIWGENIE */
5468 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
5469 (iw_handler) NULL, /* SIOCGIWAUTH */
5470 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
5471 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
5472 (iw_handler) NULL, /* SIOCSIWPMKSA */
5473};
5474
5475/*
5476 * Note that the following ioctls were defined with semantics which
5477 * cannot be handled by the "iwpriv" userspace application and hence
5478 * they are not included in the hostapd_private_args array
5479 * QCSAP_IOCTL_ASSOC_STA_MACADDR
5480 */
5481
5482static const struct iw_priv_args hostapd_private_args[] = {
5483 {
5484 QCSAP_IOCTL_SETPARAM,
5485 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
5486 }, {
5487 QCSAP_IOCTL_SETPARAM,
5488 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
5489 }, {
5490 QCSAP_PARAM_MAX_ASSOC,
5491 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5492 "setMaxAssoc"
5493 }, {
5494 QCSAP_PARAM_HIDE_SSID,
5495 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
5496 }, {
5497 QCSAP_PARAM_SET_MC_RATE,
5498 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
5499 },
5500 {
5501 QCSAP_PARAM_SET_TXRX_FW_STATS,
5502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5503 "txrx_fw_stats"
5504 }, {
5505 QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
5506 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5507 "setMccLatency"
5508 }, {
5509 QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
5510 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5511 "setMccQuota"
5512 }, {
5513 QCSAP_PARAM_SET_CHANNEL_CHANGE,
5514 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5515 "setChanChange"
5516 }, {
5517 QCSAP_PARAM_AUTO_CHANNEL,
5518 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5519 "setAutoChannel"
5520 },
5521 /* Sub-cmds DBGLOG specific commands */
5522 {
5523 QCSAP_DBGLOG_LOG_LEVEL,
5524 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5525 0, "dl_loglevel"
5526 }, {
5527 QCSAP_DBGLOG_VAP_ENABLE,
5528 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
5529 }, {
5530 QCSAP_DBGLOG_VAP_DISABLE,
5531 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5532 0, "dl_vapoff"
5533 }, {
5534 QCSAP_DBGLOG_MODULE_ENABLE,
5535 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
5536 }, {
5537 QCSAP_DBGLOG_MODULE_DISABLE,
5538 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5539 0, "dl_modoff"
5540 }, {
5541 QCSAP_DBGLOG_MOD_LOG_LEVEL,
5542 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5543 0, "dl_mod_loglevel"
5544 }, {
5545 QCSAP_DBGLOG_TYPE,
5546 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
5547 }, {
5548 QCSAP_DBGLOG_REPORT_ENABLE,
5549 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5550 0, "dl_report"
5551 }, {
5552 QCASAP_TXRX_FWSTATS_RESET,
5553 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5554 0, "txrx_fw_st_rst"
5555 }, {
5556 QCSAP_PARAM_RTSCTS,
5557 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5558 0, "enablertscts"
5559 }, {
5560 QCASAP_SET_11N_RATE,
5561 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5562 0, "set11NRates"
5563 }, {
5564 QCASAP_SET_VHT_RATE,
5565 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5566 0, "set11ACRates"
5567 }, {
5568 QCASAP_SHORT_GI,
5569 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5570 0, "enable_short_gi"
5571 }, {
5572 QCSAP_SET_AMPDU,
5573 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
5574 }, {
5575 QCSAP_SET_AMSDU,
5576 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
5577 }, {
5578 QCSAP_GTX_HT_MCS,
5579 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
5580 }, {
5581 QCSAP_GTX_VHT_MCS,
5582 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5583 0, "gtxVHTMcs"
5584 }, {
5585 QCSAP_GTX_USRCFG,
5586 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5587 0, "gtxUsrCfg"
5588 }, {
5589 QCSAP_GTX_THRE,
5590 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
5591 }, {
5592 QCSAP_GTX_MARGIN,
5593 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5594 0, "gtxMargin"
5595 }, {
5596 QCSAP_GTX_STEP,
5597 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
5598 }, {
5599 QCSAP_GTX_MINTPC,
5600 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5601 0, "gtxMinTpc"
5602 }, {
5603 QCSAP_GTX_BWMASK,
5604 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5605 0, "gtxBWMask"
5606 }, {
5607 QCSAP_PARAM_CLR_ACL,
5608 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5609 0, "setClearAcl"
5610 }, {
5611 QCSAP_PARAM_ACL_MODE,
5612 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
5613 },
5614#ifdef QCA_PKT_PROTO_TRACE
5615 {
5616 QCASAP_SET_DEBUG_LOG,
5617 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setDbgLvl"
5618 },
5619#endif /* QCA_PKT_PROTO_TRACE */
5620 {
5621 QCASAP_SET_TM_LEVEL,
5622 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5623 0, "setTmLevel"
5624 }, {
5625 QCASAP_SET_DFS_IGNORE_CAC,
5626 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5627 0, "setDfsIgnoreCAC"
5628 }, {
5629 QCASAP_SET_DFS_NOL,
5630 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5631 0, "setdfsnol"
5632 }, {
5633 QCASAP_SET_DFS_TARGET_CHNL,
5634 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5635 0, "setNextChnl"
5636 }, {
5637 QCASAP_SET_RADAR_CMD,
5638 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
5639 },
5640 {
5641 QCSAP_IPA_UC_STAT,
5642 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
5643 },
5644 {
5645 QCASAP_TX_CHAINMASK_CMD,
5646 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5647 0, "set_txchainmask"
5648 }, {
5649 QCASAP_RX_CHAINMASK_CMD,
5650 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5651 0, "set_rxchainmask"
5652 }, {
5653 QCASAP_NSS_CMD,
5654 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
5655 }, {
5656 QCASAP_SET_PHYMODE,
5657 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5658 0, "setphymode"
5659 }, {
5660 QCASAP_DUMP_STATS,
5661 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5662 0, "dumpStats"
5663 }, {
5664 QCASAP_CLEAR_STATS,
5665 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5666 0, "clearStats"
5667 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305668 QCSAP_START_FW_PROFILING,
5669 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5670 0, "startProfile"
5671 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005672 QCSAP_IOCTL_GETPARAM, 0,
5673 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
5674 }, {
5675 QCSAP_IOCTL_GETPARAM, 0,
5676 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
5677 }, {
5678 QCSAP_PARAM_MAX_ASSOC, 0,
5679 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
5680 }, {
5681 QCSAP_PARAM_GET_WLAN_DBG, 0,
5682 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
5683 }, {
5684 QCSAP_PARAM_AUTO_CHANNEL, 0,
5685 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel"
5686 }, {
5687 QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5688 "get_gtxBWMask"
5689 }, {
5690 QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5691 "get_gtxMinTpc"
5692 }, {
5693 QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5694 "get_gtxStep"
5695 }, {
5696 QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5697 "get_gtxMargin"
5698 }, {
5699 QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5700 "get_gtxThre"
5701 }, {
5702 QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5703 "get_gtxUsrCfg"
5704 }, {
5705 QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5706 "get_gtxVHTMcs"
5707 }, {
5708 QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5709 "get_gtxHTMcs"
5710 }, {
5711 QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5712 "get_short_gi"
5713 }, {
5714 QCSAP_PARAM_RTSCTS, 0,
5715 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
5716 }, {
5717 QCASAP_GET_DFS_NOL, 0,
5718 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
5719 }, {
5720 QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5721 "get_acl_list"
5722 }, {
5723 QCASAP_TX_CHAINMASK_CMD, 0,
5724 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5725 "get_txchainmask"
5726 }, {
5727 QCASAP_RX_CHAINMASK_CMD, 0,
5728 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5729 "get_rxchainmask"
5730 }, {
5731 QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5732 "get_nss"
5733 }, {
5734 QCASAP_GET_TEMP_CMD, 0,
5735 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
5736 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305737 QCSAP_GET_FW_PROFILE_DATA, 0,
5738 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
5739 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005740 QCSAP_IOCTL_GET_STAWPAIE,
5741 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
5742 "get_staWPAIE"
5743 }, {
5744 QCSAP_IOCTL_SETWPAIE,
5745 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE |
5746 IW_PRIV_SIZE_FIXED, 0, "setwpaie"
5747 }, {
5748 QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
5749 "stopbss"
5750 }, {
5751 QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE,
5752 "version"
5753 }, {
5754 QCSAP_IOCTL_GET_STA_INFO, 0,
5755 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
5756 }, {
5757 QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
5758 IW_PRIV_TYPE_BYTE |
5759 sizeof(sQcSapreq_WPSPBCProbeReqIES_t) |
5760 IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs"
5761 }
5762 , {
5763 QCSAP_IOCTL_GET_CHANNEL, 0,
5764 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
5765 }
5766 , {
5767 QCSAP_IOCTL_DISASSOC_STA,
5768 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
5769 "disassoc_sta"
5770 }
5771 /* handler for main ioctl */
5772 , {
5773 QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
5774 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
5775 }
5776 /* handler for sub-ioctl */
5777 , {
5778 QCSAP_GET_STATS, 0,
5779 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
5780 }
5781 , {
Govind Singha471e5e2015-10-12 17:11:14 +05305782 QCSAP_LIST_FW_PROFILE, 0,
5783 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
5784 }
5785 , {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005786 QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
5787 IW_PRIV_TYPE_CHAR | 18,
5788 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
5789 }
5790 , {
5791 QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
5792 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
5793 }
5794 ,
5795 /* handlers for sub-ioctl */
5796 {
5797 WE_SET_WLAN_DBG,
5798 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
5799 }, {
5800 WE_SET_SAP_CHANNELS,
5801 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setsapchannels"
5802 }
5803 ,
5804 /* handlers for sub-ioctl */
5805 {
5806 WE_SET_DP_TRACE,
5807 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
5808 }
5809 ,
5810 /* handlers for main ioctl */
5811 {
5812 QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
5813 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
5814 }
5815 , {
5816 WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
5817 }
5818 , {
5819 WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
5820 "setUnitTestCmd"
5821 }
5822 ,
5823 /* handlers for main ioctl */
5824 {
5825 QCSAP_IOCTL_MODIFY_ACL,
5826 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
5827 }
5828 ,
5829 /* handlers for main ioctl */
5830 {
5831 QCSAP_IOCTL_GET_CHANNEL_LIST,
5832 0,
5833 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
5834 "getChannelList"
5835 }
5836 ,
5837 /* handlers for main ioctl */
5838 {
5839 QCSAP_IOCTL_SET_TX_POWER,
5840 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
5841 }
5842 ,
5843 /* handlers for main ioctl */
5844 {
5845 QCSAP_IOCTL_SET_MAX_TX_POWER,
5846 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5847 0, "setTxMaxPower"
5848 }
5849 ,
5850 /* Set HDD CFG Ini param */
5851 {
5852 QCSAP_IOCTL_SET_INI_CFG,
5853 IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig"
5854 }
5855 ,
5856 /* Get HDD CFG Ini param */
5857 {
5858 QCSAP_IOCTL_GET_INI_CFG,
5859 0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
5860 }
5861 ,
5862 /* handlers for main ioctl */
5863 {
5864 /* handlers for main ioctl */
5865 QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
5866 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
5867 }
5868 ,
5869 /* handlers for sub-ioctl */
5870#ifdef DEBUG
5871 {
5872 QCSAP_IOCTL_SET_FW_CRASH_INJECT,
5873 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5874 0, "crash_inject"
5875 }
5876 ,
5877#endif
5878 {
5879 QCASAP_SET_RADAR_DBG,
5880 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5881 0, "setRadarDbg"
5882 }
5883 ,
5884 /* dump dp trace - descriptor or dp trace records */
5885 {
5886 QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
5887 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5888 0, "dump_dp_trace"
5889 }
5890 ,
Govind Singha471e5e2015-10-12 17:11:14 +05305891 {
5892 QCSAP_ENABLE_FW_PROFILE,
5893 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5894 0, "enableProfile"
5895 }
5896 ,
5897 {
5898 QCSAP_SET_FW_PROFILE_HIST_INTVL,
5899 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5900 0, "set_hist_intvl"
5901 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005902};
5903
5904static const iw_handler hostapd_private[] = {
5905 /* set priv ioctl */
5906 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
5907 /* get priv ioctl */
5908 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
5909 /* get station genIE */
5910 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
5911 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
5912 /* stop bss */
5913 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
5914 /* get driver version */
5915 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
5916 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] =
5917 iw_get_wpspbc_probe_req_ies,
5918 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
5919 iw_softap_getchannel,
5920 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
5921 iw_softap_getassoc_stamacaddr,
5922 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
5923 iw_softap_disassoc_sta,
5924 [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
5925 iw_get_char_setnone,
5926 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
5927 SIOCIWFIRSTPRIV] =
5928 iw_set_three_ints_getnone,
5929 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
5930 SIOCIWFIRSTPRIV] =
5931 iw_set_var_ints_getnone,
5932 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] =
5933 iw_softap_set_force_acs_ch_range,
5934 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
5935 iw_softap_modify_acl,
5936 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
5937 iw_softap_get_channel_list,
5938 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
5939 iw_softap_get_sta_info,
5940 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
5941 SIOCIWFIRSTPRIV] =
5942 iw_get_softap_linkspeed,
5943 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
5944 iw_softap_set_tx_power,
5945 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
5946 iw_softap_set_max_tx_power,
5947 [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
5948 iw_softap_set_ini_cfg,
5949 [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
5950 iw_softap_get_ini_cfg,
5951 [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
5952 iw_softap_set_two_ints_getnone,
5953};
5954const struct iw_handler_def hostapd_handler_def = {
5955 .num_standard = CDF_ARRAY_SIZE(hostapd_handler),
5956 .num_private = CDF_ARRAY_SIZE(hostapd_private),
5957 .num_private_args = CDF_ARRAY_SIZE(hostapd_private_args),
5958 .standard = (iw_handler *) hostapd_handler,
5959 .private = (iw_handler *) hostapd_private,
5960 .private_args = hostapd_private_args,
5961 .get_wireless_stats = NULL,
5962};
5963
5964struct net_device_ops net_ops_struct = {
5965 .ndo_open = hdd_hostapd_open,
5966 .ndo_stop = hdd_hostapd_stop,
5967 .ndo_uninit = hdd_hostapd_uninit,
5968 .ndo_start_xmit = hdd_softap_hard_start_xmit,
5969 .ndo_tx_timeout = hdd_softap_tx_timeout,
5970 .ndo_get_stats = hdd_get_stats,
5971 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
5972 .ndo_do_ioctl = hdd_ioctl,
5973 .ndo_change_mtu = hdd_hostapd_change_mtu,
5974 .ndo_select_queue = hdd_hostapd_select_queue,
5975};
5976
5977static int hdd_set_hostapd(hdd_adapter_t *pAdapter)
5978{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305979 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005980}
5981
5982void hdd_set_ap_ops(struct net_device *pWlanHostapdDev)
5983{
5984 pWlanHostapdDev->netdev_ops = &net_ops_struct;
5985}
5986
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305987QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005988{
5989 hdd_hostapd_state_t *phostapdBuf;
5990 struct net_device *dev = pAdapter->dev;
5991 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305992 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305993 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005994#ifdef WLAN_FEATURE_MBSSID
5995 v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(pAdapter))->pcds_context;
5996 v_CONTEXT_t sapContext = NULL;
5997#endif
5998 int ret;
5999
6000 ENTER();
6001
6002#ifdef WLAN_FEATURE_MBSSID
6003 sapContext = wlansap_open(p_cds_context);
6004 if (sapContext == NULL) {
6005 hddLog(LOGE, ("ERROR: wlansap_open failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306006 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006007 }
6008
6009 pAdapter->sessionCtx.ap.sapContext = sapContext;
6010
6011 status = wlansap_start(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306012 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006013 hddLog(LOGE, ("ERROR: wlansap_start failed!!"));
6014 wlansap_close(sapContext);
6015 return status;
6016 }
6017#endif
6018
6019 /* Allocate the Wireless Extensions state structure */
6020 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6021
6022 sme_set_curr_device_mode(pHddCtx->hHal, pAdapter->device_mode);
6023
6024 /* Zero the memory. This zeros the profile structure. */
6025 memset(phostapdBuf, 0, sizeof(hdd_hostapd_state_t));
6026
6027 /* Set up the pointer to the Wireless Extensions state structure */
6028 /* NOP */
6029 status = hdd_set_hostapd(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306030 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006031 hddLog(LOGE, ("ERROR: hdd_set_hostapd failed!!"));
6032#ifdef WLAN_FEATURE_MBSSID
6033 wlansap_close(sapContext);
6034#endif
6035 return status;
6036 }
6037
Anurag Chouhance0dc992016-02-16 18:18:03 +05306038 qdf_status = qdf_event_create(&phostapdBuf->cdf_event);
6039 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006040 hddLog(LOGE, ("ERROR: Hostapd HDD cdf event init failed!!"));
6041#ifdef WLAN_FEATURE_MBSSID
6042 wlansap_close(sapContext);
6043#endif
Anurag Chouhance0dc992016-02-16 18:18:03 +05306044 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006045 }
6046
Anurag Chouhance0dc992016-02-16 18:18:03 +05306047 qdf_status = qdf_event_create(&phostapdBuf->cdf_stop_bss_event);
6048 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006049 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
6050 ("ERROR: Hostapd HDD stop bss event init failed!!"));
6051#ifdef WLAN_FEATURE_MBSSID
6052 wlansap_close(sapContext);
6053#endif
Anurag Chouhance0dc992016-02-16 18:18:03 +05306054 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006055 }
6056
6057 init_completion(&pAdapter->session_close_comp_var);
6058 init_completion(&pAdapter->session_open_comp_var);
6059
6060 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
6061
6062 /* Register as a wireless device */
6063 dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
6064
6065 /* Initialize the data path module */
6066 status = hdd_softap_init_tx_rx(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306067 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006068 hddLog(LOGP, FL("hdd_softap_init_tx_rx failed"));
6069 }
6070
6071 status = hdd_wmm_adapter_init(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306072 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006073 hddLog(LOGE,
6074 "hdd_wmm_adapter_init() failed code %08d [x%08x]",
6075 status, status);
6076 goto error_wmm_init;
6077 }
6078
6079 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6080
6081 ret = wma_cli_set_command(pAdapter->sessionId,
6082 WMI_PDEV_PARAM_BURST_ENABLE,
6083 pHddCtx->config->enableSifsBurst,
6084 PDEV_CMD);
6085
6086 if (0 != ret) {
6087 hddLog(LOGE,
6088 FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"), ret);
6089 }
6090 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
6091 cdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
6092 cdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
6093 sizeof(struct sap_acs_cfg));
6094 return status;
6095
6096error_wmm_init:
6097 hdd_softap_deinit_tx_rx(pAdapter);
6098#ifdef WLAN_FEATURE_MBSSID
6099 wlansap_close(sapContext);
6100#endif
6101 EXIT();
6102 return status;
6103}
6104
6105/**
6106 * hdd_wlan_create_ap_dev() - create an AP-mode device
6107 * @pHddCtx: Global HDD context
6108 * @macAddr: MAC address to assign to the interface
6109 * @iface_name: User-visible name of the interface
6110 *
6111 * This function will allocate a Linux net_device and configuration it
6112 * for an AP mode of operation. Note that the device is NOT actually
6113 * registered with the kernel at this time.
6114 *
6115 * Return: A pointer to the private data portion of the net_device if
6116 * the allocation and initialization was successful, NULL otherwise.
6117 */
6118hdd_adapter_t *hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx,
6119 tSirMacAddr macAddr,
6120 uint8_t *iface_name) {
6121 struct net_device *pWlanHostapdDev = NULL;
6122 hdd_adapter_t *pHostapdAdapter = NULL;
6123
6124 hddLog(LOG4, FL("iface_name = %s"), iface_name);
6125
6126 pWlanHostapdDev =
6127 alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name,
6128#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
6129 NET_NAME_UNKNOWN,
6130#endif
6131 ether_setup,
6132 NUM_TX_QUEUES);
6133
6134 if (pWlanHostapdDev != NULL) {
6135 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
6136
6137 /* Init the net_device structure */
6138 ether_setup(pWlanHostapdDev);
6139
6140 /* Initialize the adapter context to zeros. */
6141 cdf_mem_zero(pHostapdAdapter, sizeof(hdd_adapter_t));
6142 pHostapdAdapter->dev = pWlanHostapdDev;
6143 pHostapdAdapter->pHddCtx = pHddCtx;
6144 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6145
6146 hddLog(LOG4,
6147 FL("pWlanHostapdDev = %p, pHostapdAdapter = %p, concurrency_mode=0x%x"),
6148 pWlanHostapdDev,
6149 pHostapdAdapter,
6150 (int)cds_get_concurrency_mode());
6151
6152 /* Init the net_device structure */
6153 strlcpy(pWlanHostapdDev->name, (const char *)iface_name,
6154 IFNAMSIZ);
6155
6156 hdd_set_ap_ops(pHostapdAdapter->dev);
6157
6158 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
6159 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
Mohit Khannaee9e80f2015-11-10 11:32:49 -08006160 pWlanHostapdDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006161
6162 cdf_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,
6163 sizeof(tSirMacAddr));
6164 cdf_mem_copy(pHostapdAdapter->macAddressCurrent.bytes,
6165 (void *)macAddr, sizeof(tSirMacAddr));
6166
6167 pHostapdAdapter->offloads_configured = false;
6168 pWlanHostapdDev->destructor = free_netdev;
6169 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev;
6170 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
6171 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
Dhanashri Atre83d373d2015-07-28 16:45:59 -07006172 hdd_set_tso_flags(pHddCtx, pWlanHostapdDev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006173 init_completion(&pHostapdAdapter->tx_action_cnf_event);
6174 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
6175 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
6176 init_completion(&pHostapdAdapter->sta_authorized_event);
6177 init_completion(&pHostapdAdapter->offchannel_tx_event);
6178 init_completion(&pHostapdAdapter->scan_info.
6179 abortscan_event_var);
6180
6181 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
6182 spin_lock_init(&pHostapdAdapter->pause_map_lock);
6183 }
6184 return pHostapdAdapter;
6185}
6186
6187/**
6188 * hdd_register_hostapd() - register hostapd
6189 * @pAdapter: Pointer to hostapd adapter
6190 * @rtnl_lock_held: RTNL lock held
6191 *
6192 * Return: CDF status
6193 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306194QDF_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006195 uint8_t rtnl_lock_held) {
6196 struct net_device *dev = pAdapter->dev;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306197 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006198
6199 ENTER();
6200
6201 if (rtnl_lock_held) {
6202 if (strnchr(dev->name, strlen(dev->name), '%')) {
6203 if (dev_alloc_name(dev, dev->name) < 0) {
6204 hddLog(LOGE, FL("Failed:dev_alloc_name"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306205 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006206 }
6207 }
6208 if (register_netdevice(dev)) {
6209 hddLog(LOGE, FL("Failed:register_netdevice"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306210 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006211 }
6212 } else {
6213 if (register_netdev(dev)) {
6214 hddLog(LOGE, FL("Failed:register_netdev"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306215 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006216 }
6217 }
6218 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6219
6220 EXIT();
6221 return status;
6222}
6223
6224/**
6225 * hdd_unregister_hostapd() - unregister hostapd
6226 * @pAdapter: Pointer to hostapd adapter
6227 * @rtnl_held: true if rtnl lock held; false otherwise
6228 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306229 * Return: QDF_STATUS enumaration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006230 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306231QDF_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006232{
6233#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306234 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006235 void *sapContext = WLAN_HDD_GET_SAP_CTX_PTR(pAdapter);
6236#endif
6237
6238 ENTER();
6239
6240 hdd_softap_deinit_tx_rx(pAdapter);
6241
6242 /* if we are being called during driver unload,
6243 * then the dev has already been invalidated.
6244 * if we are being called at other times, then we can
6245 * detach the wireless device handlers
6246 */
6247 if (pAdapter->dev) {
6248 if (rtnl_held)
6249 pAdapter->dev->wireless_handlers = NULL;
6250 else {
6251 rtnl_lock();
6252 pAdapter->dev->wireless_handlers = NULL;
6253 rtnl_unlock();
6254 }
6255 }
6256
6257#ifdef WLAN_FEATURE_MBSSID
6258 status = wlansap_stop(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306259 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006260 hddLog(LOGE, FL("Failed:wlansap_stop"));
6261
6262 status = wlansap_close(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306263 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006264 hddLog(LOGE, FL("Failed:WLANSAP_close"));
6265 pAdapter->sessionCtx.ap.sapContext = NULL;
6266#endif
6267
6268 EXIT();
6269 return 0;
6270}
6271
6272/**
6273 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
6274 * @rate: Rate to be checked
6275 *
6276 * Return: true if rate if 11g else false
6277 */
6278static bool wlan_hdd_rate_is_11g(u8 rate)
6279{
6280 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
6281 96, 108}; /* actual rate * 2 */
6282 u8 i;
6283 for (i = 0; i < 8; i++) {
6284 if (rate == gRateArray[i])
6285 return true;
6286 }
6287 return false;
6288}
6289
6290#ifdef QCA_HT_2040_COEX
6291/**
6292 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
6293 * @pHostapdAdapter: Pointer to hostapd adapter
6294 *
6295 * Return: HT support channel width config value
6296 */
6297static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6298{
6299 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
6300 tDot11fIEHTCaps dot11_ht_cap_ie = {0};
6301 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
6302 beacon_data_t *beacon = pHostapdAdapter->sessionCtx.ap.beacon;
6303 uint8_t *ie = NULL;
6304
6305 ie = wlan_hdd_cfg80211_get_ie_ptr(beacon->tail, beacon->tail_len,
6306 WLAN_EID_HT_CAPABILITY);
6307 if (ie && ie[1]) {
6308 cdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
6309 dot11f_unpack_ie_ht_caps((tpAniSirGlobal)hdd_ctx->hHal,
6310 ht_cap_ie, ie[1], &dot11_ht_cap_ie);
6311 return dot11_ht_cap_ie.supportedChannelWidthSet;
6312 }
6313
6314 return false;
6315}
6316#else
6317static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6318{
6319 return false;
6320}
6321#endif
6322/**
6323 * wlan_hdd_set_channel() - set channel in sap mode
6324 * @wiphy: Pointer to wiphy structure
6325 * @dev: Pointer to net_device structure
6326 * @chandef: Pointer to channel definition structure
6327 * @channel_type: Channel type
6328 *
6329 * Return: 0 for success non-zero for failure
6330 */
6331static int wlan_hdd_set_channel(struct wiphy *wiphy,
6332 struct net_device *dev,
6333 struct cfg80211_chan_def *chandef,
6334 enum nl80211_channel_type channel_type)
6335{
6336 hdd_adapter_t *pAdapter = NULL;
6337 uint32_t num_ch = 0;
6338 int channel = 0;
6339 int channel_seg2 = 0;
6340 hdd_context_t *pHddCtx;
6341 int status;
6342
6343 tSmeConfigParams smeConfig;
6344 tsap_Config_t *sap_config;
6345
6346 ENTER();
6347
6348
6349 if (NULL == dev) {
6350 hddLog(LOGE, FL("Called with dev = NULL."));
6351 return -ENODEV;
6352 }
6353 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6354
6355 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
6356 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
6357 pAdapter->sessionId, channel_type));
6358
6359 hddLog(LOG1, FL("Device_mode %s(%d) freq = %d"),
6360 hdd_device_mode_to_string(pAdapter->device_mode),
6361 pAdapter->device_mode, chandef->chan->center_freq);
6362
6363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6364 status = wlan_hdd_validate_context(pHddCtx);
6365
6366 if (0 != status) {
6367 hddLog(LOGE, FL("HDD context is not valid"));
6368 return status;
6369 }
6370
6371 /*
6372 * Do freq to chan conversion
6373 * TODO: for 11a
6374 */
6375
6376 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
6377 if (NL80211_CHAN_WIDTH_80P80 == chandef->width)
6378 channel_seg2 = ieee80211_frequency_to_channel(chandef->center_freq2);
6379 else
6380 channel_seg2 = 0;
6381
6382 /* Check freq range */
6383 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6384 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
6385 hddLog(LOGE,
6386 FL("Channel [%d] is outside valid range from %d to %d"),
6387 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6388 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6389 return -EINVAL;
6390 }
6391
6392 /* Check freq range */
6393
6394 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
6395 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
6396 hddLog(LOGE,
6397 FL("Channel [%d] is outside valid range from %d to %d"),
6398 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6399 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6400 return -EINVAL;
6401 }
6402
6403 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6404
6405 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6406 (WLAN_HDD_P2P_GO != pAdapter->device_mode)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306407 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006408 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
6409 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
6410 return -EINVAL;
6411 }
6412 hddLog(LOG2,
6413 FL("set channel to [%d] for device mode %s(%d)"),
6414 channel,
6415 hdd_device_mode_to_string(pAdapter->device_mode),
6416 pAdapter->device_mode);
6417 }
6418
6419 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6420 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6421 ) {
6422 hdd_wext_state_t *pWextState =
6423 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6424 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
6425 hdd_station_ctx_t *pHddStaCtx =
6426 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6427
6428 if (eConnectionState_IbssConnected ==
6429 pHddStaCtx->conn_info.connState) {
6430 /* Link is up then return cant set channel */
6431 hddLog(LOGE,
6432 FL("IBSS Associated, can't set the channel"));
6433 return -EINVAL;
6434 }
6435
6436 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6437 pHddStaCtx->conn_info.operationChannel = channel;
6438 pRoamProfile->ChannelInfo.ChannelList =
6439 &pHddStaCtx->conn_info.operationChannel;
6440 } else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6441 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
6442 ) {
6443 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig);
6444 if (WLAN_HDD_P2P_GO == pAdapter->device_mode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306445 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006446 wlan_hdd_validate_operation_channel(pAdapter,
6447 channel)) {
6448 hddLog(LOGE,
6449 FL("Invalid Channel [%d]"), channel);
6450 return -EINVAL;
6451 }
6452 sap_config->channel = channel;
6453 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6454 } else {
6455 /* set channel to what hostapd configured */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306456 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006457 wlan_hdd_validate_operation_channel(pAdapter,
6458 channel)) {
6459 hddLog(LOGE,
6460 FL("Invalid Channel [%d]"), channel);
6461 return -EINVAL;
6462 }
6463
6464 sap_config->channel = channel;
6465 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6466
6467 cdf_mem_zero(&smeConfig, sizeof(smeConfig));
6468 sme_get_config_param(pHddCtx->hHal, &smeConfig);
6469 switch (channel_type) {
6470 case NL80211_CHAN_HT20:
6471 case NL80211_CHAN_NO_HT:
6472 smeConfig.csrConfig.obssEnabled = false;
6473 if (channel <= 14)
6474 smeConfig.csrConfig.
6475 channelBondingMode24GHz =
6476 eCSR_INI_SINGLE_CHANNEL_CENTERED;
6477 else
6478 smeConfig.csrConfig.
6479 channelBondingMode5GHz =
6480 eCSR_INI_SINGLE_CHANNEL_CENTERED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006481 sap_config->sec_ch = 0;
6482 break;
6483
6484 case NL80211_CHAN_HT40MINUS:
6485 if (channel <= 14)
6486 smeConfig.csrConfig.
6487 channelBondingMode24GHz =
6488 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6489 else
6490 smeConfig.csrConfig.
6491 channelBondingMode5GHz =
6492 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6493 sap_config->sec_ch = sap_config->channel - 4;
6494 break;
6495 case NL80211_CHAN_HT40PLUS:
6496 if (channel <= 14)
6497 smeConfig.csrConfig.
6498 channelBondingMode24GHz =
6499 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6500 else
6501 smeConfig.csrConfig.
6502 channelBondingMode5GHz =
6503 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6504 sap_config->sec_ch = sap_config->channel + 4;
6505 break;
6506 default:
6507 hddLog(LOGE,
6508 FL("Error!!! Invalid HT20/40 mode !"));
6509 return -EINVAL;
6510 }
6511 smeConfig.csrConfig.obssEnabled = wlan_hdd_get_sap_obss(
6512 pAdapter);
6513 sme_update_config(pHddCtx->hHal, &smeConfig);
6514 }
6515 } else {
6516 hddLog(LOGE,
6517 FL("Invalid device mode failed to set valid channel"));
6518 return -EINVAL;
6519 }
6520 EXIT();
6521 return status;
6522}
6523
6524/**
6525 * wlan_hdd_check_11gmode() - check for 11g mode
6526 * @pIe: Pointer to IE
6527 * @require_ht: Pointer to require ht
6528 * @require_vht: Pointer to require vht
6529 * @pCheckRatesfor11g: Pointer to check rates for 11g mode
6530 * @pSapHw_mode: SAP HW mode
6531 *
6532 * Check for 11g rate and set proper 11g only mode
6533 *
6534 * Return: none
6535 */
6536static void wlan_hdd_check_11gmode(u8 *pIe, u8 *require_ht, u8 *require_vht,
6537 u8 *pCheckRatesfor11g,
6538 eCsrPhyMode *pSapHw_mode)
6539{
6540 u8 i, num_rates = pIe[0];
6541
6542 pIe += 1;
6543 for (i = 0; i < num_rates; i++) {
6544 if (*pCheckRatesfor11g
6545 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
6546 /* If rate set have 11g rate than change the mode
6547 * to 11G
6548 */
6549 *pSapHw_mode = eCSR_DOT11_MODE_11g;
6550 if (pIe[i] & BASIC_RATE_MASK) {
6551 /* If we have 11g rate as basic rate, it
6552 * means mode is 11g only mode.
6553 */
6554 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
6555 *pCheckRatesfor11g = false;
6556 }
6557 } else {
6558 if ((BASIC_RATE_MASK |
6559 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6560 *require_ht = true;
6561 else if ((BASIC_RATE_MASK |
6562 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
6563 *require_vht = true;
6564 }
6565 }
6566 return;
6567}
6568
6569/**
6570 * wlan_hdd_add_ie() - add ie
6571 * @pHostapdAdapter: Pointer to hostapd adapter
6572 * @genie: Pointer to ie to be added
6573 * @total_ielen: Pointer to store total ie length
6574 * @oui: Pointer to oui
6575 * @oui_size: Size of oui
6576 *
6577 * Return: 0 for success non-zero for failure
6578 */
6579static int wlan_hdd_add_ie(hdd_adapter_t *pHostapdAdapter, uint8_t *genie,
6580 uint8_t *total_ielen, uint8_t *oui,
6581 uint8_t oui_size)
6582{
6583 uint16_t ielen = 0;
6584 uint8_t *pIe = NULL;
6585 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6586
6587 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6588 pBeacon->tail, pBeacon->tail_len);
6589
6590 if (pIe) {
6591 ielen = pIe[1] + 2;
6592 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
6593 cdf_mem_copy(&genie[*total_ielen], pIe, ielen);
6594 } else {
6595 hddLog(LOGE,
6596 "**Ie Length is too big***");
6597 return -EINVAL;
6598 }
6599 *total_ielen += ielen;
6600 }
6601 return 0;
6602}
6603
6604/**
6605 * wlan_hdd_add_hostapd_conf_vsie() - configure vsie in sap mode
6606 * @pHostapdAdapter: Pointer to hostapd adapter
6607 * @genie: Pointer to vsie
6608 * @total_ielen: Pointer to store total ie length
6609 *
6610 * Return: none
6611 */
6612static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t *pHostapdAdapter,
6613 uint8_t *genie,
6614 uint8_t *total_ielen)
6615{
6616 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6617 int left = pBeacon->tail_len;
6618 uint8_t *ptr = pBeacon->tail;
6619 uint8_t elem_id, elem_len;
6620 uint16_t ielen = 0;
6621
6622 if (NULL == ptr || 0 == left)
6623 return;
6624
6625 while (left >= 2) {
6626 elem_id = ptr[0];
6627 elem_len = ptr[1];
6628 left -= 2;
6629 if (elem_len > left) {
6630 hddLog(LOGE,
6631 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6632 elem_id, elem_len, left);
6633 return;
6634 }
6635 if (IE_EID_VENDOR == elem_id) {
6636 /* skipping the VSIE's which we don't want to include or
6637 * it will be included by existing code
6638 */
6639 if ((memcmp(&ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) !=
6640 0) &&
6641#ifdef WLAN_FEATURE_WFD
6642 (memcmp(&ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) !=
6643 0) &&
6644#endif
6645 (memcmp
6646 (&ptr[2], WHITELIST_OUI_TYPE,
6647 WPA_OUI_TYPE_SIZE) != 0)
6648 &&
6649 (memcmp
6650 (&ptr[2], BLACKLIST_OUI_TYPE,
6651 WPA_OUI_TYPE_SIZE) != 0)
6652 &&
6653 (memcmp
6654 (&ptr[2], "\x00\x50\xf2\x02",
6655 WPA_OUI_TYPE_SIZE) != 0)
6656 && (memcmp(&ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE)
6657 != 0)
6658 && (memcmp(&ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)
6659 != 0)) {
6660 ielen = ptr[1] + 2;
6661 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
6662 cdf_mem_copy(&genie[*total_ielen], ptr,
6663 ielen);
6664 *total_ielen += ielen;
6665 } else {
6666 hddLog(LOGE,
6667 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6668 elem_id, elem_len, *total_ielen);
6669 }
6670 }
6671 }
6672
6673 left -= elem_len;
6674 ptr += (elem_len + 2);
6675 }
6676 return;
6677}
6678
6679/**
6680 * wlan_hdd_add_extra_ie() - add extra ies in beacon
6681 * @pHostapdAdapter: Pointer to hostapd adapter
6682 * @genie: Pointer to extra ie
6683 * @total_ielen: Pointer to store total ie length
6684 * @temp_ie_id: ID of extra ie
6685 *
6686 * Return: none
6687 */
6688static void wlan_hdd_add_extra_ie(hdd_adapter_t *pHostapdAdapter,
6689 uint8_t *genie, uint8_t *total_ielen,
6690 uint8_t temp_ie_id)
6691{
6692 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6693 int left = pBeacon->tail_len;
6694 uint8_t *ptr = pBeacon->tail;
6695 uint8_t elem_id, elem_len;
6696 uint16_t ielen = 0;
6697
6698 if (NULL == ptr || 0 == left)
6699 return;
6700
6701 while (left >= 2) {
6702 elem_id = ptr[0];
6703 elem_len = ptr[1];
6704 left -= 2;
6705 if (elem_len > left) {
6706 hddLog(LOGE,
6707 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6708 elem_id, elem_len, left);
6709 return;
6710 }
6711
6712 if (temp_ie_id == elem_id) {
6713 ielen = ptr[1] + 2;
6714 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
6715 cdf_mem_copy(&genie[*total_ielen], ptr, ielen);
6716 *total_ielen += ielen;
6717 } else {
6718 hddLog(LOGE,
6719 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6720 elem_id, elem_len, *total_ielen);
6721 }
6722 }
6723
6724 left -= elem_len;
6725 ptr += (elem_len + 2);
6726 }
6727 return;
6728}
6729
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006730/**
6731 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
6732 * @pAdapter: Pointer to hostapd adapter
6733 * @ppBeacon: Pointer to pointer to beacon data
6734 * @params: Pointer to beacon parameters
6735 * @dtim_period: DTIM period
6736 *
6737 * Return: 0 for success non-zero for failure
6738 */
6739int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
6740 beacon_data_t **ppBeacon,
6741 struct cfg80211_beacon_data *params,
6742 int dtim_period)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006743{
6744 int size;
6745 beacon_data_t *beacon = NULL;
6746 beacon_data_t *old = NULL;
6747 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
6748 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
6749
6750 ENTER();
6751 if (params->head && !params->head_len) {
6752 hddLog(LOGE, FL("head_len is NULL"));
6753 return -EINVAL;
6754 }
6755
6756 old = pAdapter->sessionCtx.ap.beacon;
6757
6758 if (!params->head && !old) {
6759 hddLog(LOGE, FL("session(%d) old and new heads points to NULL"),
6760 pAdapter->sessionId);
6761 return -EINVAL;
6762 }
6763
6764 if (params->head) {
6765 head_len = params->head_len;
6766 head = params->head;
6767 } else {
6768 head_len = old->head_len;
6769 head = old->head;
6770 }
6771
6772 if (params->tail || !old) {
6773 tail_len = params->tail_len;
6774 tail = params->tail;
6775 } else {
6776 tail_len = old->tail_len;
6777 tail = old->tail;
6778 }
6779
6780 if (params->proberesp_ies || !old) {
6781 proberesp_ies_len = params->proberesp_ies_len;
6782 proberesp_ies = params->proberesp_ies;
6783 } else {
6784 proberesp_ies_len = old->proberesp_ies_len;
6785 proberesp_ies = old->proberesp_ies;
6786 }
6787
6788 if (params->assocresp_ies || !old) {
6789 assocresp_ies_len = params->assocresp_ies_len;
6790 assocresp_ies = params->assocresp_ies;
6791 } else {
6792 assocresp_ies_len = old->assocresp_ies_len;
6793 assocresp_ies = old->assocresp_ies;
6794 }
6795
6796 size = sizeof(beacon_data_t) + head_len + tail_len +
6797 proberesp_ies_len + assocresp_ies_len;
6798
6799 beacon = kzalloc(size, GFP_KERNEL);
6800
6801 if (beacon == NULL) {
6802 hddLog(LOGE,
6803 FL("Mem allocation for beacon failed"));
6804 return -ENOMEM;
6805 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006806 if (dtim_period)
6807 beacon->dtim_period = dtim_period;
6808 else if (old)
6809 beacon->dtim_period = old->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006810 /* -----------------------------------------------
6811 * | head | tail | proberesp_ies | assocresp_ies |
6812 * -----------------------------------------------
6813 */
6814 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6815 beacon->tail = beacon->head + head_len;
6816 beacon->proberesp_ies = beacon->tail + tail_len;
6817 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
6818
6819 beacon->head_len = head_len;
6820 beacon->tail_len = tail_len;
6821 beacon->proberesp_ies_len = proberesp_ies_len;
6822 beacon->assocresp_ies_len = assocresp_ies_len;
6823
6824 if (head && head_len)
6825 memcpy(beacon->head, head, head_len);
6826 if (tail && tail_len)
6827 memcpy(beacon->tail, tail, tail_len);
6828 if (proberesp_ies && proberesp_ies_len)
6829 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
6830 if (assocresp_ies && assocresp_ies_len)
6831 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
6832
6833 *ppBeacon = beacon;
6834
6835 kfree(old);
6836
6837 return 0;
6838
6839}
6840
6841/**
6842 * wlan_hdd_cfg80211_update_apies() - update ap mode ies
6843 * @adapter: Pointer to hostapd adapter
6844 *
6845 * Return: 0 for success non-zero for failure
6846 */
6847int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *adapter)
6848{
6849 uint8_t *genie;
6850 uint8_t total_ielen = 0;
6851 int ret = 0;
6852 tsap_Config_t *pConfig;
6853 tSirUpdateIE updateIE;
6854 beacon_data_t *beacon = NULL;
6855
6856 pConfig = &adapter->sessionCtx.ap.sapConfig;
6857 beacon = adapter->sessionCtx.ap.beacon;
6858
6859 genie = cdf_mem_malloc(MAX_GENIE_LEN);
6860
6861 if (genie == NULL)
6862 return -ENOMEM;
6863
6864 if (0 != wlan_hdd_add_ie(adapter, genie,
6865 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) {
6866 hddLog(LOGE, FL("Adding WPS IE failed"));
6867 ret = -EINVAL;
6868 goto done;
6869 }
6870#ifdef WLAN_FEATURE_WFD
6871 if (0 != wlan_hdd_add_ie(adapter, genie,
6872 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) {
6873 hddLog(LOGE, FL("Adding WFD IE failed"));
6874 ret = -EINVAL;
6875 goto done;
6876 }
6877#endif
6878
6879#ifdef FEATURE_WLAN_WAPI
6880 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6881 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6882 WLAN_EID_WAPI);
6883 }
6884#endif
6885
6886 if (adapter->device_mode == WLAN_HDD_SOFTAP ||
6887 adapter->device_mode == WLAN_HDD_P2P_GO)
6888 wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
6889 &total_ielen);
6890
6891 if (wlan_hdd_add_ie(adapter, genie,
6892 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0) {
6893 hddLog(LOGE, FL("Adding P2P IE failed"));
6894 ret = -EINVAL;
6895 goto done;
6896 }
6897
6898#ifdef QCA_HT_2040_COEX
6899 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6900 tSmeConfigParams smeConfig;
6901 cdf_mem_zero(&smeConfig, sizeof(smeConfig));
6902 sme_get_config_param(WLAN_HDD_GET_HAL_CTX(adapter),
6903 &smeConfig);
6904 if (smeConfig.csrConfig.obssEnabled)
6905 wlan_hdd_add_extra_ie(adapter, genie,
6906 &total_ielen,
6907 WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
6908 }
6909#endif
Srinivas Girigowda8b983962015-11-18 22:14:34 -08006910 cdf_copy_macaddr(&updateIE.bssid, &adapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006911 updateIE.smeSessionId = adapter->sessionId;
6912
6913 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6914 updateIE.ieBufferlength = total_ielen;
6915 updateIE.pAdditionIEBuffer = genie;
6916 updateIE.append = false;
6917 updateIE.notify = true;
6918 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6919 &updateIE,
6920 eUPDATE_IE_PROBE_BCN) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306921 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006922 hddLog(LOGE,
6923 FL("Could not pass on Add Ie probe beacon data"));
6924 ret = -EINVAL;
6925 goto done;
6926 }
6927 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
6928 } else {
6929 wlansap_update_sap_config_add_ie(pConfig,
6930 genie,
6931 total_ielen,
6932 eUPDATE_IE_PROBE_BCN);
6933 }
6934
6935 /* Added for Probe Response IE */
6936 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6937 updateIE.ieBufferlength = beacon->proberesp_ies_len;
6938 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->proberesp_ies;
6939 updateIE.append = false;
6940 updateIE.notify = false;
6941 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6942 &updateIE,
6943 eUPDATE_IE_PROBE_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306944 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006945 hddLog(LOGE,
6946 FL("Could not pass on PROBE_RESP add Ie data"));
6947 ret = -EINVAL;
6948 goto done;
6949 }
6950 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
6951 } else {
6952 wlansap_update_sap_config_add_ie(pConfig,
6953 beacon->proberesp_ies,
6954 beacon->proberesp_ies_len,
6955 eUPDATE_IE_PROBE_RESP);
6956 }
6957
6958 /* Assoc resp Add ie Data */
6959 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6960 updateIE.ieBufferlength = beacon->assocresp_ies_len;
6961 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
6962 updateIE.append = false;
6963 updateIE.notify = false;
6964 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6965 &updateIE,
6966 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306967 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006968 hddLog(LOGE,
6969 FL("Could not pass on Add Ie Assoc Response data"));
6970 ret = -EINVAL;
6971 goto done;
6972 }
6973 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
6974 } else {
6975 wlansap_update_sap_config_add_ie(pConfig,
6976 beacon->assocresp_ies,
6977 beacon->assocresp_ies_len,
6978 eUPDATE_IE_ASSOC_RESP);
6979 }
6980
6981done:
6982 cdf_mem_free(genie);
6983 return ret;
6984}
6985
6986/**
6987 * wlan_hdd_set_sap_hwmode() - set sap hw mode
6988 * @pHostapdAdapter: Pointer to hostapd adapter
6989 *
6990 * Return: none
6991 */
6992static void wlan_hdd_set_sap_hwmode(hdd_adapter_t *pHostapdAdapter)
6993{
6994 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6995 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6996 struct ieee80211_mgmt *pMgmt_frame =
6997 (struct ieee80211_mgmt *)pBeacon->head;
6998 u8 checkRatesfor11g = true;
6999 u8 require_ht = false, require_vht = false;
7000 u8 *pIe = NULL;
7001
7002 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
7003
7004 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7005 pBeacon->head_len,
7006 WLAN_EID_SUPP_RATES);
7007 if (pIe != NULL) {
7008 pIe += 1;
7009 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
7010 &checkRatesfor11g, &pConfig->SapHw_mode);
7011 }
7012
7013 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7014 WLAN_EID_EXT_SUPP_RATES);
7015 if (pIe != NULL) {
7016 pIe += 1;
7017 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
7018 &checkRatesfor11g, &pConfig->SapHw_mode);
7019 }
7020
7021 if (pConfig->channel > 14)
7022 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
7023
7024 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7025 WLAN_EID_HT_CAPABILITY);
7026
7027 if (pIe) {
7028 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
7029 if (require_ht)
7030 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
7031 }
7032
7033 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7034 WLAN_EID_VHT_CAPABILITY);
7035
7036 if (pIe) {
7037 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
7038 if (require_vht)
7039 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
7040 }
7041}
7042
7043/**
7044 * wlan_hdd_config_acs() - config ACS needed parameters
7045 * @hdd_ctx: HDD context
7046 * @adapter: Adapter pointer
7047 *
7048 * This function get ACS related INI paramters and populated
7049 * sap config and smeConfig for ACS needed configurations.
7050 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307051 * Return: The QDF_STATUS code associated with performing the operation.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007052 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307053QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007054{
7055 tsap_Config_t *sap_config;
7056 struct hdd_config *ini_config;
7057 tHalHandle hal;
7058
7059 hal = WLAN_HDD_GET_HAL_CTX(adapter);
7060 sap_config = &adapter->sessionCtx.ap.sapConfig;
7061 ini_config = hdd_ctx->config;
7062
7063 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
7064
7065#if defined(WLAN_FEATURE_MBSSID) && defined(FEATURE_WLAN_AP_AP_ACS_OPTIMIZE)
7066 hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"),
7067 hdd_ctx->skip_acs_scan_status);
7068 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
7069 hdd_adapter_t *con_sap_adapter;
7070 tsap_Config_t *con_sap_config = NULL;
7071
7072 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
7073
7074 if (con_sap_adapter)
7075 con_sap_config =
7076 &con_sap_adapter->sessionCtx.ap.sapConfig;
7077
7078 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
7079
7080 if (con_sap_config &&
7081 con_sap_config->acs_cfg.acs_mode == true &&
7082 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
7083 con_sap_config->acs_cfg.hw_mode ==
7084 sap_config->acs_cfg.hw_mode) {
7085 uint8_t con_sap_st_ch, con_sap_end_ch;
7086 uint8_t cur_sap_st_ch, cur_sap_end_ch;
7087 uint8_t bandStartChannel, bandEndChannel;
7088
7089 con_sap_st_ch =
7090 con_sap_config->acs_cfg.start_ch;
7091 con_sap_end_ch =
7092 con_sap_config->acs_cfg.end_ch;
7093 cur_sap_st_ch = sap_config->acs_cfg.start_ch;
7094 cur_sap_end_ch = sap_config->acs_cfg.end_ch;
7095
7096 wlansap_extend_to_acs_range(
7097 &cur_sap_st_ch, &cur_sap_end_ch,
7098 &bandStartChannel, &bandEndChannel);
7099
7100 wlansap_extend_to_acs_range(
7101 &con_sap_st_ch, &con_sap_end_ch,
7102 &bandStartChannel, &bandEndChannel);
7103
7104 if (con_sap_st_ch <= cur_sap_st_ch &&
7105 con_sap_end_ch >= cur_sap_end_ch) {
7106 sap_config->acs_cfg.skip_scan_status =
7107 eSAP_SKIP_ACS_SCAN;
7108
7109 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7110 con_sap_end_ch >= cur_sap_end_ch) {
7111 sap_config->acs_cfg.skip_scan_status =
7112 eSAP_DO_PAR_ACS_SCAN;
7113
7114 sap_config->acs_cfg.skip_scan_range1_stch =
7115 cur_sap_st_ch;
7116 sap_config->acs_cfg.skip_scan_range1_endch =
7117 con_sap_st_ch - 1;
7118 sap_config->acs_cfg.skip_scan_range2_stch =
7119 0;
7120 sap_config->acs_cfg.skip_scan_range2_endch =
7121 0;
7122
7123 } else if (con_sap_st_ch <= cur_sap_st_ch &&
7124 con_sap_end_ch <= cur_sap_end_ch) {
7125 sap_config->acs_cfg.skip_scan_status =
7126 eSAP_DO_PAR_ACS_SCAN;
7127
7128 sap_config->acs_cfg.skip_scan_range1_stch =
7129 con_sap_end_ch + 1;
7130 sap_config->acs_cfg.skip_scan_range1_endch =
7131 cur_sap_end_ch;
7132 sap_config->acs_cfg.skip_scan_range2_stch =
7133 0;
7134 sap_config->acs_cfg.skip_scan_range2_endch =
7135 0;
7136
7137 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7138 con_sap_end_ch <= cur_sap_end_ch) {
7139 sap_config->acs_cfg.skip_scan_status =
7140 eSAP_DO_PAR_ACS_SCAN;
7141
7142 sap_config->acs_cfg.skip_scan_range1_stch =
7143 cur_sap_st_ch;
7144 sap_config->acs_cfg.skip_scan_range1_endch =
7145 con_sap_st_ch - 1;
7146 sap_config->acs_cfg.skip_scan_range2_stch =
7147 con_sap_end_ch;
7148 sap_config->acs_cfg.skip_scan_range2_endch =
7149 cur_sap_end_ch + 1;
7150
7151 } else
7152 sap_config->acs_cfg.skip_scan_status =
7153 eSAP_DO_NEW_ACS_SCAN;
7154
7155
7156 hddLog(LOG1, FL(
7157 "SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d"),
7158 sap_config->acs_cfg.skip_scan_status,
7159 sap_config->acs_cfg.skip_scan_range1_stch,
7160 sap_config->acs_cfg.skip_scan_range1_endch,
7161 sap_config->acs_cfg.skip_scan_range2_stch,
7162 sap_config->acs_cfg.skip_scan_range2_endch);
7163 }
7164 }
7165#endif
7166
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307167 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007168}
7169
7170/**
7171 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
7172 * @adapter: pointer to adapter struct
7173 *
7174 * This function overrides SAP / P2P Go configuration based on driver INI
7175 * parameters for 11AC override and ACS. This overrides are done to support
7176 * android legacy configuration method.
7177 *
7178 * NOTE: Non android platform supports concurrency and these overrides shall
7179 * not be used. Also future driver based overrides shall be consolidated in this
7180 * function only. Avoid random overrides in other location based on ini.
7181 *
7182 * Return: 0 for Success or Negative error codes.
7183 */
7184int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
7185{
7186 tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
7187 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
7188 tHalHandle h_hal = WLAN_HDD_GET_HAL_CTX(ap_adapter);
7189
7190 if (ap_adapter->device_mode == WLAN_HDD_SOFTAP &&
7191 hdd_ctx->config->force_sap_acs)
7192 goto setup_acs_overrides;
7193
7194 /* Fixed channel 11AC override:
7195 * 11AC override in qcacld is introduced for following reasons:
7196 * 1. P2P GO also follows start_bss and since p2p GO could not be
7197 * configured to setup VHT channel width in wpa_supplicant
7198 * 2. Android UI does not provide advanced configuration options for SAP
7199 *
7200 * Default override enabled (for android). MDM shall disable this in ini
7201 */
7202 if (hdd_ctx->config->sap_p2p_11ac_override &&
7203 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7204 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7205 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)) {
7206 hddLog(LOG1, FL("** Driver force 11AC override for SAP/Go **"));
7207
7208 /* 11n only shall not be overridden since it may be on purpose*/
7209 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
7210 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7211
7212 if (sap_cfg->channel >= 36)
7213 sap_cfg->ch_width_orig =
7214 hdd_ctx->config->vhtChannelWidth;
7215 else
7216 sap_cfg->ch_width_orig =
7217 hdd_ctx->config->nChannelBondingMode24GHz ?
7218 eHT_CHANNEL_WIDTH_40MHZ :
7219 eHT_CHANNEL_WIDTH_20MHZ;
7220 }
7221 sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
7222 sme_set_ch_params(h_hal, sap_cfg->SapHw_mode, sap_cfg->channel,
7223 sap_cfg->sec_ch, &sap_cfg->ch_params);
7224
7225 return 0;
7226
7227setup_acs_overrides:
7228 hddLog(LOGE, FL("** Driver force ACS override **"));
7229
7230 sap_cfg->channel = AUTO_CHANNEL_SELECT;
7231 sap_cfg->acs_cfg.acs_mode = true;
7232 sap_cfg->acs_cfg.start_ch = hdd_ctx->config->force_sap_acs_st_ch;
7233 sap_cfg->acs_cfg.end_ch = hdd_ctx->config->force_sap_acs_end_ch;
7234
7235 if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.end_ch) {
7236 hddLog(LOGE, FL("Driver force ACS start ch (%d) > end ch (%d)"),
7237 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7238 return -EINVAL;
7239 }
7240
7241 /* Derive ACS HW mode */
7242 sap_cfg->SapHw_mode = hdd_cfg_xlate_to_csr_phy_mode(
7243 hdd_ctx->config->dot11Mode);
7244 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_AUTO)
7245 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7246
7247 if ((sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11b ||
7248 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g ||
7249 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
7250 sap_cfg->acs_cfg.start_ch > 14) {
7251 hddLog(LOGE, FL("Invalid ACS HW Mode %d + CH range <%d - %d>"),
7252 sap_cfg->SapHw_mode, sap_cfg->acs_cfg.start_ch,
7253 sap_cfg->acs_cfg.end_ch);
7254 return -EINVAL;
7255 }
7256 sap_cfg->acs_cfg.hw_mode = sap_cfg->SapHw_mode;
7257
7258 /* Derive ACS BW */
7259 sap_cfg->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
7260 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7261 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) {
7262
7263 sap_cfg->ch_width_orig = hdd_ctx->config->vhtChannelWidth;
7264 /* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
7265 if (sap_cfg->acs_cfg.end_ch <= 14)
7266 sap_cfg->ch_width_orig =
7267 hdd_ctx->config->nChannelBondingMode24GHz ?
7268 eHT_CHANNEL_WIDTH_40MHZ :
7269 eHT_CHANNEL_WIDTH_20MHZ;
7270 }
7271
7272 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7273 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY) {
7274 if (sap_cfg->acs_cfg.end_ch <= 14)
7275 sap_cfg->ch_width_orig =
7276 hdd_ctx->config->nChannelBondingMode24GHz ?
7277 eHT_CHANNEL_WIDTH_40MHZ :
7278 eHT_CHANNEL_WIDTH_20MHZ;
7279 else
7280 sap_cfg->ch_width_orig =
7281 hdd_ctx->config->nChannelBondingMode5GHz ?
7282 eHT_CHANNEL_WIDTH_40MHZ :
7283 eHT_CHANNEL_WIDTH_20MHZ;
7284 }
7285 sap_cfg->acs_cfg.ch_width = sap_cfg->ch_width_orig;
7286
7287 hddLog(LOG1, FL("Force ACS Config: HW_MODE: %d ACS_BW: %d"),
7288 sap_cfg->acs_cfg.hw_mode, sap_cfg->acs_cfg.ch_width);
7289 hddLog(LOG1, FL("Force ACS Config: ST_CH: %d END_CH: %d"),
7290 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7291
7292 return 0;
7293}
7294
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007295/**
7296 * wlan_hdd_cfg80211_start_bss() - start bss
7297 * @pHostapdAdapter: Pointer to hostapd adapter
7298 * @params: Pointer to start bss beacon parameters
7299 * @ssid: Pointer ssid
7300 * @ssid_len: Length of ssid
7301 * @hidden_ssid: Hidden SSID parameter
7302 *
7303 * Return: 0 for success non-zero for failure
7304 */
7305static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7306 struct cfg80211_beacon_data *params,
7307 const u8 *ssid, size_t ssid_len,
7308 enum nl80211_hidden_ssid hidden_ssid)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007309{
7310 tsap_Config_t *pConfig;
7311 beacon_data_t *pBeacon = NULL;
7312 struct ieee80211_mgmt *pMgmt_frame;
7313 uint8_t *pIe = NULL;
7314 uint16_t capab_info;
7315 eCsrAuthType RSNAuthType;
7316 eCsrEncryptionType RSNEncryptType;
7317 eCsrEncryptionType mcRSNEncryptType;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307318 int status = QDF_STATUS_SUCCESS, ret;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307319 int qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007320 tpWLAN_SAPEventCB pSapEventCallback;
7321 hdd_hostapd_state_t *pHostapdState;
7322#ifndef WLAN_FEATURE_MBSSID
7323 v_CONTEXT_t p_cds_context =
7324 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
7325#endif
7326 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
7327 struct qc_mac_acl_entry *acl_entry = NULL;
7328 int32_t i;
7329 struct hdd_config *iniConfig;
7330 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
7331 tSmeConfigParams sme_config;
7332 bool MFPCapable = false;
7333 bool MFPRequired = false;
7334 uint16_t prev_rsn_length = 0;
7335 ENTER();
7336
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007337 if (cds_is_connection_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007338 hdd_err("Can't start BSS: connection is in progress");
7339 return -EINVAL;
7340 }
7341
7342 iniConfig = pHddCtx->config;
7343 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7344
7345 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
7346 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
7347
7348 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7349
7350 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7351
7352 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
7353
7354 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7355
7356 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
7357
7358 /* channel is already set in the set_channel Call back */
7359 /* pConfig->channel = pCommitConfig->channel; */
7360
7361 /* Protection parameter to enable or disable */
7362 pConfig->protEnabled = iniConfig->apProtEnabled;
7363
7364 pConfig->dtim_period = pBeacon->dtim_period;
7365
7366 hddLog(LOG2, FL("****pConfig->dtim_period=%d***"),
7367 pConfig->dtim_period);
7368
7369 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
7370 pIe =
7371 wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail,
7372 pBeacon->tail_len,
7373 WLAN_EID_COUNTRY);
7374 if (pIe) {
7375 pConfig->ieee80211d = 1;
7376 cdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
7377 sme_set_reg_info(hHal, pConfig->countryCode);
7378 sme_apply_channel_power_info_to_fw(hHal);
7379 } else {
7380 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7381 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7382 pConfig->ieee80211d = 0;
7383 }
7384
7385 ret = wlan_hdd_sap_cfg_dfs_override(pHostapdAdapter);
7386 if (ret < 0) {
7387 return ret;
7388 } else {
7389 if (ret == 0) {
7390 if (CDS_IS_DFS_CH(pConfig->channel))
7391 pHddCtx->dev_dfs_cac_status =
7392 DFS_CAC_NEVER_DONE;
7393 }
7394 }
7395
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307396 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007397 wlan_hdd_validate_operation_channel(pHostapdAdapter,
7398 pConfig->channel)) {
7399 hddLog(LOGE, FL("Invalid Channel [%d]"),
7400 pConfig->channel);
7401 return -EINVAL;
7402 }
7403
7404 /* reject SAP if DFS channel scan is not allowed */
7405 if (!(pHddCtx->config->enableDFSChnlScan) &&
7406 (CHANNEL_STATE_DFS == cds_get_channel_state(
7407 pConfig->channel))) {
7408 hddLog(LOGE,
7409 FL("not allowed to start SAP on DFS channel"));
7410 return -EOPNOTSUPP;
7411 }
7412 wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC);
7413 wlansap_set_dfs_restrict_japan_w53(hHal,
7414 iniConfig->gDisableDfsJapanW53);
7415 wlansap_set_dfs_preferred_channel_location(hHal,
7416 iniConfig->gSapPreferredChanLocation);
7417#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
7418 wlan_sap_set_channel_avoidance(hHal,
7419 iniConfig->sap_channel_avoidance);
7420#endif
7421 } else if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7422 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7423 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7424 pConfig->ieee80211d = 0;
7425 } else {
7426 pConfig->ieee80211d = 0;
7427 }
7428
7429 capab_info = pMgmt_frame->u.beacon.capab_info;
7430
7431 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
7432 WLAN_CAPABILITY_PRIVACY) ? true : false;
7433
7434 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7435
7436 /*Set wps station to configured */
7437 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7438
7439 if (pIe) {
7440 if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) {
7441 hddLog(LOGE,
7442 FL("**Wps Ie Length is too small***"));
7443 return -EINVAL;
7444 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
7445 0) {
7446 hddLog(LOG1, FL("** WPS IE(len %d) ***"), (pIe[1] + 2));
7447 /* Check 15 bit of WPS IE as it contain information for
7448 * wps state
7449 */
7450 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
7451 pConfig->wps_state =
7452 SAP_WPS_ENABLED_UNCONFIGURED;
7453 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
7454 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7455 }
7456 }
7457 } else {
7458 hdd_info("WPS disabled");
7459 pConfig->wps_state = SAP_WPS_DISABLED;
7460 }
7461 /* Forward WPS PBC probe request frame up */
7462 pConfig->fwdWPSPBCProbeReq = 1;
7463
7464 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7465 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7466 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7467 eCSR_ENCRYPT_TYPE_NONE;
7468
7469 pConfig->RSNWPAReqIELength = 0;
7470 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
7471 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7472 WLAN_EID_RSN);
7473 if (pIe && pIe[1]) {
7474 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7475 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
7476 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7477 pConfig->RSNWPAReqIELength);
7478 else
7479 hddLog(LOGE,
7480 FL("RSNWPA IE MAX Length exceeded; length =%d"),
7481 pConfig->RSNWPAReqIELength);
7482 /* The actual processing may eventually be more extensive than
7483 * this. Right now, just consume any PMKIDs that are sent in
7484 * by the app.
7485 * */
7486 status =
7487 hdd_softap_unpack_ie(cds_get_context
7488 (CDF_MODULE_ID_SME),
7489 &RSNEncryptType, &mcRSNEncryptType,
7490 &RSNAuthType, &MFPCapable,
7491 &MFPRequired,
7492 pConfig->RSNWPAReqIE[1] + 2,
7493 pConfig->RSNWPAReqIE);
7494
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307495 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007496 /* Now copy over all the security attributes you have
7497 * parsed out. Use the cipher type in the RSN IE
7498 */
7499 pConfig->RSNEncryptType = RSNEncryptType;
7500 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7501 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7502 ucEncryptType = RSNEncryptType;
7503 hddLog(LOG1,
7504 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7505 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7506 }
7507 }
7508
7509 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7510 pBeacon->tail, pBeacon->tail_len);
7511
7512 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
7513 if (pConfig->RSNWPAReqIE[0]) {
7514 /*Mixed mode WPA/WPA2 */
7515 prev_rsn_length = pConfig->RSNWPAReqIELength;
7516 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7517 if (pConfig->RSNWPAReqIELength <
7518 sizeof(pConfig->RSNWPAReqIE))
7519 memcpy(&pConfig->RSNWPAReqIE[0] +
7520 prev_rsn_length, pIe, pIe[1] + 2);
7521 else
7522 hddLog(LOGE,
7523 "RSNWPA IE MAX Length exceeded; length =%d",
7524 pConfig->RSNWPAReqIELength);
7525 } else {
7526 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7527 if (pConfig->RSNWPAReqIELength <
7528 sizeof(pConfig->RSNWPAReqIE))
7529 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7530 pConfig->RSNWPAReqIELength);
7531 else
7532 hddLog(LOGE,
7533 "RSNWPA IE MAX Length exceeded; length =%d",
7534 pConfig->RSNWPAReqIELength);
7535 status = hdd_softap_unpack_ie
7536 (cds_get_context(CDF_MODULE_ID_SME),
7537 &RSNEncryptType,
7538 &mcRSNEncryptType, &RSNAuthType,
7539 &MFPCapable, &MFPRequired,
7540 pConfig->RSNWPAReqIE[1] + 2,
7541 pConfig->RSNWPAReqIE);
7542
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307543 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007544 /* Now copy over all the security attributes
7545 * you have parsed out. Use the cipher type
7546 * in the RSN IE
7547 */
7548 pConfig->RSNEncryptType = RSNEncryptType;
7549 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7550 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7551 ucEncryptType = RSNEncryptType;
7552 hddLog(LOG1,
7553 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7554 RSNAuthType, RSNEncryptType,
7555 mcRSNEncryptType);
7556 }
7557 }
7558 }
7559
7560 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
7561 hddLog(LOGE,
7562 FL("**RSNWPAReqIELength is too large***"));
7563 return -EINVAL;
7564 }
7565
7566 pConfig->SSIDinfo.ssidHidden = false;
7567
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007568 if (ssid != NULL) {
7569 cdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7570 pConfig->SSIDinfo.ssid.length = ssid_len;
7571
7572 switch (hidden_ssid) {
7573 case NL80211_HIDDEN_SSID_NOT_IN_USE:
7574 hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
7575 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
7576 break;
7577 case NL80211_HIDDEN_SSID_ZERO_LEN:
7578 hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
7579 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
7580 break;
7581 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
7582 hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
7583 pConfig->SSIDinfo.ssidHidden =
7584 eHIDDEN_SSID_ZERO_CONTENTS;
7585 break;
7586 default:
7587 hddLog(LOGE, "Wrong hidden_ssid param %d", hidden_ssid);
7588 break;
7589 }
7590 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007591
7592 cdf_mem_copy(pConfig->self_macaddr.bytes,
7593 pHostapdAdapter->macAddressCurrent.bytes,
7594 CDF_MAC_ADDR_SIZE);
7595
7596 /* default value */
7597 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7598 pConfig->num_accept_mac = 0;
7599 pConfig->num_deny_mac = 0;
7600#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
7601 /*
7602 * We don't want P2PGO to follow STA's channel
7603 * so lets limit the logic for SAP only.
7604 * Later if we decide to make p2pgo follow STA's
7605 * channel then remove this check.
7606 */
7607 if ((0 == pHddCtx->config->conc_custom_rule1) ||
7608 (pHddCtx->config->conc_custom_rule1 &&
7609 WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode))
7610 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
7611#endif
7612
7613 pIe =
7614 wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE,
7615 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7616 pBeacon->tail_len);
7617
7618 /* pIe for black list is following form:
7619 * type : 1 byte
7620 * length : 1 byte
7621 * OUI : 4 bytes
7622 * acl type : 1 byte
7623 * no of mac addr in black list: 1 byte
7624 * list of mac_acl_entries: variable, 6 bytes per mac
7625 * address + sizeof(int) for vlan id
7626 */
7627 if ((pIe != NULL) && (pIe[1] != 0)) {
7628 pConfig->SapMacaddr_acl = pIe[6];
7629 pConfig->num_deny_mac = pIe[7];
7630 hddLog(LOG1,
7631 FL("acl type = %d no deny mac = %d"), pIe[6], pIe[7]);
7632 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7633 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
7634 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7635 for (i = 0; i < pConfig->num_deny_mac; i++) {
7636 cdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr,
7637 sizeof(qcmacaddr));
7638 acl_entry++;
7639 }
7640 }
7641 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE,
7642 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7643 pBeacon->tail_len);
7644
7645 /* pIe for white list is following form:
7646 * type : 1 byte
7647 * length : 1 byte
7648 * OUI : 4 bytes
7649 * acl type : 1 byte
7650 * no of mac addr in white list: 1 byte
7651 * list of mac_acl_entries: variable, 6 bytes per mac
7652 * address + sizeof(int) for vlan id
7653 */
7654 if ((pIe != NULL) && (pIe[1] != 0)) {
7655 pConfig->SapMacaddr_acl = pIe[6];
7656 pConfig->num_accept_mac = pIe[7];
7657 hddLog(LOG1, FL("acl type = %d no accept mac = %d"),
7658 pIe[6], pIe[7]);
7659 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7660 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
7661 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7662 for (i = 0; i < pConfig->num_accept_mac; i++) {
7663 cdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr,
7664 sizeof(qcmacaddr));
7665 acl_entry++;
7666 }
7667 }
7668
7669 wlan_hdd_set_sap_hwmode(pHostapdAdapter);
7670 cdf_mem_zero(&sme_config, sizeof(tSmeConfigParams));
7671 sme_get_config_param(pHddCtx->hHal, &sme_config);
7672 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
7673 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
7674 * may not be good with non QOS 11N AP
7675 * Default: enable QOS for SAP unless WMM IE not present for 11bga
7676 */
7677 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
7678 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
7679 pBeacon->tail, pBeacon->tail_len);
7680 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
7681 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
7682 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
7683 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
7684 sme_update_config(pHddCtx->hHal, &sme_config);
7685
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007686 if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80P80) {
7687 if (pHddCtx->isVHT80Allowed == false)
7688 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7689 else
7690 pConfig->ch_width_orig = CH_WIDTH_80P80MHZ;
7691 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_160) {
7692 if (pHddCtx->isVHT80Allowed == false)
7693 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7694 else
7695 pConfig->ch_width_orig = CH_WIDTH_160MHZ;
7696 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80) {
7697 if (pHddCtx->isVHT80Allowed == false)
7698 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7699 else
7700 pConfig->ch_width_orig = CH_WIDTH_80MHZ;
7701 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40) {
7702 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7703 } else {
7704 pConfig->ch_width_orig = CH_WIDTH_20MHZ;
7705 }
7706
7707 if (wlan_hdd_setup_driver_overrides(pHostapdAdapter))
7708 return -EINVAL;
7709
7710 /* ht_capab is not what the name conveys,this is used for protection
7711 * bitmap */
7712 pConfig->ht_capab = iniConfig->apProtection;
7713
7714 if (0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter)) {
7715 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7716 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7717 return -EINVAL;
7718 }
7719 /* Uapsd Enabled Bit */
7720 pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
7721 /* Enable OBSS protection */
7722 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
7723
7724 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7725 pConfig->sap_dot11mc =
7726 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->sap_dot11mc;
7727 else /* for P2P-Go case */
7728 pConfig->sap_dot11mc = 1;
7729
7730 hddLog(LOG1, FL("11MC Support Enabled : %d\n"),
7731 pConfig->sap_dot11mc);
7732
7733#ifdef WLAN_FEATURE_11W
7734 pConfig->mfpCapable = MFPCapable;
7735 pConfig->mfpRequired = MFPRequired;
7736 hddLog(LOG1, FL("Soft AP MFP capable %d, MFP required %d"),
7737 pConfig->mfpCapable, pConfig->mfpRequired);
7738#endif
7739
7740 hddLog(LOGW, FL("SOftAP macaddress : " MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
7742 hddLog(LOGW, FL("ssid =%s, beaconint=%d, channel=%d"),
7743 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7744 (int)pConfig->channel);
7745 hddLog(LOGW, FL("hw_mode=%x, privacy=%d, authType=%d"),
7746 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
7747 hddLog(LOGW, FL("RSN/WPALen=%d, Uapsd = %d"),
7748 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7749 hddLog(LOGW, FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7750 pConfig->protEnabled, pConfig->obssProtEnabled);
7751
7752 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
7753 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7754 /* Bss already started. just return. */
7755 /* TODO Probably it should update some beacon params. */
7756 hddLog(LOGE, "Bss Already started...Ignore the request");
7757 EXIT();
7758 return 0;
7759 }
7760
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007761 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007762 cds_convert_device_mode_to_hdd_type(
7763 pHostapdAdapter->device_mode),
7764 pConfig->channel, HW_MODE_20_MHZ)) {
7765 hddLog(LOGW,
7766 FL("This concurrency combination is not allowed"));
7767 return -EINVAL;
7768 }
7769
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007770 if (!cds_set_connection_in_progress(true)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007771 hdd_err("Can't start BSS: set connnection in progress failed");
7772 return -EINVAL;
7773 }
7774
7775 pConfig->persona = pHostapdAdapter->device_mode;
7776
7777 pSapEventCallback = hdd_hostapd_sap_event_cb;
7778
7779 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = true;
7780
Anurag Chouhance0dc992016-02-16 18:18:03 +05307781 qdf_event_reset(&pHostapdState->cdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007782 status = wlansap_start_bss(
7783#ifdef WLAN_FEATURE_MBSSID
7784 WLAN_HDD_GET_SAP_CTX_PTR
7785 (pHostapdAdapter),
7786#else
7787 p_cds_context,
7788#endif
7789 pSapEventCallback, pConfig,
7790 pHostapdAdapter->dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307791 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007792 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007793 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007794 hddLog(LOGE, FL("SAP Start Bss fail"));
7795 return -EINVAL;
7796 }
7797
7798 hddLog(LOG1,
7799 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7800
Anurag Chouhance0dc992016-02-16 18:18:03 +05307801 qdf_status = qdf_wait_single_event(&pHostapdState->cdf_event, 10000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007802
7803 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7804
Anurag Chouhance0dc992016-02-16 18:18:03 +05307805 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007806 hddLog(LOGE,
7807 FL("ERROR: HDD cdf wait for single_event failed!!"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007808 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007809 sme_get_command_q_status(hHal);
7810#ifdef WLAN_FEATURE_MBSSID
7811 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
7812#else
7813 wlansap_stop_bss(p_cds_context);
7814#endif
7815 CDF_ASSERT(0);
7816 return -EINVAL;
7817 }
7818 /* Succesfully started Bss update the state bit. */
7819 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
7820 /* Initialize WMM configuation */
7821 hdd_wmm_init(pHostapdAdapter);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007822 cds_incr_active_session(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007823 pHostapdAdapter->sessionId);
7824#ifdef DHCP_SERVER_OFFLOAD
7825 if (iniConfig->enableDHCPServerOffload)
7826 wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
7827#endif /* DHCP_SERVER_OFFLOAD */
7828
7829#ifdef WLAN_FEATURE_P2P_DEBUG
7830 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7831 if (global_p2p_connection_status == P2P_GO_NEG_COMPLETED) {
7832 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7833 hddLog(LOGE,
7834 FL("[P2P State] From Go nego completed to Non-autonomous Group started"));
7835 } else if (global_p2p_connection_status == P2P_NOT_ACTIVE) {
7836 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7837 hddLog(LOGE,
7838 FL("[P2P State] From Inactive to Autonomous Group started"));
7839 }
7840 }
7841#endif
7842
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007843 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007844 pHostapdState->bCommit = true;
7845 EXIT();
7846
7847 return 0;
7848}
7849
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007850/**
7851 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
7852 * @wiphy: Pointer to wiphy structure
7853 * @dev: Pointer to net_device structure
7854 *
7855 * Return: 0 for success non-zero for failure
7856 */
7857static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7858 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007859{
7860 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7861 hdd_context_t *pHddCtx = NULL;
7862 hdd_scaninfo_t *pScanInfo = NULL;
7863 hdd_adapter_t *staAdapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307864 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307865 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007866 tSirUpdateIE updateIE;
7867 beacon_data_t *old;
7868 int ret;
7869 unsigned long rc;
7870 hdd_adapter_list_node_t *pAdapterNode = NULL;
7871 hdd_adapter_list_node_t *pNext = NULL;
7872
7873 ENTER();
7874
Peng Xuf5d60c82015-10-02 17:17:03 -07007875 if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007876 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7877 return -EINVAL;
7878 }
7879
7880 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
7881 TRACE_CODE_HDD_CFG80211_STOP_AP,
7882 pAdapter->sessionId, pAdapter->device_mode));
7883
7884 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7885 ret = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307886 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007887 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007888
7889 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
7890 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
7891 return -EOPNOTSUPP;
7892 }
7893
7894 hddLog(LOG1, FL("Device_mode %s(%d)"),
7895 hdd_device_mode_to_string(pAdapter->device_mode),
7896 pAdapter->device_mode);
7897
7898 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307899 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007900 staAdapter = pAdapterNode->pAdapter;
7901
7902 if (WLAN_HDD_INFRA_STATION == staAdapter->device_mode ||
7903 (WLAN_HDD_P2P_CLIENT == staAdapter->device_mode) ||
7904 (WLAN_HDD_P2P_GO == staAdapter->device_mode)) {
7905 pScanInfo = &staAdapter->scan_info;
7906
7907 if (pScanInfo && pScanInfo->mScanPending) {
7908 hddLog(LOG1, FL("Aborting pending scan for device mode:%d"),
7909 staAdapter->device_mode);
7910 INIT_COMPLETION(pScanInfo->abortscan_event_var);
7911 hdd_abort_mac_scan(staAdapter->pHddCtx,
7912 staAdapter->sessionId,
7913 eCSR_SCAN_ABORT_DEFAULT);
7914 rc = wait_for_completion_timeout(
7915 &pScanInfo->abortscan_event_var,
7916 msecs_to_jiffies(
7917 WLAN_WAIT_TIME_ABORTSCAN));
7918 if (!rc) {
7919 hddLog(LOGE,
7920 FL("Timeout occurred while waiting for abortscan"));
7921 CDF_ASSERT(pScanInfo->mScanPending);
7922 }
7923 }
7924 }
7925
7926 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
7927 pAdapterNode = pNext;
7928 }
7929 /*
7930 * When ever stop ap adapter gets called, we need to check
7931 * whether any restart AP work is pending. If any restart is pending
7932 * then lets finish it and go ahead from there.
7933 */
7934 if (pHddCtx->config->conc_custom_rule1 &&
7935 (WLAN_HDD_SOFTAP == pAdapter->device_mode)) {
7936 cds_flush_work(&pHddCtx->sap_start_work);
7937 hddLog(LOGW, FL("Canceled the pending restart work"));
7938 spin_lock(&pHddCtx->sap_update_info_lock);
7939 pHddCtx->is_sap_restart_required = false;
7940 spin_unlock(&pHddCtx->sap_update_info_lock);
7941 }
7942 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
7943 if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list)
7944 cdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
7945 cdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
7946 sizeof(struct sap_acs_cfg));
7947 hdd_hostapd_stop(dev);
7948
7949 old = pAdapter->sessionCtx.ap.beacon;
7950 if (!old) {
7951 hddLog(LOGE,
7952 FL("Session(%d) beacon data points to NULL"),
7953 pAdapter->sessionId);
7954 return -EINVAL;
7955 }
7956
7957 hdd_cleanup_actionframe(pHddCtx, pAdapter);
7958
7959 mutex_lock(&pHddCtx->sap_lock);
7960 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) {
7961 hdd_hostapd_state_t *pHostapdState =
7962 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7963
Anurag Chouhance0dc992016-02-16 18:18:03 +05307964 qdf_event_reset(&pHostapdState->cdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007965#ifdef WLAN_FEATURE_MBSSID
7966 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter));
7967#else
7968 status = wlansap_stop_bss(pHddCtx->pcds_context);
7969#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307970 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05307971 qdf_status =
7972 qdf_wait_single_event(&pHostapdState->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007973 cdf_stop_bss_event,
7974 10000);
7975
Anurag Chouhance0dc992016-02-16 18:18:03 +05307976 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007977 hddLog(LOGE,
7978 FL("HDD cdf wait for single_event failed!!"));
7979 CDF_ASSERT(0);
7980 }
7981 }
7982 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7983 /*BSS stopped, clear the active sessions for this device mode*/
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08007984 cds_decr_session_set_pcl(pAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007985 pAdapter->sessionId);
7986 pAdapter->sessionCtx.ap.beacon = NULL;
7987 kfree(old);
7988 }
7989 mutex_unlock(&pHddCtx->sap_lock);
7990
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307991 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007992 hddLog(LOGE, FL("Stopping the BSS"));
7993 return -EINVAL;
7994 }
7995
Srinivas Girigowda8b983962015-11-18 22:14:34 -08007996 cdf_copy_macaddr(&updateIE.bssid, &pAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007997 updateIE.smeSessionId = pAdapter->sessionId;
7998 updateIE.ieBufferlength = 0;
7999 updateIE.pAdditionIEBuffer = NULL;
8000 updateIE.append = true;
8001 updateIE.notify = true;
8002 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
8003 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308004 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008005 hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
8006 }
8007
8008 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
8009 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308010 eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008011 hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE"));
8012 }
8013 /* Reset WNI_CFG_PROBE_RSP Flags */
8014 wlan_hdd_reset_prob_rspies(pAdapter);
8015
8016#ifdef WLAN_FEATURE_P2P_DEBUG
8017 if ((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8018 (global_p2p_connection_status == P2P_GO_COMPLETED_STATE)) {
8019 hddLog(LOGE,
8020 "[P2P State] From GO completed to Inactive state GO got removed");
8021 global_p2p_connection_status = P2P_NOT_ACTIVE;
8022 }
8023#endif
8024 EXIT();
8025 return ret;
8026}
8027
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008028/**
8029 * wlan_hdd_get_channel_bw() - get channel bandwidth
8030 * @width: input channel width in nl80211_chan_width value
8031 *
8032 * Return: channel width value defined by driver
8033 */
8034static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
8035 enum nl80211_chan_width width)
8036{
8037 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
8038
8039 switch (width) {
8040 case NL80211_CHAN_WIDTH_20_NOHT:
8041 case NL80211_CHAN_WIDTH_20:
8042 ch_bw = HW_MODE_20_MHZ;
8043 break;
8044 case NL80211_CHAN_WIDTH_40:
8045 ch_bw = HW_MODE_40_MHZ;
8046 break;
8047 case NL80211_CHAN_WIDTH_80:
8048 ch_bw = HW_MODE_80_MHZ;
8049 break;
8050 case NL80211_CHAN_WIDTH_80P80:
8051 ch_bw = HW_MODE_80_PLUS_80_MHZ;
8052 break;
8053 case NL80211_CHAN_WIDTH_160:
8054 ch_bw = HW_MODE_160_MHZ;
8055 break;
8056 default:
8057 hdd_err("Invalid width: %d, using default 20MHz", width);
8058 break;
8059 }
8060
8061 return ch_bw;
8062}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008063
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008064/**
8065 * wlan_hdd_cfg80211_stop_ap() - stop sap
8066 * @wiphy: Pointer to wiphy
8067 * @dev: Pointer to netdev
8068 *
8069 * Return: zero for success non-zero for failure
8070 */
8071int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8072 struct net_device *dev)
8073{
8074 int ret;
8075
8076 cds_ssr_protect(__func__);
8077 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8078 cds_ssr_unprotect(__func__);
8079
8080 return ret;
8081}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008082
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008083/**
8084 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
8085 * @wiphy: Pointer to wiphy structure
8086 * @dev: Pointer to net_device structure
8087 * @params: Pointer to AP settings parameters
8088 *
8089 * Return: 0 for success non-zero for failure
8090 */
8091static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8092 struct net_device *dev,
8093 struct cfg80211_ap_settings *params)
8094{
8095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8096 hdd_context_t *pHddCtx;
Chandrasekaran, Manishekar96c90962015-11-20 16:47:45 +05308097 enum hw_mode_bandwidth channel_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008098 int status;
8099 uint8_t channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008100
8101 ENTER();
8102
Peng Xuf5d60c82015-10-02 17:17:03 -07008103 if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008104 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8105 return -EINVAL;
8106 }
8107
8108 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
8109 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8110 params->beacon_interval));
8111 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
8112 hddLog(LOGE, FL("HDD adapter magic is invalid"));
8113 return -ENODEV;
8114 }
8115
8116 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8117 status = wlan_hdd_validate_context(pHddCtx);
8118
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308119 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008120 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008121
8122 hddLog(LOG2, FL("pAdapter = %p, Device mode %s(%d)"), pAdapter,
8123 hdd_device_mode_to_string(pAdapter->device_mode),
8124 pAdapter->device_mode);
8125
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008126 channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
8127 channel = ieee80211_frequency_to_channel(
8128 params->chandef.chan->center_freq);
Amar Singhal01098f72015-10-08 11:55:32 -07008129
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008130 /* check if concurrency is allowed */
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008131 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008132 cds_convert_device_mode_to_hdd_type(
8133 pAdapter->device_mode),
8134 channel,
8135 channel_width)) {
8136 hdd_err("Connection failed due to concurrency check failure");
8137 return -EINVAL;
8138 }
8139 if (pHddCtx->config->policy_manager_enabled) {
Chandrasekaran, Manishekareceb8112015-11-16 15:38:53 +05308140 status = cdf_reset_connection_update();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308141 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008142 hdd_err("ERR: clear event failed");
8143
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308144 status = cds_current_connections_update(pAdapter->sessionId,
8145 channel,
8146 CDS_UPDATE_REASON_START_AP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308147 if (QDF_STATUS_E_FAILURE == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008148 hdd_err("ERROR: connections update failed!!");
8149 return -EINVAL;
8150 }
8151
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308152 if (QDF_STATUS_SUCCESS == status) {
Chandrasekaran, Manishekareceb8112015-11-16 15:38:53 +05308153 status = cdf_wait_for_connection_update();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308154 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008155 hdd_err("ERROR: cdf wait for event failed!!");
8156 return -EINVAL;
8157 }
8158 }
8159 }
8160
8161 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8162 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
8163 ) {
8164 beacon_data_t *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008165 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008166
8167 old = pAdapter->sessionCtx.ap.beacon;
8168
8169 if (old)
8170 return -EALREADY;
8171
8172 status =
8173 wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new,
8174 &params->beacon,
8175 params->dtim_period);
8176
8177 if (status != 0) {
8178 hddLog(LOGE, FL("Error!!! Allocating the new beacon"));
8179 return -EINVAL;
8180 }
8181 pAdapter->sessionCtx.ap.beacon = new;
8182
8183 if (params->chandef.width < NL80211_CHAN_WIDTH_80)
8184 channel_type = cfg80211_get_chandef_type(
8185 &(params->chandef));
8186 else
8187 channel_type = NL80211_CHAN_HT40PLUS;
8188
8189
8190 wlan_hdd_set_channel(wiphy, dev,
8191 &params->chandef,
8192 channel_type);
8193
8194 /* set authentication type */
8195 switch (params->auth_type) {
8196 case NL80211_AUTHTYPE_OPEN_SYSTEM:
8197 pAdapter->sessionCtx.ap.sapConfig.authType =
8198 eSAP_OPEN_SYSTEM;
8199 break;
8200 case NL80211_AUTHTYPE_SHARED_KEY:
8201 pAdapter->sessionCtx.ap.sapConfig.authType =
8202 eSAP_SHARED_KEY;
8203 break;
8204 default:
8205 pAdapter->sessionCtx.ap.sapConfig.authType =
8206 eSAP_AUTO_SWITCH;
8207 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008208 pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
8209 params->chandef.width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008210 status =
8211 wlan_hdd_cfg80211_start_bss(pAdapter,
8212 &params->beacon,
8213 params->ssid, params->ssid_len,
8214 params->hidden_ssid);
8215 }
8216
8217 EXIT();
8218 return status;
8219}
8220
8221/**
8222 * wlan_hdd_cfg80211_start_ap() - start sap
8223 * @wiphy: Pointer to wiphy
8224 * @dev: Pointer to netdev
8225 * @params: Pointer to start ap configuration parameters
8226 *
8227 * Return: zero for success non-zero for failure
8228 */
8229int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8230 struct net_device *dev,
8231 struct cfg80211_ap_settings *params)
8232{
8233 int ret;
8234
8235 cds_ssr_protect(__func__);
8236 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8237 cds_ssr_unprotect(__func__);
8238
8239 return ret;
8240}
8241
8242/**
8243 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
8244 * @wiphy: Pointer to wiphy structure
8245 * @dev: Pointer to net_device structure
8246 * @params: Pointer to change beacon parameters
8247 *
8248 * Return: 0 for success non-zero for failure
8249 */
8250static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8251 struct net_device *dev,
8252 struct cfg80211_beacon_data *params)
8253{
8254 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8255 hdd_context_t *pHddCtx;
8256 beacon_data_t *old, *new;
8257 int status;
8258
8259 ENTER();
8260
Peng Xuf5d60c82015-10-02 17:17:03 -07008261 if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008262 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8263 return -EINVAL;
8264 }
8265
8266 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
8267 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8268 pAdapter->sessionId, pAdapter->device_mode));
8269 hddLog(LOG1, FL("Device_mode %s(%d)"),
8270 hdd_device_mode_to_string(pAdapter->device_mode),
8271 pAdapter->device_mode);
8272
8273 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8274 status = wlan_hdd_validate_context(pHddCtx);
8275
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308276 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008277 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008278
8279 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
8280 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
8281 return -EOPNOTSUPP;
8282 }
8283
8284 old = pAdapter->sessionCtx.ap.beacon;
8285
8286 if (!old) {
8287 hddLog(LOGE, FL("session(%d) beacon data points to NULL"),
8288 pAdapter->sessionId);
8289 return -EINVAL;
8290 }
8291
8292 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8293
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308294 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008295 hddLog(LOGE, FL("new beacon alloc failed"));
8296 return -EINVAL;
8297 }
8298
8299 pAdapter->sessionCtx.ap.beacon = new;
8300 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
8301
8302 EXIT();
8303 return status;
8304}
8305
8306/**
8307 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
8308 * @wiphy: Pointer to wiphy
8309 * @dev: Pointer to netdev
8310 * @params: Pointer to change beacon parameters
8311 *
8312 * Return: zero for success non-zero for failure
8313 */
8314int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8315 struct net_device *dev,
8316 struct cfg80211_beacon_data *params)
8317{
8318 int ret;
8319
8320 cds_ssr_protect(__func__);
8321 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8322 cds_ssr_unprotect(__func__);
8323
8324 return ret;
8325}