blob: 4351c7219b1339e5cac7b78cf03e7cfde15695a7 [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>
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070043#include <cdp_txrx_stats.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080044#include <cds_api.h>
45#include <cds_sched.h>
46#include <linux/etherdevice.h>
47#include <wlan_hdd_includes.h>
48#include <qc_sap_ioctl.h>
49#include <wlan_hdd_hostapd.h>
50#include <sap_api.h>
51#include <sap_internal.h>
52#include <wlan_hdd_softap_tx_rx.h>
53#include <wlan_hdd_main.h>
54#include <wlan_hdd_ioctl.h>
55#include <wlan_hdd_stats.h>
56#include <linux/netdevice.h>
57#include <linux/rtnetlink.h>
58#include <linux/mmc/sdio_func.h>
59#include "wlan_hdd_p2p.h"
60#include <wlan_hdd_ipa.h>
61#include "cfg_api.h"
62#include "wni_cfg.h"
63#include "wlan_hdd_misc.h"
64#include <cds_utils.h>
65#if defined CONFIG_CNSS
66#include <net/cnss.h>
67#endif
68
69#include "wma.h"
70#ifdef DEBUG
71#include "wma_api.h"
72#endif
73#include "wlan_hdd_trace.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053074#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053075#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076#include "wlan_hdd_cfg.h"
77#include "cds_concurrency.h"
78#include "wlan_hdd_green_ap.h"
79
80#define IS_UP(_dev) \
81 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
82#define IS_UP_AUTO(_ic) \
83 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
84#define WE_WLAN_VERSION 1
85#define WE_GET_STA_INFO_SIZE 30
86/* WEXT limitation: MAX allowed buf len for any *
87 * IW_PRIV_TYPE_CHAR is 2Kbytes *
88 */
89#define WE_SAP_MAX_STA_INFO 0x7FF
90
91#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7)
92#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
93#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf)
94#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)
95
96#define SAP_24GHZ_CH_COUNT (14)
97#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080098
99#define DUMP_DP_TRACE 0
100
101/* Function definitions */
102
103/**
104 * hdd_hostapd_channel_wakelock_init() - init the channel wakelock
105 * @pHddCtx: pointer to hdd context
106 *
107 * Return: None
108 */
109void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx)
110{
111 /* Initialize the wakelock */
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530112 qdf_wake_lock_create(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800113 atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
114}
115
116/**
117 * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
118 * Called when, 1. bss stopped, 2. channel switch
119 *
120 * @pAdapter: pointer to hdd adapter
121 * @channel: current channel
122 *
123 * Return: None
124 */
125void hdd_hostapd_channel_allow_suspend(hdd_adapter_t *pAdapter,
126 uint8_t channel)
127{
128
129 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
130 hdd_hostapd_state_t *pHostapdState =
131 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
132
133 hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
134 pHostapdState->bssState, channel,
135 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
136
137 /* Return if BSS is already stopped */
138 if (pHostapdState->bssState == BSS_STOP)
139 return;
140
141 /* Release wakelock when no more DFS channels are used */
142 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
143 if (atomic_dec_and_test(&pHddCtx->sap_dfs_ref_cnt)) {
144 hddLog(LOGE, FL("DFS: allowing suspend (chan %d)"),
145 channel);
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530146 qdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800147 WIFI_POWER_EVENT_WAKELOCK_DFS);
148 }
149 }
150}
151
152/**
153 * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
154 * Called when, 1. bss started, 2. channel switch
155 *
156 * @pAdapter: pointer to hdd adapter
157 * @channel: current channel
158 *
159 * Return - None
160 */
161void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter,
162 uint8_t channel)
163{
164 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
165 hdd_hostapd_state_t *pHostapdState =
166 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
167
168 hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
169 pHostapdState->bssState, channel,
170 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
171
172 /* Return if BSS is already started && wakelock is acquired */
173 if ((pHostapdState->bssState == BSS_START) &&
174 (atomic_read(&pHddCtx->sap_dfs_ref_cnt) >= 1))
175 return;
176
177 /* Acquire wakelock if we have at least one DFS channel in use */
178 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
179 if (atomic_inc_return(&pHddCtx->sap_dfs_ref_cnt) == 1) {
180 hddLog(LOGE, FL("DFS: preventing suspend (chan %d)"),
181 channel);
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530182 qdf_wake_lock_acquire(&pHddCtx->sap_dfs_wakelock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800183 WIFI_POWER_EVENT_WAKELOCK_DFS);
184 }
185 }
186}
187
188/**
189 * hdd_hostapd_channel_wakelock_deinit() - destroy the channel wakelock
190 *
191 * @pHddCtx: pointer to hdd context
192 *
193 * Return: None
194 */
195void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx)
196{
197 if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) {
198 /* Release wakelock */
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530199 qdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800200 WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
201 /* Reset the reference count */
202 atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
203 hddLog(LOGE, FL("DFS: allowing suspend"));
204 }
205
206 /* Destroy lock */
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530207 qdf_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208}
209
210/**
211 * __hdd_hostapd_open() - hdd open function for hostapd interface
212 * This is called in response to ifconfig up
213 * @dev: pointer to net_device structure
214 *
215 * Return - 0 for success non-zero for failure
216 */
217static int __hdd_hostapd_open(struct net_device *dev)
218{
219 hdd_adapter_t *pAdapter = netdev_priv(dev);
220
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800221 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800222
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530223 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
225
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800226 if (cds_is_load_or_unload_in_progress()) {
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800227 hdd_err("Driver load/unload in progress, ignore, state: 0x%x",
228 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229 goto done;
230 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800231
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800232 /* Enable all Tx queues */
233 hddLog(LOG1, FL("Enabling queues"));
234 wlan_hdd_netif_queue_control(pAdapter,
235 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
236 WLAN_CONTROL_PATH);
237done:
238 EXIT();
239 return 0;
240}
241
242/**
243 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
244 * @dev: pointer to net device
245 *
246 * Return: 0 on success, error number otherwise
247 */
248static int hdd_hostapd_open(struct net_device *dev)
249{
250 int ret;
251
252 cds_ssr_protect(__func__);
253 ret = __hdd_hostapd_open(dev);
254 cds_ssr_unprotect(__func__);
255
256 return ret;
257}
258
259/**
260 * __hdd_hostapd_stop() - hdd stop function for hostapd interface
261 * This is called in response to ifconfig down
262 *
263 * @dev: pointer to net_device structure
264 *
265 * Return - 0 for success non-zero for failure
266 */
267static int __hdd_hostapd_stop(struct net_device *dev)
268{
269 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800270
271 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272
273 /* Stop all tx queues */
274 hddLog(LOG1, FL("Disabling queues"));
275 wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
276 WLAN_CONTROL_PATH);
277
278 EXIT();
279 return 0;
280}
281
282/**
283 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
284 * @dev: pointer to net_device
285 *
286 * This is called in response to ifconfig down
287 *
288 * Return: 0 on success, error number otherwise
289 */
290int hdd_hostapd_stop(struct net_device *dev)
291{
292 int ret;
293
294 cds_ssr_protect(__func__);
295 ret = __hdd_hostapd_stop(dev);
296 cds_ssr_unprotect(__func__);
297
298 return ret;
299}
300
301/**
302 * __hdd_hostapd_uninit() - hdd uninit function
303 * This is called during the netdev unregister to uninitialize all data
304 * associated with the device.
305 *
306 * @dev: pointer to net_device structure
307 *
308 * Return: None
309 */
310static void __hdd_hostapd_uninit(struct net_device *dev)
311{
312 hdd_adapter_t *adapter = netdev_priv(dev);
313 hdd_context_t *hdd_ctx;
314
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800315 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316
317 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
318 hddLog(LOGE, FL("Invalid magic"));
319 return;
320 }
321
322 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
323 if (NULL == hdd_ctx) {
324 hddLog(LOGE, FL("NULL hdd_ctx"));
325 return;
326 }
327
328 hdd_deinit_adapter(hdd_ctx, adapter, true);
329
330 /* after uninit our adapter structure will no longer be valid */
331 adapter->dev = NULL;
332 adapter->magic = 0;
333
334 EXIT();
335}
336
337/**
338 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
339 * @dev: pointer to net_device
340 *
341 * Return: 0 on success, error number otherwise
342 */
343static void hdd_hostapd_uninit(struct net_device *dev)
344{
345 cds_ssr_protect(__func__);
346 __hdd_hostapd_uninit(dev);
347 cds_ssr_unprotect(__func__);
348}
349
350/**
351 * __hdd_hostapd_change_mtu() - change mtu
352 * @dev: pointer to net_device
353 * @new_mtu: new mtu
354 *
355 * Return: 0 on success, error number otherwise
356 */
357static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
358{
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800359 ENTER_DEV(dev);
360
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800361 return 0;
362}
363
364/**
365 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
366 * @dev: pointer to net_device
367 * @new_mtu: new mtu
368 *
369 * Return: 0 on success, error number otherwise
370 */
371static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
372{
373 int ret;
374
375 cds_ssr_protect(__func__);
376 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
377 cds_ssr_unprotect(__func__);
378
379 return ret;
380}
381
382#ifdef QCA_HT_2040_COEX
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530383QDF_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 uint8_t channel_type)
385{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530386 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800387 void *hHal = NULL;
388
389 hddLog(LOGE, FL("change HT20/40 mode"));
390
391 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
392 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
393 if (NULL == hHal) {
394 hddLog(LOGE, FL("Hal ctx is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530395 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530397 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 sme_set_ht2040_mode(hHal, pHostapdAdapter->sessionId,
399 channel_type, true);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530400 if (qdf_ret_status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800401 hddLog(LOGE, FL("Failed to change HT20/40 mode"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530402 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403 }
404 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530405 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406}
407#endif
408
409/**
410 * __hdd_hostapd_set_mac_address() -
411 * This function sets the user specified mac address using
412 * the command ifconfig wlanX hw ether <mac address>.
413 *
414 * @dev: pointer to the net device.
415 * @addr: pointer to the sockaddr.
416 *
417 * Return: 0 for success, non zero for failure
418 */
419static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
420{
421 struct sockaddr *psta_mac_addr = addr;
422 hdd_adapter_t *adapter;
423 hdd_context_t *hdd_ctx;
424 int ret = 0;
425
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800426 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427
428 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
429 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
430 ret = wlan_hdd_validate_context(hdd_ctx);
431 if (0 != ret)
432 return ret;
433
434 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
435 EXIT();
436 return 0;
437}
438
439/**
440 * hdd_hostapd_set_mac_address() - set mac address
441 * @dev: pointer to net_device
442 * @addr: mac address
443 *
444 * Return: 0 on success, error number otherwise
445 */
446static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
447{
448 int ret;
449
450 cds_ssr_protect(__func__);
451 ret = __hdd_hostapd_set_mac_address(dev, addr);
452 cds_ssr_unprotect(__func__);
453
454 return ret;
455}
456
457void hdd_hostapd_inactivity_timer_cb(void *usrDataForCallback)
458{
459 struct net_device *dev = (struct net_device *)usrDataForCallback;
460 uint8_t we_custom_event[64];
461 union iwreq_data wrqu;
462#ifdef DISABLE_CONCURRENCY_AUTOSAVE
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530463 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 hdd_adapter_t *pHostapdAdapter;
465 hdd_ap_ctx_t *pHddApCtx;
466#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
467
468 /* event_name space-delimiter driver_module_name
469 * Format of the event is "AUTO-SHUT.indication" " " "module_name"
470 */
471 char *autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
472
473 /* For the NULL at the end */
474 int event_len = strlen(autoShutEvent) + 1;
475
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800476 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477
478#ifdef DISABLE_CONCURRENCY_AUTOSAVE
479 if (cds_concurrent_open_sessions_running()) {
480 /*
481 * This timer routine is going to be called only when AP
482 * persona is up.
483 * If there are concurrent sessions running we do not want
484 * to shut down the Bss.Instead we run the timer again so
485 * that if Autosave is enabled next time and other session
486 was down only then we bring down AP
487 */
488 pHostapdAdapter = netdev_priv(dev);
489 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530490 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +0530491 qdf_mc_timer_start(&pHddApCtx->hdd_ap_inactivity_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
493 config->nAPAutoShutOff * 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530494 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800495 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
496 }
497 EXIT();
498 return;
499 }
500#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
501 memset(&we_custom_event, '\0', sizeof(we_custom_event));
502 memcpy(&we_custom_event, autoShutEvent, event_len);
503
504 memset(&wrqu, 0, sizeof(wrqu));
505 wrqu.data.length = event_len;
506
507 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
508 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
509
510 EXIT();
511}
512
513void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter,
514 void *usrDataForCallback)
515{
516 uint8_t staId = 0;
517 struct net_device *dev;
518 dev = (struct net_device *)usrDataForCallback;
519
520 hddLog(LOGE, FL("Clearing all the STA entry...."));
521 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
522 if (pHostapdAdapter->aStaInfo[staId].isUsed &&
523 (staId !=
524 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)) {
525 /* Disconnect all the stations */
526 hdd_softap_sta_disassoc(pHostapdAdapter,
527 &pHostapdAdapter->
528 aStaInfo[staId].macAddrSTA.
529 bytes[0]);
530 }
531 }
532}
533
534static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,
535 void *usrDataForCallback)
536{
537 struct net_device *dev;
538 hdd_context_t *pHddCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530539 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800540 dev = (struct net_device *)usrDataForCallback;
541 ENTER();
542
543 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
544 status = wlan_hdd_validate_context(pHddCtx);
545
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +0530546 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548
549 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
550#ifdef WLAN_FEATURE_MBSSID
551 status =
552 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(
553 pHostapdAdapter));
554#else
555 status =
556 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
557 pcds_context);
558#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530559 if (QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 hddLog(LOGE, FL("Deleting SAP/P2P link!!!!!!"));
561
562 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -0800563 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564 pHostapdAdapter->sessionId);
565 }
566 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530567 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568}
569
570/**
571 * hdd_issue_stored_joinreq() - This function will trigger stations's
572 * cached connect request to proceed.
573 * @hdd_ctx: pointer to hdd context.
574 * @sta_adater: pointer to station adapter.
575 *
576 * This function will call SME to release station's stored/cached connect
577 * request to proceed.
578 *
579 * Return: none.
580 */
581static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
582 hdd_context_t *hdd_ctx)
583{
584 tHalHandle hal_handle;
585 uint32_t roam_id;
586
587 if (NULL == sta_adapter) {
588 hddLog(LOGE,
589 FL
590 ("Invalid station adapter, ignore issueing join req"));
591 return;
592 }
593 hal_handle = WLAN_HDD_GET_HAL_CTX(sta_adapter);
594
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800595 if (true == cds_is_sta_connection_pending()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530596 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597 TRACE_CODE_HDD_ISSUE_JOIN_REQ,
598 sta_adapter->sessionId, roam_id));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530599 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600 sme_issue_stored_joinreq(hal_handle,
601 &roam_id,
602 sta_adapter->sessionId)) {
603 /* change back to NotAssociated */
604 hdd_conn_set_connection_state(sta_adapter,
605 eConnectionState_NotConnected);
606 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800607 cds_change_sta_conn_pending_status(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608 }
609}
610
Liangwei Dongd7be7772015-11-05 21:50:25 -0500611#ifdef WLAN_FEATURE_MBSSID
612static eCsrPhyMode
613hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter)
614{
615 return wlansap_get_phymode(WLAN_HDD_GET_SAP_CTX_PTR(hostapd_adapter));
616}
617#else
618static eCsrPhyMode
619hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter)
620{
621 return wlansap_get_phymode(
622 (WLAN_HDD_GET_CTX(hostapd_adapter))->pcds_context);
623}
624#endif
625
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626/**
Wu Gao2c3a8002016-01-22 10:56:07 +0800627 * hdd_update_chandef() - Function to update channel width and center freq
628 * @hostapd_adapter: hostapd adapter
629 * @chandef: cfg80211 chan def
630 * @cb_mode: chan offset
631 *
632 * This function will be called to update channel width and center freq
633 *
634 * Return: None
635 */
636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) || defined(WITH_BACKPORTS)
637static inline void
638hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
639 struct cfg80211_chan_def *chandef,
640 ePhyChanBondState cb_mode)
641{
642 uint16_t ch_width;
643 hdd_ap_ctx_t *phdd_ap_ctx;
644 uint8_t center_chan, chan;
645
646 phdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
647 ch_width = phdd_ap_ctx->sapConfig.acs_cfg.ch_width;
648
649 switch (ch_width) {
650 case eHT_CHANNEL_WIDTH_20MHZ:
651 case eHT_CHANNEL_WIDTH_40MHZ:
652 hdd_info("ch_width %d, won't update", ch_width);
653 break;
654 case eHT_CHANNEL_WIDTH_80MHZ:
655 chan = cds_freq_to_chan(chandef->chan->center_freq);
656 chandef->width = NL80211_CHAN_WIDTH_80;
657
658 switch (cb_mode) {
659 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
660 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
661 center_chan = chan + 2;
662 break;
663 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
664 center_chan = chan + 6;
665 break;
666 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
667 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
668 center_chan = chan - 2;
669 break;
670 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
671 center_chan = chan - 6;
672 break;
673 default:
674 center_chan = chan;
675 break;
676 }
677
678 chandef->center_freq1 = cds_chan_to_freq(center_chan);
679 break;
680 case eHT_CHANNEL_WIDTH_160MHZ:
681 default:
682 /* Todo, please add related codes if support 160MHZ or others */
683 hdd_err("unsupport ch_width %d", ch_width);
684 break;
685 }
686
687}
688#else
689static inline void
690hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
691 struct cfg80211_chan_def *chandef,
692 ePhyChanBondState cb_mode)
693{
694}
695#endif
696
697/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 * hdd_chan_change_notify() - Function to notify hostapd about channel change
699 * @hostapd_adapter hostapd adapter
700 * @dev: Net device structure
701 * @oper_chan: New operating channel
702 *
703 * This function is used to notify hostapd about the channel change
704 *
705 * Return: Success on intimating userspace
706 *
707 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530708QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709 struct net_device *dev,
710 uint8_t oper_chan)
711{
712 struct ieee80211_channel *chan;
713 struct cfg80211_chan_def chandef;
714 enum nl80211_channel_type channel_type;
715 eCsrPhyMode phy_mode;
716 ePhyChanBondState cb_mode;
717 uint32_t freq;
718 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);
719
720 if (NULL == hal) {
721 hdd_err("hal is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530722 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800723 }
724
725 freq = cds_chan_to_freq(oper_chan);
726
727 chan = __ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);
728
729 if (!chan) {
730 hdd_err("Invalid input frequency for channel conversion");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530731 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 }
733
Liangwei Dongd7be7772015-11-05 21:50:25 -0500734 phy_mode = hdd_sap_get_phymode(hostapd_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735
736 if (oper_chan <= 14)
737 cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
738 sme_get_channel_bonding_mode24_g(hal));
739 else
740 cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
741 sme_get_channel_bonding_mode5_g(hal));
742
743 switch (phy_mode) {
744 case eCSR_DOT11_MODE_11n:
745 case eCSR_DOT11_MODE_11n_ONLY:
746 case eCSR_DOT11_MODE_11ac:
747 case eCSR_DOT11_MODE_11ac_ONLY:
748 if (cb_mode == PHY_SINGLE_CHANNEL_CENTERED)
749 channel_type = NL80211_CHAN_HT20;
750 else if (cb_mode == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
751 channel_type = NL80211_CHAN_HT40MINUS;
752 else if (cb_mode == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
753 channel_type = NL80211_CHAN_HT40PLUS;
754 else
755 channel_type = NL80211_CHAN_HT40PLUS;
756 break;
757 default:
758 channel_type = NL80211_CHAN_NO_HT;
759 break;
760 }
761
Liangwei Dongd7be7772015-11-05 21:50:25 -0500762 hdd_info("%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d",
763 __func__, phy_mode, cb_mode, channel_type, oper_chan);
764
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765 cfg80211_chandef_create(&chandef, chan, channel_type);
766
Wu Gao2c3a8002016-01-22 10:56:07 +0800767 if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
768 (phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
769 hdd_update_chandef(hostapd_adapter, &chandef, cb_mode);
770
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 cfg80211_ch_switch_notify(dev, &chandef);
772
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530773 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774}
775
776/**
777 * hdd_send_radar_event() - Function to send radar events to user space
778 * @hdd_context: HDD context
779 * @event: Type of radar event
780 * @dfs_info: Structure containing DFS channel and country
781 * @wdev: Wireless device structure
782 *
783 * This function is used to send radar events such as CAC start, CAC
784 * end etc., to userspace
785 *
786 * Return: Success on sending notifying userspace
787 *
788 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530789QDF_STATUS hdd_send_radar_event(hdd_context_t *hdd_context,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790 eSapHddEvent event,
791 struct wlan_dfs_info dfs_info,
792 struct wireless_dev *wdev)
793{
794
795 struct sk_buff *vendor_event;
796 enum qca_nl80211_vendor_subcmds_index index;
797 uint32_t freq, ret;
798 uint32_t data_size;
799
800 if (!hdd_context) {
801 hddLog(LOGE, FL("HDD context is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530802 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 }
804
805 freq = cds_chan_to_freq(dfs_info.channel);
806
807 switch (event) {
808 case eSAP_DFS_CAC_START:
809 index =
810 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
811 data_size = sizeof(uint32_t);
812 break;
813 case eSAP_DFS_CAC_END:
814 index =
815 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
816 data_size = sizeof(uint32_t);
817 break;
818 case eSAP_DFS_RADAR_DETECT:
819 index =
820 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
821 data_size = sizeof(uint32_t);
822 break;
823 default:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530824 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800825 }
826
827 vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
828 wdev,
829 data_size + NLMSG_HDRLEN,
830 index,
831 GFP_KERNEL);
832 if (!vendor_event) {
833 hddLog(LOGE,
834 FL("cfg80211_vendor_event_alloc failed for %d"), index);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530835 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836 }
837
838 ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
839
840 if (ret) {
841 hddLog(LOGE, FL("NL80211_ATTR_WIPHY_FREQ put fail"));
842 kfree_skb(vendor_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530843 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800844 }
845
846 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530847 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800848}
849
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530850QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 void *usrDataForCallback)
852{
853 hdd_adapter_t *pHostapdAdapter;
854 hdd_ap_ctx_t *pHddApCtx;
855 hdd_hostapd_state_t *pHostapdState;
856 struct net_device *dev;
857 eSapHddEvent sapEvent;
858 union iwreq_data wrqu;
859 uint8_t *we_custom_event_generic = NULL;
860 int we_event = 0;
861 int i = 0;
862 uint8_t staId;
Anurag Chouhance0dc992016-02-16 18:18:03 +0530863 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 bool bWPSState;
865 bool bAuthRequired = true;
866 tpSap_AssocMacAddr pAssocStasArray = NULL;
867 char unknownSTAEvent[IW_CUSTOM_MAX + 1];
868 char maxAssocExceededEvent[IW_CUSTOM_MAX + 1];
869 uint8_t we_custom_start_event[64];
870 char *startBssEvent;
871 hdd_context_t *pHddCtx;
872 hdd_scaninfo_t *pScanInfo = NULL;
873 struct iw_michaelmicfailure msg;
874 uint8_t ignoreCAC = 0;
875 struct hdd_config *cfg = NULL;
876 struct wlan_dfs_info dfs_info;
877 uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
878 hdd_adapter_t *con_sap_adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530879 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880#if defined CONFIG_CNSS
881 int ret = 0;
882#endif
883
884 dev = (struct net_device *)usrDataForCallback;
885 if (!dev) {
886 hddLog(LOGE, FL("usrDataForCallback is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530887 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 }
889
890 pHostapdAdapter = netdev_priv(dev);
891
892 if ((NULL == pHostapdAdapter) ||
893 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) {
894 hddLog(LOGE, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530895 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 }
897
898 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
899 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
900
901 if (!pSapEvent) {
902 hddLog(LOGE, FL("pSapEvent is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530903 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904 }
905
906 sapEvent = pSapEvent->sapHddEventCode;
907 memset(&wrqu, '\0', sizeof(wrqu));
908 pHddCtx = (hdd_context_t *) (pHostapdAdapter->pHddCtx);
909
910 if (!pHddCtx) {
911 hddLog(LOGE, FL("HDD context is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530912 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800913 }
914
915 cfg = pHddCtx->config;
916
917 if (!cfg) {
918 hddLog(LOGE, FL("HDD config is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530919 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800920 }
921
922 dfs_info.channel = pHddApCtx->operatingChannel;
923 sme_get_country_code(pHddCtx->hHal, dfs_info.country_code, &cc_len);
924
925 switch (sapEvent) {
926 case eSAP_START_BSS_EVENT:
927 hddLog(LOG1,
928 FL("BSS status = %s, channel = %u, bc sta Id = %d"),
929 pSapEvent->sapevt.sapStartBssCompleteEvent.
930 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
931 pSapEvent->sapevt.sapStartBssCompleteEvent.
932 operatingChannel,
933 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
934
935 pHostapdAdapter->sessionId =
936 pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;
937
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530938 pHostapdState->qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939 pSapEvent->sapevt.sapStartBssCompleteEvent.status;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530940 qdf_status = qdf_event_set(&pHostapdState->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800941
Anurag Chouhance0dc992016-02-16 18:18:03 +0530942 if (!QDF_IS_STATUS_SUCCESS(qdf_status)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530943 || pHostapdState->qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 hddLog(LOGE, ("ERROR: startbss event failed!!"));
945 goto stopbss;
946 } else {
947 sme_ch_avoid_update_req(pHddCtx->hHal);
948
949 pHddApCtx->uBCStaId =
950 pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
951
952 hdd_register_tx_flow_control(pHostapdAdapter,
953 hdd_softap_tx_resume_timer_expired_handler,
954 hdd_softap_tx_resume_cb);
955
956 /* @@@ need wep logic here to set privacy bit */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530957 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800958 hdd_softap_register_bc_sta(pHostapdAdapter,
959 pHddApCtx->uPrivacy);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530960 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 hddLog(LOGW, FL("Failed to register BC STA %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530962 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 hdd_stop_bss_link(pHostapdAdapter,
964 usrDataForCallback);
965 }
966 }
967
968 if (hdd_ipa_is_enabled(pHddCtx)) {
969 status = hdd_ipa_wlan_evt(pHostapdAdapter,
970 pHddApCtx->uBCStaId,
971 WLAN_AP_CONNECT,
972 pHostapdAdapter->dev->dev_addr);
973 if (status) {
974 hddLog(LOGE,
975 ("WLAN_AP_CONNECT event failed!!"));
976 goto stopbss;
977 }
978 }
979
980 if (0 !=
981 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
982 nAPAutoShutOff) {
983 /* AP Inactivity timer init and start */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530984 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +0530985 qdf_mc_timer_init(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800986 hdd_ap_inactivity_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530987 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 hdd_hostapd_inactivity_timer_cb,
989 dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530990 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991 hddLog(LOGE,
992 FL("Failed to init inactivity timer"));
993
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530994 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +0530995 qdf_mc_timer_start(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996 hdd_ap_inactivity_timer,
997 (WLAN_HDD_GET_CTX
998 (pHostapdAdapter))->config->
999 nAPAutoShutOff * 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301000 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001 hddLog(LOGE,
1002 FL("Failed to init inactivity timer"));
1003
1004 }
1005#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1006 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1007#endif
1008 pHddApCtx->operatingChannel =
1009 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
1010
1011 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1012 pHddApCtx->
1013 operatingChannel);
1014
1015 pHostapdState->bssState = BSS_START;
1016 hdd_wlan_green_ap_start_bss(pHddCtx);
1017
1018 /* Set group key / WEP key every time when BSS is restarted */
1019 if (pHddApCtx->groupKey.keyLength) {
1020 status = wlansap_set_key_sta(
1021#ifdef WLAN_FEATURE_MBSSID
1022 WLAN_HDD_GET_SAP_CTX_PTR
1023 (pHostapdAdapter),
1024#else
1025 (WLAN_HDD_GET_CTX
1026 (pHostapdAdapter))->
1027 pcds_context,
1028#endif
1029 &pHddApCtx->groupKey);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301030 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001031 hddLog(LOGE, FL("wlansap_set_key_sta failed"));
1032 } else {
1033 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
1034 if (!pHddApCtx->wepKey[i].keyLength)
1035 continue;
1036
1037 status = wlansap_set_key_sta(
1038#ifdef WLAN_FEATURE_MBSSID
1039 WLAN_HDD_GET_SAP_CTX_PTR
1040 (pHostapdAdapter),
1041#else
1042 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
1043 pcds_context,
1044#endif
1045 &pHddApCtx->
1046 wepKey[i]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301047 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 hddLog(LOGE,
1049 FL("set_key failed idx %d"), i);
1050 }
1051 }
1052 }
1053
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301054 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301056 mutex_unlock(&pHddCtx->dfs_lock);
1057
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058 wlansap_get_dfs_ignore_cac(pHddCtx->hHal, &ignoreCAC);
1059
1060 /* DFS requirement: DO NOT transmit during CAC. */
1061 if ((CHANNEL_STATE_DFS !=
1062 cds_get_channel_state(pHddApCtx->operatingChannel))
1063 || ignoreCAC
1064 || pHddCtx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
1065 pHddApCtx->dfs_cac_block_tx = false;
1066 else
1067 pHddApCtx->dfs_cac_block_tx = true;
1068
1069 hddLog(LOG3, "The value of dfs_cac_block_tx[%d] for ApCtx[%p]",
1070 pHddApCtx->dfs_cac_block_tx, pHddApCtx);
1071
1072 if ((CHANNEL_STATE_DFS ==
1073 cds_get_channel_state(pHddApCtx->operatingChannel))
1074 && (pHddCtx->config->IsSapDfsChSifsBurstEnabled == 0)) {
1075
1076 hddLog(LOG1,
1077 FL("Set SIFS Burst disable for DFS channel %d"),
1078 pHddApCtx->operatingChannel);
1079
1080 if (wma_cli_set_command(pHostapdAdapter->sessionId,
1081 WMI_PDEV_PARAM_BURST_ENABLE,
1082 0, PDEV_CMD)) {
1083 hddLog(LOGE,
1084 FL("Failed to Set SIFS Burst %d"),
1085 pHddApCtx->operatingChannel);
1086 }
1087 }
1088 /* Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled */
1089 startBssEvent = "SOFTAP.enabled";
1090 memset(&we_custom_start_event, '\0',
1091 sizeof(we_custom_start_event));
1092 memcpy(&we_custom_start_event, startBssEvent,
1093 strlen(startBssEvent));
1094 memset(&wrqu, 0, sizeof(wrqu));
1095 wrqu.data.length = strlen(startBssEvent);
1096 we_event = IWEVCUSTOM;
1097 we_custom_event_generic = we_custom_start_event;
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001098 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099 /* Send SCC/MCC Switching event to IPA */
1100 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1101 break; /* Event will be sent after Switch-Case stmt */
1102
1103 case eSAP_STOP_BSS_EVENT:
1104 hddLog(LOG1, FL("BSS stop status = %s"),
1105 pSapEvent->sapevt.sapStopBssCompleteEvent.
1106 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1107
1108 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1109 pHddApCtx->operatingChannel);
1110
1111 hdd_wlan_green_ap_stop_bss(pHddCtx);
1112
1113 /* Free up Channel List incase if it is set */
1114#ifdef WLAN_FEATURE_MBSSID
1115 sap_cleanup_channel_list(WLAN_HDD_GET_SAP_CTX_PTR
1116 (pHostapdAdapter));
1117#else
1118 sap_cleanup_channel_list();
1119#endif
1120 /* Invalidate the channel info. */
1121 pHddApCtx->operatingChannel = 0;
1122 if (hdd_ipa_is_enabled(pHddCtx)) {
1123 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1124 pHddApCtx->uBCStaId,
1125 WLAN_AP_DISCONNECT,
1126 pHostapdAdapter->dev->dev_addr);
1127 if (status) {
1128 hddLog(LOGE,
1129 ("WLAN_AP_DISCONNECT event failed!!"));
1130 goto stopbss;
1131 }
1132 }
1133
1134 /* reset the dfs_cac_status and dfs_cac_block_tx flag only when
1135 * the last BSS is stopped
1136 */
1137 con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter, true);
1138 if (!con_sap_adapter) {
1139 pHddApCtx->dfs_cac_block_tx = true;
1140 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1141 }
1142 if (pHddCtx->config->conc_custom_rule2 &&
1143 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
1144 hdd_adapter_t *sta_adapter = hdd_get_adapter(pHddCtx,
1145 WLAN_HDD_INFRA_STATION);
1146 hddLog(LOG2,
1147 FL("P2PGO is going down now"));
1148 hdd_issue_stored_joinreq(sta_adapter, pHddCtx);
1149 }
1150 goto stopbss;
1151
1152 case eSAP_DFS_CAC_START:
1153 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_START_IND,
1154 &dfs_info,
1155 sizeof(struct wlan_dfs_info));
1156 pHddCtx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301157 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001158 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_START,
1159 dfs_info, &pHostapdAdapter->wdev)) {
1160 hddLog(LOGE, FL("Unable to indicate CAC start NL event"));
1161 } else {
1162 hdd_info("Sent CAC start to user space");
1163 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301164
1165 mutex_lock(&pHddCtx->dfs_lock);
1166 pHddCtx->dfs_radar_found = false;
1167 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001168 break;
1169 case eSAP_DFS_CAC_INTERRUPTED:
1170 /*
1171 * The CAC timer did not run completely and a radar was detected
1172 * during the CAC time. This new state will keep the tx path
1173 * blocked since we do not want any transmission on the DFS
1174 * channel. CAC end will only be reported here since the user
1175 * space applications are waiting on CAC end for their state
1176 * management.
1177 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301178 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001179 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1180 dfs_info, &pHostapdAdapter->wdev)) {
1181 hdd_err("Unable to indicate CAC end (interrupted) event");
1182 } else {
1183 hdd_info("Sent CAC end (interrupted) to user space");
1184 }
1185 break;
1186 case eSAP_DFS_CAC_END:
1187 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_END_IND,
1188 &dfs_info,
1189 sizeof(struct wlan_dfs_info));
1190 pHddApCtx->dfs_cac_block_tx = false;
1191 pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301192 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001193 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1194 dfs_info, &pHostapdAdapter->wdev)) {
1195 hddLog(LOGE, FL("Unable to indicate CAC end NL event"));
1196 } else {
1197 hdd_info("Sent CAC end to user space");
1198 }
1199 break;
1200
1201 case eSAP_DFS_RADAR_DETECT:
1202 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_RADAR_DETECT_IND,
1203 &dfs_info,
1204 sizeof(struct wlan_dfs_info));
1205 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301206 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
1208 dfs_info, &pHostapdAdapter->wdev)) {
1209 hddLog(LOGE, FL("Unable to indicate Radar detect NL event"));
1210 } else {
1211 hdd_info("Sent radar detected to user space");
1212 }
1213 break;
1214
1215 case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1216 wlan_hdd_send_svc_nlink_msg
1217 (WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
1218 sizeof(struct wlan_dfs_info));
1219 break;
1220
1221 case eSAP_STA_SET_KEY_EVENT:
1222 /* TODO:
1223 * forward the message to hostapd once implementation
1224 * is done for now just print
1225 */
1226 hddLog(LOG1, FL("SET Key: configured status = %s"),
1227 pSapEvent->sapevt.sapStationSetKeyCompleteEvent.
1228 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301229 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 case eSAP_STA_MIC_FAILURE_EVENT:
1231 {
1232 memset(&msg, '\0', sizeof(msg));
1233 msg.src_addr.sa_family = ARPHRD_ETHER;
1234 memcpy(msg.src_addr.sa_data,
1235 &pSapEvent->sapevt.sapStationMICFailureEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301236 staMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
1238 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
1239 if (pSapEvent->sapevt.sapStationMICFailureEvent.
1240 multicast == eSAP_TRUE)
1241 msg.flags = IW_MICFAILURE_GROUP;
1242 else
1243 msg.flags = IW_MICFAILURE_PAIRWISE;
1244 memset(&wrqu, 0, sizeof(wrqu));
1245 wrqu.data.length = sizeof(msg);
1246 we_event = IWEVMICHAELMICFAILURE;
1247 we_custom_event_generic = (uint8_t *) &msg;
1248 }
1249 /* inform mic failure to nl80211 */
1250 cfg80211_michael_mic_failure(dev,
1251 pSapEvent->
1252 sapevt.sapStationMICFailureEvent.
1253 staMac.bytes,
1254 ((pSapEvent->sapevt.
1255 sapStationMICFailureEvent.
1256 multicast ==
1257 eSAP_TRUE) ?
1258 NL80211_KEYTYPE_GROUP :
1259 NL80211_KEYTYPE_PAIRWISE),
1260 pSapEvent->sapevt.
1261 sapStationMICFailureEvent.keyId,
1262 pSapEvent->sapevt.
1263 sapStationMICFailureEvent.TSC,
1264 GFP_KERNEL);
1265 break;
1266
1267 case eSAP_STA_ASSOC_EVENT:
1268 case eSAP_STA_REASSOC_EVENT:
1269 wrqu.addr.sa_family = ARPHRD_ETHER;
1270 memcpy(wrqu.addr.sa_data,
1271 &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301272 staMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 hddLog(LOG1, " associated " MAC_ADDRESS_STR,
1274 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1275 we_event = IWEVREGISTERED;
1276
1277#ifdef WLAN_FEATURE_MBSSID
1278 wlansap_get_wps_state(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
1279 &bWPSState);
1280#else
1281 wlansap_get_wps_state((WLAN_HDD_GET_CTX(pHostapdAdapter))->
1282 pcds_context, &bWPSState);
1283#endif
1284
1285 if ((eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
1286 (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
1287 pHddApCtx->ucEncryptType)
1288 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
1289 pHddApCtx->ucEncryptType)) {
1290 bAuthRequired = false;
1291 }
1292
1293 if (bAuthRequired || bWPSState == true) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301294 qdf_status = hdd_softap_register_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001295 pHostapdAdapter,
1296 true,
1297 pHddApCtx->uPrivacy,
1298 pSapEvent->sapevt.
1299 sapStationAssocReassocCompleteEvent.
1300 staId, 0, 0,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301301 (struct qdf_mac_addr *)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 wrqu.addr.sa_data,
1303 pSapEvent->sapevt.
1304 sapStationAssocReassocCompleteEvent.
1305 wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301306 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307 hddLog(LOGW,
1308 FL("Failed to register STA %d "
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301309 MAC_ADDRESS_STR ""), qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1311 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301312 qdf_status = hdd_softap_register_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001313 pHostapdAdapter,
1314 false,
1315 pHddApCtx->uPrivacy,
1316 pSapEvent->sapevt.
1317 sapStationAssocReassocCompleteEvent.
1318 staId, 0, 0,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301319 (struct qdf_mac_addr *)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320 wrqu.addr.sa_data,
1321 pSapEvent->sapevt.
1322 sapStationAssocReassocCompleteEvent.
1323 wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301324 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 hddLog(LOGW,
1326 FL("Failed to register STA %d "
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301327 MAC_ADDRESS_STR ""), qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1329 }
1330
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301331 staId =
1332 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301333 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301334 pHostapdAdapter->aStaInfo[staId].nss =
1335 pSapEvent->sapevt.
1336 sapStationAssocReassocCompleteEvent.
1337 chan_info.nss;
1338 pHostapdAdapter->aStaInfo[staId].rate_flags =
1339 pSapEvent->sapevt.
1340 sapStationAssocReassocCompleteEvent.
1341 chan_info.rate_flags;
1342 }
1343
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 if (hdd_ipa_is_enabled(pHddCtx)) {
1345 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1346 pSapEvent->sapevt.
1347 sapStationAssocReassocCompleteEvent.
1348 staId, WLAN_CLIENT_CONNECT_EX,
1349 pSapEvent->sapevt.
1350 sapStationAssocReassocCompleteEvent.
1351 staMac.bytes);
1352 if (status) {
1353 hddLog(LOGE,
1354 FL("WLAN_CLIENT_CONNECT_EX event failed"));
1355 goto stopbss;
1356 }
1357 }
1358
1359#ifdef QCA_PKT_PROTO_TRACE
1360 /* Peer associated, update into trace buffer */
1361 if (pHddCtx->config->gEnableDebugLog) {
1362 cds_pkt_trace_buf_update("HA:ASSOC");
1363 }
1364#endif /* QCA_PKT_PROTO_TRACE */
1365
1366#ifdef MSM_PLATFORM
1367 /* start timer in sap/p2p_go */
1368 if (pHddApCtx->bApActive == false) {
1369 spin_lock_bh(&pHddCtx->bus_bw_lock);
1370 pHostapdAdapter->prev_tx_packets =
1371 pHostapdAdapter->stats.tx_packets;
1372 pHostapdAdapter->prev_rx_packets =
1373 pHostapdAdapter->stats.rx_packets;
1374 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1375 hdd_start_bus_bw_compute_timer(pHostapdAdapter);
1376 }
1377#endif
1378 pHddApCtx->bApActive = true;
1379 /* Stop AP inactivity timer */
1380 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301381 QDF_TIMER_STATE_RUNNING) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301382 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301383 qdf_mc_timer_stop(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301385 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 hddLog(LOGE,
1387 FL("Failed to start inactivity timer"));
1388 }
1389 }
1390#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1391 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1392#endif
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301393 qdf_wake_lock_timeout_acquire(&pHddCtx->sap_wake_lock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001394 HDD_SAP_WAKE_LOCK_DURATION,
1395 WIFI_POWER_EVENT_WAKELOCK_SAP);
1396 {
1397 struct station_info staInfo;
1398 uint16_t iesLen =
1399 pSapEvent->sapevt.
1400 sapStationAssocReassocCompleteEvent.iesLen;
1401
1402 memset(&staInfo, 0, sizeof(staInfo));
1403 if (iesLen <= MAX_ASSOC_IND_IE_LEN) {
1404 staInfo.assoc_req_ies =
1405 (const u8 *)&pSapEvent->sapevt.
1406 sapStationAssocReassocCompleteEvent.ies[0];
1407 staInfo.assoc_req_ies_len = iesLen;
Ryan Hsue7bc3a72016-01-18 12:08:22 -08001408#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
1409 /*
1410 * After Kernel 4.0, it's no longer need to set
1411 * STATION_INFO_ASSOC_REQ_IES flag, as it
1412 * changed to use assoc_req_ies_len length to
1413 * check the existance of request IE.
1414 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
Ryan Hsue7bc3a72016-01-18 12:08:22 -08001416#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417 cfg80211_new_sta(dev,
1418 (const u8 *)&pSapEvent->sapevt.
1419 sapStationAssocReassocCompleteEvent.
1420 staMac.bytes[0], &staInfo,
1421 GFP_KERNEL);
1422 } else {
1423 hddLog(LOGE,
1424 FL("Assoc Ie length is too long"));
1425 }
1426 }
1427
1428 pScanInfo = &pHostapdAdapter->scan_info;
1429 /* Lets do abort scan to ensure smooth authentication for client */
1430 if ((pScanInfo != NULL) && pScanInfo->mScanPending) {
1431 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
1432 eCSR_SCAN_ABORT_DEFAULT);
1433 }
1434 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1435 /* send peer status indication to oem app */
1436 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1437 sapStationAssocReassocCompleteEvent.
1438 staMac, ePeerConnected,
1439 pSapEvent->sapevt.
1440 sapStationAssocReassocCompleteEvent.
1441 timingMeasCap,
1442 pHostapdAdapter->
1443 sessionId,
1444 &pSapEvent->sapevt.
1445 sapStationAssocReassocCompleteEvent.
1446 chan_info);
1447 }
1448 hdd_wlan_green_ap_add_sta(pHddCtx);
1449 break;
1450
1451 case eSAP_STA_DISASSOC_EVENT:
1452 memcpy(wrqu.addr.sa_data,
1453 &pSapEvent->sapevt.sapStationDisassocCompleteEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301454 staMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001455 hddLog(LOG1, " disassociated " MAC_ADDRESS_STR,
1456 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1457
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301458 qdf_status = qdf_event_set(&pHostapdState->qdf_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301459 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460 hddLog(LOGE, "ERR: Station Deauth event Set failed");
1461
1462 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
1463 eSAP_USR_INITATED_DISASSOC)
1464 hddLog(LOG1, " User initiated disassociation");
1465 else
1466 hddLog(LOG1, " MAC initiated disassociation");
1467 we_event = IWEVEXPIRED;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301468 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469 hdd_softap_get_sta_id(pHostapdAdapter,
1470 &pSapEvent->sapevt.
1471 sapStationDisassocCompleteEvent.staMac,
1472 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301473 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474 hddLog(LOGE, FL("ERROR: HDD Failed to find sta id!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301475 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 }
1477#ifdef IPA_OFFLOAD
1478 if (hdd_ipa_is_enabled(pHddCtx)) {
1479 status = hdd_ipa_wlan_evt(pHostapdAdapter, staId,
1480 WLAN_CLIENT_DISCONNECT,
1481 pSapEvent->sapevt.
1482 sapStationDisassocCompleteEvent.
1483 staMac.bytes);
1484
1485 if (status) {
1486 hddLog(LOGE,
1487 ("ERROR: WLAN_CLIENT_DISCONNECT event failed!!"));
1488 goto stopbss;
1489 }
1490 }
1491#endif
1492#ifdef QCA_PKT_PROTO_TRACE
1493 /* Peer dis-associated, update into trace buffer */
1494 if (pHddCtx->config->gEnableDebugLog) {
1495 cds_pkt_trace_buf_update("HA:DISASC");
1496 }
1497#endif /* QCA_PKT_PROTO_TRACE */
1498 hdd_softap_deregister_sta(pHostapdAdapter, staId);
1499
1500 pHddApCtx->bApActive = false;
1501 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1502 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
1503 if (pHostapdAdapter->aStaInfo[i].isUsed
1504 && i !=
1505 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
1506 uBCStaId) {
1507 pHddApCtx->bApActive = true;
1508 break;
1509 }
1510 }
1511 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1512
1513 /* Start AP inactivity timer if no stations associated with it */
1514 if ((0 !=
1515 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1516 nAPAutoShutOff)) {
1517 if (pHddApCtx->bApActive == false) {
1518 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301519 QDF_TIMER_STATE_STOPPED) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301520 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301521 qdf_mc_timer_start(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522 hdd_ap_inactivity_timer,
1523 (WLAN_HDD_GET_CTX
1524 (pHostapdAdapter))->
1525 config->
1526 nAPAutoShutOff *
1527 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301528 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 hddLog(LOGE,
1530 FL("Failed to init AP inactivity timer"));
1531 } else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301532 QDF_ASSERT
Anurag Chouhan210db072016-02-22 18:42:15 +05301533 (qdf_mc_timer_get_current_state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534 (&pHddApCtx->
1535 hdd_ap_inactivity_timer) ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301536 QDF_TIMER_STATE_STOPPED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 }
1538 }
1539#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1540 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1541#endif
1542
1543 cfg80211_del_sta(dev,
1544 (const u8 *)&pSapEvent->sapevt.
1545 sapStationDisassocCompleteEvent.staMac.
1546 bytes[0], GFP_KERNEL);
1547
1548 /* Update the beacon Interval if it is P2P GO */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301549 qdf_status = cds_change_mcc_go_beacon_interval(pHostapdAdapter);
1550 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 hddLog(LOGE, FL("failed to update Beacon interval %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301552 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001553 }
1554 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1555 /* send peer status indication to oem app */
1556 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1557 sapStationDisassocCompleteEvent.
1558 staMac, ePeerDisconnected,
1559 0,
1560 pHostapdAdapter->
1561 sessionId, NULL);
1562 }
1563#ifdef MSM_PLATFORM
1564 /*stop timer in sap/p2p_go */
1565 if (pHddApCtx->bApActive == false) {
1566 spin_lock_bh(&pHddCtx->bus_bw_lock);
1567 pHostapdAdapter->prev_tx_packets = 0;
1568 pHostapdAdapter->prev_rx_packets = 0;
1569 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1570 hdd_stop_bus_bw_compute_timer(pHostapdAdapter);
1571 }
1572#endif
1573 hdd_wlan_green_ap_del_sta(pHddCtx);
1574 break;
1575
1576 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1577 {
1578 static const char *message =
1579 "MLMEWPSPBCPROBEREQ.indication";
1580 union iwreq_data wreq;
1581
1582 down(&pHddApCtx->semWpsPBCOverlapInd);
1583 pHddApCtx->WPSPBCProbeReq.probeReqIELen =
1584 pSapEvent->sapevt.sapPBCProbeReqEvent.
1585 WPSPBCProbeReq.probeReqIELen;
1586
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301587 qdf_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001588 pSapEvent->sapevt.sapPBCProbeReqEvent.
1589 WPSPBCProbeReq.probeReqIE,
1590 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1591
Anurag Chouhanc5548422016-02-24 18:33:27 +05301592 qdf_copy_macaddr(&pHddApCtx->WPSPBCProbeReq.peer_macaddr,
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001593 &pSapEvent->sapevt.sapPBCProbeReqEvent.
1594 WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595 hddLog(LOG1, "WPS PBC probe req " MAC_ADDRESS_STR,
1596 MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001597 peer_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598 memset(&wreq, 0, sizeof(wreq));
1599 wreq.data.length = strlen(message); /* This is length of message */
1600 wireless_send_event(dev, IWEVCUSTOM, &wreq,
1601 (char *)message);
1602
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301603 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604 }
1605 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1606 pAssocStasArray =
1607 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1608 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) { /* List of associated stations */
1609 for (i = 0;
1610 i <
1611 pSapEvent->sapevt.sapAssocStaListEvent.
1612 noOfAssocSta; i++) {
1613 hddLog(LOG1,
1614 "Associated Sta Num %d:assocId=%d, staId=%d, staMac="
1615 MAC_ADDRESS_STR, i + 1,
1616 pAssocStasArray->assocId,
1617 pAssocStasArray->staId,
1618 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
1619 bytes));
1620 pAssocStasArray++;
1621 }
1622 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301623 qdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas); /* Release caller allocated memory here */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301625 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 case eSAP_REMAIN_CHAN_READY:
1627 hdd_remain_chan_ready_handler(pHostapdAdapter,
1628 pSapEvent->sapevt.sap_roc_ind.scan_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301629 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630 case eSAP_SEND_ACTION_CNF:
1631 hdd_send_action_cnf(pHostapdAdapter,
1632 (eSAP_STATUS_SUCCESS ==
1633 pSapEvent->sapevt.sapActionCnf.
1634 actionSendSuccess) ? true : false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301635 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001636 case eSAP_UNKNOWN_STA_JOIN:
1637 snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
1638 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1639 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1640 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1641 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1642 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1643 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1644 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1645 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1646 wrqu.data.pointer = unknownSTAEvent;
1647 wrqu.data.length = strlen(unknownSTAEvent);
1648 we_custom_event_generic = (uint8_t *) unknownSTAEvent;
1649 hddLog(LOGE, "%s", unknownSTAEvent);
1650 break;
1651
1652 case eSAP_MAX_ASSOC_EXCEEDED:
1653 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
1654 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1655 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1656 " one or more devices to enable the new device connection",
1657 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1658 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1659 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1660 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1661 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1662 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
1663 bytes[5]);
1664 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1665 wrqu.data.pointer = maxAssocExceededEvent;
1666 wrqu.data.length = strlen(maxAssocExceededEvent);
1667 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
1668 hddLog(LOG1, "%s", maxAssocExceededEvent);
1669 break;
1670 case eSAP_STA_ASSOC_IND:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301671 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672
1673 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
1674 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
1675 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301676 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677
1678 case eSAP_MAC_TRIG_STOP_BSS_EVENT:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301679 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301681 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001682 hddLog(LOGW, FL("hdd_stop_bss_link failed %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301683 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001684 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301685 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001686
1687 case eSAP_CHANNEL_CHANGE_EVENT:
1688 hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event"));
1689 /* Prevent suspend for new channel */
1690 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1691 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1692 /* Allow suspend for old channel */
1693 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1694 pHddApCtx->operatingChannel);
1695 /* SME/PE is already updated for new operation channel. So update
1696 * HDD layer also here. This resolves issue in AP-AP mode where
1697 * AP1 channel is changed due to RADAR then CAC is going on and
1698 * START_BSS on new channel has not come to HDD. At this case if
1699 * AP2 is start it needs current operation channel for MCC DFS
1700 * restiction
1701 */
1702 pHddApCtx->operatingChannel =
1703 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1704 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1705 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1706 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1707 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1708 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1709 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1710 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1711 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1712 pHddApCtx->sapConfig.acs_cfg.ch_width =
1713 pSapEvent->sapevt.sap_ch_selected.ch_width;
1714
1715 /* Indicate operating channel change to hostapd
1716 * only for non driver override acs
1717 */
1718 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
1719 pHddCtx->config->force_sap_acs)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301720 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 else
1722 return hdd_chan_change_notify(pHostapdAdapter, dev,
1723 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1724
1725#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1726 case eSAP_ACS_SCAN_SUCCESS_EVENT:
1727 pHddCtx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1728 hddLog(LOG1, FL("Reusing Last ACS scan result for %d sec"),
1729 ACS_SCAN_EXPIRY_TIMEOUT_S);
Anurag Chouhan210db072016-02-22 18:42:15 +05301730 qdf_mc_timer_stop(&pHddCtx->skip_acs_scan_timer);
1731 qdf_status = qdf_mc_timer_start(&pHddCtx->skip_acs_scan_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 ACS_SCAN_EXPIRY_TIMEOUT_S *
1733 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301734 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001735 hddLog(LOGE,
1736 FL("Failed to start ACS scan expiry timer"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301737 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738#endif
1739
1740 case eSAP_DFS_NOL_GET:
1741 hddLog(LOG1,
1742 FL("Received eSAP_DFS_NOL_GET event"));
1743#if defined CONFIG_CNSS
1744 /* get the dfs nol from cnss */
1745 ret =
1746 cnss_wlan_get_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1747 pDfsList,
1748 pSapEvent->sapevt.sapDfsNolInfo.
1749 sDfsList);
1750
1751 if (ret > 0) {
1752 hddLog(LOG2,
1753 FL("Get %d bytes of dfs nol from cnss"), ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301754 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001755 } else {
1756 hddLog(LOG2,
1757 FL("No dfs nol entry in CNSS, ret: %d"), ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301758 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001759 }
1760#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301761 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001762#endif
1763 case eSAP_DFS_NOL_SET:
1764 hddLog(LOG1, FL("Received eSAP_DFS_NOL_SET event"));
1765#if defined CONFIG_CNSS
1766 /* set the dfs nol to cnss */
1767 ret =
1768 cnss_wlan_set_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1769 pDfsList,
1770 pSapEvent->sapevt.sapDfsNolInfo.
1771 sDfsList);
1772
1773 if (ret) {
1774 hddLog(LOG2,
1775 FL("Failed to set dfs nol - ret: %d"),
1776 ret);
1777 } else {
1778 hddLog(LOG2, FL(" Set %d bytes dfs nol to cnss"),
1779 pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
1780 }
1781#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301782 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001783#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301784 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785 case eSAP_ACS_CHANNEL_SELECTED:
1786 hddLog(LOG1, FL("ACS Completed for wlan%d"),
1787 pHostapdAdapter->dev->ifindex);
1788 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
1789 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
1790 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1791 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1792 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1793 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1794 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1795 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1796 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1797 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1798 pHddApCtx->sapConfig.acs_cfg.ch_width =
1799 pSapEvent->sapevt.sap_ch_selected.ch_width;
1800 /* send vendor event to hostapd only for hostapd based acs*/
1801 if (!pHddCtx->config->force_sap_acs)
1802 wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301803 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301804 case eSAP_ECSA_CHANGE_CHAN_IND:
1805 hddLog(LOG1,
1806 FL("Channel change indication from peer for channel %d"),
1807 pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
1808 if (hdd_softap_set_channel_change(dev,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301809 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
1810 CH_WIDTH_MAX))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301811 return QDF_STATUS_E_FAILURE;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301812 else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301813 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301814
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815 default:
1816 hddLog(LOG1, "SAP message is not handled");
1817 goto stopbss;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301818 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001819 }
1820 wireless_send_event(dev, we_event, &wrqu,
1821 (char *)we_custom_event_generic);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301822 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823
1824stopbss:
1825 {
1826 uint8_t we_custom_event[64];
1827 char *stopBssEvent = "STOP-BSS.response"; /* 17 */
1828 int event_len = strlen(stopBssEvent);
1829
1830 hddLog(LOG1, FL("BSS stop status = %s"),
1831 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1832 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1833
1834 /* Change the BSS state now since, as we are shutting things down,
1835 * we don't want interfaces to become re-enabled */
1836 pHostapdState->bssState = BSS_STOP;
1837
1838 if (0 !=
1839 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1840 nAPAutoShutOff) {
Anurag Chouhan210db072016-02-22 18:42:15 +05301841 if (QDF_TIMER_STATE_RUNNING ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001842 pHddApCtx->hdd_ap_inactivity_timer.state) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301843 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301844 qdf_mc_timer_stop(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301846 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001847 hddLog(LOGE,
1848 FL("Failed to stop AP inactivity timer"));
1849 }
1850 }
1851
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301852 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301853 qdf_mc_timer_destroy(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001854 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301855 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1857 }
1858#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1859 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1860#endif
1861
1862 /* Stop the pkts from n/w stack as we are going to free all of
1863 * the TX WMM queues for all STAID's */
1864 hdd_hostapd_stop(dev);
1865
1866 /* reclaim all resources allocated to the BSS */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301867 qdf_status = hdd_softap_stop_bss(pHostapdAdapter);
1868 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869 hddLog(LOGW,
1870 FL("hdd_softap_stop_bss failed %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301871 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001872 }
1873
1874 /* once the event is set, structure dev/pHostapdAdapter should
1875 * not be touched since they are now subject to being deleted
1876 * by another thread */
1877 if (eSAP_STOP_BSS_EVENT == sapEvent)
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301878 qdf_event_set(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001879
1880 /* notify userspace that the BSS has stopped */
1881 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1882 memcpy(&we_custom_event, stopBssEvent, event_len);
1883 memset(&wrqu, 0, sizeof(wrqu));
1884 wrqu.data.length = event_len;
1885 we_event = IWEVCUSTOM;
1886 we_custom_event_generic = we_custom_event;
1887 wireless_send_event(dev, we_event, &wrqu,
1888 (char *)we_custom_event_generic);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001889 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001890 /* Send SCC/MCC Switching event to IPA */
1891 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1892 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301893 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001894}
1895
1896int hdd_softap_unpack_ie(tHalHandle halHandle,
1897 eCsrEncryptionType *pEncryptType,
1898 eCsrEncryptionType *mcEncryptType,
1899 eCsrAuthType *pAuthType,
1900 bool *pMFPCapable,
1901 bool *pMFPRequired,
1902 uint16_t gen_ie_len, uint8_t *gen_ie)
1903{
1904 tDot11fIERSN dot11RSNIE;
1905 tDot11fIEWPA dot11WPAIE;
1906
1907 uint8_t *pRsnIe;
1908 uint16_t RSNIeLen;
1909
1910 if (NULL == halHandle) {
1911 hddLog(LOGE, FL("Error haHandle returned NULL"));
1912 return -EINVAL;
1913 }
1914 /* Validity checks */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301915 if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001916 || (gen_ie_len >
Anurag Chouhan6d760662016-02-20 16:05:43 +05301917 QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918 return -EINVAL;
1919 /* Type check */
1920 if (gen_ie[0] == DOT11F_EID_RSN) {
1921 /* Validity checks */
1922 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
1923 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301924 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001925 }
1926 /* Skip past the EID byte and length byte */
1927 pRsnIe = gen_ie + 2;
1928 RSNIeLen = gen_ie_len - 2;
1929 /* Unpack the RSN IE */
1930 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1931 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
1932 pRsnIe, RSNIeLen, &dot11RSNIE);
1933 /* Copy out the encryption and authentication types */
1934 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
1935 dot11RSNIE.pwise_cipher_suite_count);
1936 hddLog(LOG1, FL("authentication suite count: %d"),
1937 dot11RSNIE.akm_suite_count);
1938 /*Here we have followed the apple base code,
1939 but probably I suspect we can do something different */
1940 /* dot11RSNIE.akm_suite_count */
1941 /* Just translate the FIRST one */
1942 *pAuthType =
1943 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suites[0]);
1944 /* dot11RSNIE.pwise_cipher_suite_count */
1945 *pEncryptType =
1946 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1947 pwise_cipher_suites[0]);
1948 /* dot11RSNIE.gp_cipher_suite_count */
1949 *mcEncryptType =
1950 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1951 gp_cipher_suite);
1952 /* Set the PMKSA ID Cache for this interface */
1953 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1954 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
1955 /* Calling csr_roam_set_pmkid_cache to configure the PMKIDs into the cache */
1956 } else if (gen_ie[0] == DOT11F_EID_WPA) {
1957 /* Validity checks */
1958 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
1959 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301960 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 }
1962 /* Skip past the EID byte and length byte - and four byte WiFi OUI */
1963 pRsnIe = gen_ie + 2 + 4;
1964 RSNIeLen = gen_ie_len - (2 + 4);
1965 /* Unpack the WPA IE */
1966 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1967 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
1968 pRsnIe, RSNIeLen, &dot11WPAIE);
1969 /* Copy out the encryption and authentication types */
1970 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
1971 dot11WPAIE.unicast_cipher_count);
1972 hddLog(LOG1, FL("WPA authentication suite count: %d"),
1973 dot11WPAIE.auth_suite_count);
1974 /* dot11WPAIE.auth_suite_count */
1975 /* Just translate the FIRST one */
1976 *pAuthType =
1977 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
1978 /* dot11WPAIE.unicast_cipher_count */
1979 *pEncryptType =
1980 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1981 unicast_ciphers[0]);
1982 /* dot11WPAIE.unicast_cipher_count */
1983 *mcEncryptType =
1984 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1985 multicast_cipher);
1986 *pMFPCapable = false;
1987 *pMFPRequired = false;
1988 } else {
1989 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301990 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001991 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301992 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001993}
1994
1995/**
1996 * hdd_softap_set_channel_change() -
1997 * This function to support SAP channel change with CSA IE
1998 * set in the beacons.
1999 *
2000 * @dev: pointer to the net device.
2001 * @target_channel: target channel number.
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302002 * @target_bw: Target bandwidth to move.
2003 * If no bandwidth is specified, the value is CH_WIDTH_MAX
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002004 *
2005 * Return: 0 for success, non zero for failure
2006 */
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302007int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
Amar Singhale4f28ee2015-10-21 14:36:56 -07002008 enum ch_width target_bw)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002009{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302010 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 int ret = 0;
2012 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2013 hdd_context_t *pHddCtx = NULL;
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302014 hdd_adapter_t *sta_adapter;
2015 hdd_station_ctx_t *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002016
2017#ifndef WLAN_FEATURE_MBSSID
2018 v_CONTEXT_t p_cds_context =
2019 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2020#endif
2021
2022 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2023 ret = wlan_hdd_validate_context(pHddCtx);
2024 if (ret) {
2025 hddLog(LOGE, FL("invalid HDD context"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002026 return ret;
2027 }
2028
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +05302029 ret = hdd_validate_channel_and_bandwidth(pHostapdAdapter,
2030 target_channel, target_bw);
2031 if (ret) {
2032 hdd_err("Invalid CH and BW combo");
2033 return ret;
2034 }
2035
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302036 sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
2037 /*
2038 * conc_custom_rule1:
2039 * Force SCC for SAP + STA
2040 * if STA is already connected then we shouldn't allow
2041 * channel switch in SAP interface.
2042 */
2043 if (sta_adapter && pHddCtx->config->conc_custom_rule1) {
2044 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
2045 if (hdd_conn_is_connected(sta_ctx)) {
2046 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
2047 return -EBUSY;
2048 }
2049 }
2050
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302051 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002052 if (pHddCtx->dfs_radar_found == true) {
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302053 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002054 hddLog(LOGE, FL("Channel switch in progress!!"));
2055 return -EBUSY;
2056 }
2057 /*
2058 * Set the dfs_radar_found flag to mimic channel change
2059 * when a radar is found. This will enable synchronizing
2060 * SAP and HDD states similar to that of radar indication.
2061 * Suspend the netif queues to stop queuing Tx frames
2062 * from upper layers. netif queues will be resumed
2063 * once the channel change is completed and SAP will
2064 * post eSAP_START_BSS_EVENT success event to HDD.
2065 */
2066 pHddCtx->dfs_radar_found = true;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302067 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002068 /*
2069 * Post the Channel Change request to SAP.
2070 */
2071 status = wlansap_set_channel_change_with_csa(
2072#ifdef WLAN_FEATURE_MBSSID
2073 WLAN_HDD_GET_SAP_CTX_PTR
2074 (pHostapdAdapter),
2075#else
2076 p_cds_context,
2077#endif
2078 (uint32_t)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302079 target_channel,
2080 target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002081
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302082 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002083 hddLog(LOGE,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302084 FL("SAP set channel failed for channel = %d, bw:%d"),
2085 target_channel, target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 /*
2087 * If channel change command fails then clear the
2088 * radar found flag and also restart the netif
2089 * queues.
2090 */
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302091 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002092 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302093 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094
2095 ret = -EINVAL;
2096 }
2097
2098 return ret;
2099}
2100
2101int
2102static __iw_softap_set_ini_cfg(struct net_device *dev,
2103 struct iw_request_info *info,
2104 union iwreq_data *wrqu, char *extra)
2105{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302106 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002107 int ret = 0; /* success */
2108 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2109 hdd_context_t *pHddCtx;
2110
Jeff Johnson02050312016-02-11 18:40:28 -08002111 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002112
2113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2114 ret = wlan_hdd_validate_context(pHddCtx);
2115 if (ret != 0) {
2116 hddLog(LOGE, FL("HDD context is not valid"));
2117 return ret;
2118 }
2119
2120 hddLog(LOG1, FL("Received data %s"), extra);
2121
2122 vstatus = hdd_execute_global_config_command(pHddCtx, extra);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302123 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002124 ret = -EINVAL;
2125 }
2126
2127 return ret;
2128}
2129
2130int
2131static iw_softap_set_ini_cfg(struct net_device *dev,
2132 struct iw_request_info *info,
2133 union iwreq_data *wrqu, char *extra)
2134{
2135 int ret;
2136
2137 cds_ssr_protect(__func__);
2138 ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
2139 cds_ssr_unprotect(__func__);
2140
2141 return ret;
2142}
2143
2144int
2145static __iw_softap_get_ini_cfg(struct net_device *dev,
2146 struct iw_request_info *info,
2147 union iwreq_data *wrqu, char *extra)
2148{
2149 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2150 hdd_context_t *pHddCtx;
2151 int ret = 0;
2152
Jeff Johnson02050312016-02-11 18:40:28 -08002153 ENTER_DEV(dev);
2154
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002155 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2156 ret = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson02050312016-02-11 18:40:28 -08002157 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002158 return ret;
Jeff Johnson02050312016-02-11 18:40:28 -08002159
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160 hddLog(LOG1, FL("Printing CLD global INI Config"));
2161 hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN);
2162 wrqu->data.length = strlen(extra) + 1;
2163
2164 return 0;
2165}
2166
2167int
2168static iw_softap_get_ini_cfg(struct net_device *dev,
2169 struct iw_request_info *info,
2170 union iwreq_data *wrqu, char *extra)
2171{
2172 int ret;
2173
2174 cds_ssr_protect(__func__);
2175 ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
2176 cds_ssr_unprotect(__func__);
2177
2178 return ret;
2179}
2180
Govind Singha471e5e2015-10-12 17:11:14 +05302181/**
2182 * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
2183 * @dev: device upon which the ioctl was received
2184 * @info: ioctl request information
2185 * @wrqu: ioctl request data
2186 * @extra: ioctl extra data
2187 *
2188 * Return: 0 on success, non-zero on error
2189 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002190static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
2191 struct iw_request_info *info,
2192 union iwreq_data *wrqu, char *extra)
2193{
Govind Singha471e5e2015-10-12 17:11:14 +05302194 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2195 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 int *value = (int *)extra;
2197 int sub_cmd = value[0];
Govind Singha471e5e2015-10-12 17:11:14 +05302198 hdd_context_t *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002199
Jeff Johnson02050312016-02-11 18:40:28 -08002200 ENTER_DEV(dev);
2201
Govind Singha471e5e2015-10-12 17:11:14 +05302202 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2203 ret = wlan_hdd_validate_context(hdd_ctx);
2204 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002205 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002206
2207 switch (sub_cmd) {
2208#ifdef DEBUG
2209 case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
2210 hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
2211 value[1], value[2]);
Govind Singha471e5e2015-10-12 17:11:14 +05302212 ret = wma_cli_set2_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213 GEN_PARAM_CRASH_INJECT,
2214 value[1], value[2],
2215 GEN_CMD);
2216 break;
2217#endif
2218 case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
2219 hdd_info("WE_DUMP_DP_TRACE: %d %d",
2220 value[1], value[2]);
2221 if (value[1] == DUMP_DP_TRACE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302222 qdf_dp_trace_dump_all(value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223 break;
Govind Singha471e5e2015-10-12 17:11:14 +05302224 case QCSAP_ENABLE_FW_PROFILE:
2225 hddLog(LOG1, "QCSAP_ENABLE_FW_PROFILE: %d %d",
2226 value[1], value[2]);
2227 ret = wma_cli_set2_command(adapter->sessionId,
2228 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2229 value[1], value[2], DBG_CMD);
2230 break;
2231 case QCSAP_SET_FW_PROFILE_HIST_INTVL:
2232 hddLog(LOG1, "QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
2233 value[1], value[2]);
2234 ret = wma_cli_set2_command(adapter->sessionId,
2235 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2236 value[1], value[2], DBG_CMD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237 default:
2238 hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
2239 break;
2240 }
2241
2242out:
2243 return ret;
2244}
2245
2246static int iw_softap_set_two_ints_getnone(struct net_device *dev,
2247 struct iw_request_info *info,
2248 union iwreq_data *wrqu, char *extra)
2249{
2250 int ret;
2251
2252 cds_ssr_protect(__func__);
2253 ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
2254 cds_ssr_unprotect(__func__);
2255
2256 return ret;
2257}
2258
Anurag Chouhan6d760662016-02-20 16:05:43 +05302259static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002260{
2261 int i;
2262 uint8_t *macArray;
2263
2264 for (i = 0; i < size; i++) {
2265 macArray = (macList + i)->bytes;
2266 pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n",
2267 i, MAC_ADDR_ARRAY(macArray));
2268 }
2269 return;
2270}
2271
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302272static QDF_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002273{
2274 eSapMacAddrACL acl_mode;
Anurag Chouhan6d760662016-02-20 16:05:43 +05302275 struct qdf_mac_addr MacList[MAX_ACL_MAC_ADDRESS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002276 uint8_t listnum;
2277 void *p_cds_gctx = NULL;
2278
2279#ifdef WLAN_FEATURE_MBSSID
2280 p_cds_gctx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter);
2281#else
2282 p_cds_gctx = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2283#endif
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302284 qdf_mem_zero(&MacList[0], sizeof(MacList));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302285 if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(p_cds_gctx, &acl_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002286 pr_info("******** ACL MODE *********\n");
2287 switch (acl_mode) {
2288 case eSAP_ACCEPT_UNLESS_DENIED:
2289 pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
2290 break;
2291 case eSAP_DENY_UNLESS_ACCEPTED:
2292 pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
2293 break;
2294 case eSAP_SUPPORT_ACCEPT_AND_DENY:
2295 pr_info("ACL Mode = ACCEPT_AND_DENY\n");
2296 break;
2297 case eSAP_ALLOW_ALL:
2298 pr_info("ACL Mode = ALLOW_ALL\n");
2299 break;
2300 default:
2301 pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302302 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002303 }
2304 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302305 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002306 }
2307
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302308 if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002309 &MacList[0],
2310 &listnum)) {
2311 pr_info("******* WHITE LIST ***********\n");
2312 if (listnum <= MAX_ACL_MAC_ADDRESS)
2313 print_mac_list(&MacList[0], listnum);
2314 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302315 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002316 }
2317
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302318 if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002319 &MacList[0],
2320 &listnum)) {
2321 pr_info("******* BLACK LIST ***********\n");
2322 if (listnum <= MAX_ACL_MAC_ADDRESS)
2323 print_mac_list(&MacList[0], listnum);
2324 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302325 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002326 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302327 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002328}
2329
2330int
2331static __iw_softap_setparam(struct net_device *dev,
2332 struct iw_request_info *info,
2333 union iwreq_data *wrqu, char *extra)
2334{
2335 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2336 tHalHandle hHal;
2337 int *value = (int *)extra;
2338 int sub_cmd = value[0];
2339 int set_value = value[1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302340 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002341 int ret = 0; /* success */
2342 v_CONTEXT_t p_cds_context;
2343 hdd_context_t *hdd_ctx;
2344
Jeff Johnson02050312016-02-11 18:40:28 -08002345 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302346
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002347 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2348 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302349 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002350 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002351
2352 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2353 if (!hHal) {
2354 hddLog(LOGE, FL("Hal ctx is null"));
2355 return -EINVAL;
2356 }
2357
2358 p_cds_context = hdd_ctx->pcds_context;
2359 if (!p_cds_context) {
2360 hddLog(LOGE, FL("cds ctx is null"));
2361 return -ENOENT;
2362 }
2363
2364 switch (sub_cmd) {
2365 case QCASAP_SET_RADAR_DBG:
2366 hddLog(LOG1, FL("QCASAP_SET_RADAR_DBG called with: value: %d"),
2367 set_value);
2368 wlan_sap_enable_phy_error_logs(hHal, (bool) set_value);
2369 break;
2370
2371 case QCSAP_PARAM_CLR_ACL:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302372 if (QDF_STATUS_SUCCESS != wlansap_clear_acl(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002373#ifdef WLAN_FEATURE_MBSSID
2374 WLAN_HDD_GET_SAP_CTX_PTR
2375 (pHostapdAdapter)
2376#else
2377 p_cds_context
2378#endif
2379 )) {
2380 ret = -EIO;
2381 }
2382 break;
2383
2384 case QCSAP_PARAM_ACL_MODE:
2385 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
2386 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
2387 hddLog(LOGE, FL("Invalid ACL Mode value %d"),
2388 set_value);
2389 ret = -EINVAL;
2390 } else {
2391#ifdef WLAN_FEATURE_MBSSID
2392 wlansap_set_mode(WLAN_HDD_GET_SAP_CTX_PTR
2393 (pHostapdAdapter), set_value);
2394#else
2395 wlansap_set_mode(p_cds_context, set_value);
2396#endif
2397
2398 }
2399 break;
2400
2401 case QCSAP_PARAM_SET_CHANNEL_CHANGE:
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302402 if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) ||
2403 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404 hddLog(LOG1,
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302405 "SET Channel Change to new channel= %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002406 set_value);
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302407 ret = hdd_softap_set_channel_change(dev, set_value,
2408 CH_WIDTH_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409 } else {
2410 hddLog(LOGE,
2411 FL("Channel Change Failed, Device in test mode"));
2412 ret = -EINVAL;
2413 }
2414 break;
2415 case QCSAP_PARAM_AUTO_CHANNEL:
2416 if (set_value == 0 || set_value == 1)
2417 (WLAN_HDD_GET_CTX(
2418 pHostapdAdapter))->config->force_sap_acs =
2419 set_value;
2420 else
2421 ret = -EINVAL;
2422 break;
2423
2424 case QCSAP_PARAM_MAX_ASSOC:
2425 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
2426 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"),
2427 set_value);
2428 ret = -EINVAL;
2429 } else {
2430 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) {
2431 hddLog(LOGW,
2432 FL("setMaxAssoc %d > max allowed %d."),
2433 set_value,
2434 WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
2435 hddLog(LOGW,
2436 FL("Setting it to max allowed and continuing"));
2437 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
2438 }
2439 status = sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
2440 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302441 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002442 hddLog(LOGE,
2443 FL("setMaxAssoc failure, status %d"),
2444 status);
2445 ret = -EIO;
2446 }
2447 }
2448 break;
2449
2450 case QCSAP_PARAM_HIDE_SSID:
2451 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302452 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002453 status =
2454 sme_hide_ssid(hHal, pHostapdAdapter->sessionId,
2455 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302456 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 hddLog(LOGE, FL("QCSAP_PARAM_HIDE_SSID failed"));
2458 return status;
2459 }
2460 break;
2461 }
2462 case QCSAP_PARAM_SET_MC_RATE:
2463 {
2464 tSirRateUpdateInd rateUpdate = {0};
2465 struct hdd_config *pConfig = hdd_ctx->config;
2466
2467 hddLog(LOG1, "MC Target rate %d", set_value);
Anurag Chouhanc5548422016-02-24 18:33:27 +05302468 qdf_copy_macaddr(&rateUpdate.bssid,
Srinivas Girigowdaafede182015-11-18 22:36:12 -08002469 &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1;
2471 rateUpdate.dev_mode = pHostapdAdapter->device_mode;
2472 rateUpdate.mcastDataRate24GHz = set_value;
2473 rateUpdate.mcastDataRate24GHzTxFlag = 1;
2474 rateUpdate.mcastDataRate5GHz = set_value;
2475 rateUpdate.bcastDataRate = -1;
2476 status = sme_send_rate_update_ind(hHal, &rateUpdate);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302477 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478 hddLog(LOGE, FL("SET_MC_RATE failed"));
2479 ret = -1;
2480 }
2481 break;
2482 }
2483
2484 case QCSAP_PARAM_SET_TXRX_FW_STATS:
2485 {
2486 hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
2487 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2488 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
2489 set_value, VDEV_CMD);
2490 break;
2491 }
2492 /* Firmware debug log */
2493 case QCSAP_DBGLOG_LOG_LEVEL:
2494 {
2495 hddLog(LOG1, "QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
2496 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2497 WMI_DBGLOG_LOG_LEVEL,
2498 set_value, DBG_CMD);
2499 break;
2500 }
2501
2502 case QCSAP_DBGLOG_VAP_ENABLE:
2503 {
2504 hddLog(LOG1, "QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
2505 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2506 WMI_DBGLOG_VAP_ENABLE,
2507 set_value, DBG_CMD);
2508 break;
2509 }
2510
2511 case QCSAP_DBGLOG_VAP_DISABLE:
2512 {
2513 hddLog(LOG1, "QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
2514 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2515 WMI_DBGLOG_VAP_DISABLE,
2516 set_value, DBG_CMD);
2517 break;
2518 }
2519
2520 case QCSAP_DBGLOG_MODULE_ENABLE:
2521 {
2522 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
2523 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2524 WMI_DBGLOG_MODULE_ENABLE,
2525 set_value, DBG_CMD);
2526 break;
2527 }
2528
2529 case QCSAP_DBGLOG_MODULE_DISABLE:
2530 {
2531 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
2532 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2533 WMI_DBGLOG_MODULE_DISABLE,
2534 set_value, DBG_CMD);
2535 break;
2536 }
2537
2538 case QCSAP_DBGLOG_MOD_LOG_LEVEL:
2539 {
2540 hddLog(LOG1, "QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
2541 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2542 WMI_DBGLOG_MOD_LOG_LEVEL,
2543 set_value, DBG_CMD);
2544 break;
2545 }
2546
2547 case QCSAP_DBGLOG_TYPE:
2548 {
2549 hddLog(LOG1, "QCSAP_DBGLOG_TYPE val %d", set_value);
2550 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2551 WMI_DBGLOG_TYPE,
2552 set_value, DBG_CMD);
2553 break;
2554 }
2555 case QCSAP_DBGLOG_REPORT_ENABLE:
2556 {
2557 hddLog(LOG1, "QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
2558 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2559 WMI_DBGLOG_REPORT_ENABLE,
2560 set_value, DBG_CMD);
2561 break;
2562 }
2563 case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
2564 {
2565 cds_set_mcc_latency(pHostapdAdapter, set_value);
2566 break;
2567 }
2568
2569 case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
2570 {
2571 hddLog(LOG1,
2572 FL("iwpriv cmd to set MCC quota value %dms"),
2573 set_value);
2574 ret = cds_go_set_mcc_p2p_quota(pHostapdAdapter,
2575 set_value);
2576 break;
2577 }
2578
2579 case QCASAP_TXRX_FWSTATS_RESET:
2580 {
2581 hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
2582 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2583 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
2584 set_value, VDEV_CMD);
2585 break;
2586 }
2587
2588 case QCSAP_PARAM_RTSCTS:
2589 {
2590 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2591 WMI_VDEV_PARAM_ENABLE_RTSCTS,
2592 set_value, VDEV_CMD);
2593 if (ret) {
2594 hddLog(LOGE, "FAILED TO SET RTSCTS at SAP");
2595 ret = -EIO;
2596 }
2597 break;
2598 }
2599 case QCASAP_SET_11N_RATE:
2600 {
2601 uint8_t preamble = 0, nss = 0, rix = 0;
2602 tsap_Config_t *pConfig =
2603 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2604
2605 hddLog(LOG1, "SET_HT_RATE val %d", set_value);
2606
2607 if (set_value != 0xff) {
2608 rix = RC_2_RATE_IDX(set_value);
2609 if (set_value & 0x80) {
2610 if (pConfig->SapHw_mode ==
2611 eCSR_DOT11_MODE_11b
2612 || pConfig->SapHw_mode ==
2613 eCSR_DOT11_MODE_11b_ONLY
2614 || pConfig->SapHw_mode ==
2615 eCSR_DOT11_MODE_11g
2616 || pConfig->SapHw_mode ==
2617 eCSR_DOT11_MODE_11g_ONLY
2618 || pConfig->SapHw_mode ==
2619 eCSR_DOT11_MODE_abg
2620 || pConfig->SapHw_mode ==
2621 eCSR_DOT11_MODE_11a) {
2622 hddLog(LOGE,
2623 "Not valid mode for HT");
2624 ret = -EIO;
2625 break;
2626 }
2627 preamble = WMI_RATE_PREAMBLE_HT;
2628 nss = HT_RC_2_STREAMS(set_value) - 1;
2629 } else if (set_value & 0x10) {
2630 if (pConfig->SapHw_mode ==
2631 eCSR_DOT11_MODE_11a) {
2632 hddLog(LOGE, "Not valid for cck");
2633 ret = -EIO;
2634 break;
2635 }
2636 preamble = WMI_RATE_PREAMBLE_CCK;
2637 /* Enable Short preamble always
2638 * for CCK except 1mbps
2639 */
2640 if (rix != 0x3)
2641 rix |= 0x4;
2642 } else {
2643 if (pConfig->SapHw_mode ==
2644 eCSR_DOT11_MODE_11b
2645 || pConfig->SapHw_mode ==
2646 eCSR_DOT11_MODE_11b_ONLY) {
2647 hddLog(LOGE, "Not valid for OFDM");
2648 ret = -EIO;
2649 break;
2650 }
2651 preamble = WMI_RATE_PREAMBLE_OFDM;
2652 }
2653 set_value = (preamble << 6) | (nss << 4) | rix;
2654 }
2655 hddLog(LOG1, "SET_HT_RATE val %d rix %d preamble %x nss %d",
2656 set_value, rix, preamble, nss);
2657 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2658 WMI_VDEV_PARAM_FIXED_RATE,
2659 set_value, VDEV_CMD);
2660 break;
2661 }
2662
2663 case QCASAP_SET_VHT_RATE:
2664 {
2665 uint8_t preamble = 0, nss = 0, rix = 0;
2666 tsap_Config_t *pConfig =
2667 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2668
2669 if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
2670 pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
2671 hddLog(LOGE,
2672 FL("SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d"),
2673 pConfig->SapHw_mode, pConfig->channel);
2674 ret = -EIO;
2675 break;
2676 }
2677
2678 if (set_value != 0xff) {
2679 rix = RC_2_RATE_IDX_11AC(set_value);
2680 preamble = WMI_RATE_PREAMBLE_VHT;
2681 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
2682
2683 set_value = (preamble << 6) | (nss << 4) | rix;
2684 }
2685 hddLog(LOG1, "SET_VHT_RATE val %d rix %d preamble %x nss %d",
2686 set_value, rix, preamble, nss);
2687
2688 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2689 WMI_VDEV_PARAM_FIXED_RATE,
2690 set_value, VDEV_CMD);
2691 break;
2692 }
2693
2694 case QCASAP_SHORT_GI:
2695 {
2696 hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value);
2697
2698 /* same as 40MHZ */
2699 ret = sme_update_ht_config(hHal, pHostapdAdapter->sessionId,
2700 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
2701 set_value);
2702 if (ret)
2703 hddLog(LOGE,
2704 "Failed to set ShortGI value ret(%d)", ret);
2705 break;
2706 }
2707
2708 case QCSAP_SET_AMPDU:
2709 {
2710 hddLog(LOG1, "QCSAP_SET_AMPDU %d", set_value);
2711 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2712 GEN_VDEV_PARAM_AMPDU,
2713 set_value, GEN_CMD);
2714 break;
2715 }
2716
2717 case QCSAP_SET_AMSDU:
2718 {
2719 hddLog(LOG1, "QCSAP_SET_AMSDU %d", set_value);
2720 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2721 GEN_VDEV_PARAM_AMSDU,
2722 set_value, GEN_CMD);
2723 break;
2724 }
2725 case QCSAP_GTX_HT_MCS:
2726 {
2727 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
2728 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2729 WMI_VDEV_PARAM_GTX_HT_MCS,
2730 set_value, GTX_CMD);
2731 break;
2732 }
2733
2734 case QCSAP_GTX_VHT_MCS:
2735 {
2736 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
2737 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2738 WMI_VDEV_PARAM_GTX_VHT_MCS,
2739 set_value, GTX_CMD);
2740 break;
2741 }
2742
2743 case QCSAP_GTX_USRCFG:
2744 {
2745 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
2746 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2747 WMI_VDEV_PARAM_GTX_USR_CFG,
2748 set_value, GTX_CMD);
2749 break;
2750 }
2751
2752 case QCSAP_GTX_THRE:
2753 {
2754 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
2755 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2756 WMI_VDEV_PARAM_GTX_THRE,
2757 set_value, GTX_CMD);
2758 break;
2759 }
2760
2761 case QCSAP_GTX_MARGIN:
2762 {
2763 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
2764 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2765 WMI_VDEV_PARAM_GTX_MARGIN,
2766 set_value, GTX_CMD);
2767 break;
2768 }
2769
2770 case QCSAP_GTX_STEP:
2771 {
2772 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
2773 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2774 WMI_VDEV_PARAM_GTX_STEP,
2775 set_value, GTX_CMD);
2776 break;
2777 }
2778
2779 case QCSAP_GTX_MINTPC:
2780 {
2781 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
2782 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2783 WMI_VDEV_PARAM_GTX_MINTPC,
2784 set_value, GTX_CMD);
2785 break;
2786 }
2787
2788 case QCSAP_GTX_BWMASK:
2789 {
2790 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
2791 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2792 WMI_VDEV_PARAM_GTX_BW_MASK,
2793 set_value, GTX_CMD);
2794 break;
2795 }
2796
2797#ifdef QCA_PKT_PROTO_TRACE
2798 case QCASAP_SET_DEBUG_LOG:
2799 {
2800 hdd_context_t *pHddCtx =
2801 WLAN_HDD_GET_CTX(pHostapdAdapter);
2802
2803 hddLog(LOG1, "QCASAP_SET_DEBUG_LOG val %d", set_value);
2804 /* Trace buffer dump only */
2805 if (CDS_PKT_TRAC_DUMP_CMD == set_value) {
2806 cds_pkt_trace_buf_dump();
2807 break;
2808 }
2809 pHddCtx->config->gEnableDebugLog = set_value;
2810 break;
2811 }
2812#endif /* QCA_PKT_PROTO_TRACE */
2813
2814 case QCASAP_SET_TM_LEVEL:
2815 {
2816 hddLog(LOG1, "Set Thermal Mitigation Level %d", set_value);
2817 (void)sme_set_thermal_level(hHal, set_value);
2818 break;
2819 }
2820
2821 case QCASAP_SET_DFS_IGNORE_CAC:
2822 {
2823 hddLog(LOG1, "Set Dfs ignore CAC %d", set_value);
2824
2825 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2826 return -EINVAL;
2827
2828 ret = wlansap_set_dfs_ignore_cac(hHal, set_value);
2829 break;
2830 }
2831
2832 case QCASAP_SET_DFS_TARGET_CHNL:
2833 {
2834 hddLog(LOG1, "Set Dfs target channel %d", set_value);
2835
2836 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2837 return -EINVAL;
2838
2839 ret = wlansap_set_dfs_target_chnl(hHal, set_value);
2840 break;
2841 }
2842
2843 case QCASAP_SET_DFS_NOL:
2844 wlansap_set_dfs_nol(
2845#ifdef WLAN_FEATURE_MBSSID
2846 WLAN_HDD_GET_SAP_CTX_PTR
2847 (pHostapdAdapter),
2848#else
2849 p_cds_context,
2850#endif
2851 (eSapDfsNolType) set_value);
2852 break;
2853
2854 case QCASAP_SET_RADAR_CMD:
2855 {
2856 hdd_context_t *pHddCtx =
2857 WLAN_HDD_GET_CTX(pHostapdAdapter);
2858 uint8_t ch =
2859 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
2860 operatingChannel;
2861 bool isDfsch;
2862
2863 isDfsch = (CHANNEL_STATE_DFS ==
2864 cds_get_channel_state(ch));
2865
2866 hddLog(LOG1, FL("Set QCASAP_SET_RADAR_CMD val %d"), set_value);
2867
2868 if (!pHddCtx->dfs_radar_found && isDfsch) {
2869 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2870 WMA_VDEV_DFS_CONTROL_CMDID,
2871 set_value, VDEV_CMD);
2872 } else {
2873 hddLog(LOGE,
2874 FL("Ignore, radar_found: %d, dfs_channel: %d"),
2875 pHddCtx->dfs_radar_found, isDfsch);
2876 }
2877 break;
2878 }
2879 case QCASAP_TX_CHAINMASK_CMD:
2880 {
2881 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD val %d", set_value);
2882 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2883 WMI_PDEV_PARAM_TX_CHAIN_MASK,
2884 set_value, PDEV_CMD);
2885 break;
2886 }
2887
2888 case QCASAP_RX_CHAINMASK_CMD:
2889 {
2890 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD val %d", set_value);
2891 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2892 WMI_PDEV_PARAM_RX_CHAIN_MASK,
2893 set_value, PDEV_CMD);
2894 break;
2895 }
2896
2897 case QCASAP_NSS_CMD:
2898 {
2899 hddLog(LOG1, "QCASAP_NSS_CMD val %d", set_value);
2900 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2901 WMI_VDEV_PARAM_NSS,
2902 set_value, VDEV_CMD);
2903 break;
2904 }
2905
2906 case QCSAP_IPA_UC_STAT:
2907 {
2908 /* If input value is non-zero get stats */
2909 switch (set_value) {
2910 case 1:
2911 hdd_ipa_uc_stat_request(pHostapdAdapter, set_value);
2912 break;
2913 case 3:
2914 hdd_ipa_uc_rt_debug_host_dump(
2915 WLAN_HDD_GET_CTX(pHostapdAdapter));
2916 break;
2917 default:
2918 /* place holder for stats clean up
2919 * Stats clean not implemented yet on firmware and ipa
2920 */
2921 break;
2922 }
2923 return ret;
2924 }
2925
2926 case QCASAP_SET_PHYMODE:
2927 {
2928 hdd_context_t *phddctx =
2929 WLAN_HDD_GET_CTX(pHostapdAdapter);
2930
2931 ret =
2932 wlan_hdd_update_phymode(dev, hHal, set_value,
2933 phddctx);
2934 break;
2935 }
2936 case QCASAP_DUMP_STATS:
2937 {
2938 hddLog(LOG1, "QCASAP_DUMP_STATS val %d", set_value);
2939 hdd_wlan_dump_stats(pHostapdAdapter, set_value);
2940 break;
2941 }
2942 case QCASAP_CLEAR_STATS:
2943 {
2944 hdd_context_t *hdd_ctx =
2945 WLAN_HDD_GET_CTX(pHostapdAdapter);
2946 hddLog(LOG1, "QCASAP_CLEAR_STATS val %d", set_value);
2947 switch (set_value) {
2948 case WLAN_HDD_STATS:
2949 memset(&pHostapdAdapter->stats, 0,
2950 sizeof(pHostapdAdapter->stats));
2951 memset(&pHostapdAdapter->hdd_stats, 0,
2952 sizeof(pHostapdAdapter->hdd_stats));
2953 break;
2954 case WLAN_TXRX_HIST_STATS:
2955 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
2956 break;
2957 case WLAN_HDD_NETIF_OPER_HISTORY:
2958 wlan_hdd_clear_netif_queue_history(hdd_ctx);
2959 break;
2960 default:
2961 ol_txrx_clear_stats(set_value);
2962 }
2963 break;
2964 }
Govind Singha471e5e2015-10-12 17:11:14 +05302965 case QCSAP_START_FW_PROFILING:
2966 hddLog(LOG1, "QCSAP_START_FW_PROFILING %d", set_value);
2967 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2968 WMI_WLAN_PROFILE_TRIGGER_CMDID,
2969 set_value, DBG_CMD);
2970 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002971 default:
2972 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
2973 sub_cmd, set_value);
2974 ret = -EINVAL;
2975 break;
2976 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302977 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002978 return ret;
2979}
2980
2981int
2982static iw_softap_setparam(struct net_device *dev,
2983 struct iw_request_info *info,
2984 union iwreq_data *wrqu, char *extra)
2985{
2986 int ret;
2987
2988 cds_ssr_protect(__func__);
2989 ret = __iw_softap_setparam(dev, info, wrqu, extra);
2990 cds_ssr_unprotect(__func__);
2991
2992 return ret;
2993}
2994
2995int
2996static __iw_softap_getparam(struct net_device *dev,
2997 struct iw_request_info *info,
2998 union iwreq_data *wrqu, char *extra)
2999{
3000 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3001 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3002 int *value = (int *)extra;
3003 int sub_cmd = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303004 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003005 int ret;
3006 hdd_context_t *hdd_ctx;
3007
Jeff Johnson02050312016-02-11 18:40:28 -08003008 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303009
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003010 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3011 ret = wlan_hdd_validate_context(hdd_ctx);
3012 if (0 != ret)
3013 return ret;
3014
3015 switch (sub_cmd) {
3016 case QCSAP_PARAM_MAX_ASSOC:
3017 status =
3018 sme_cfg_get_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
3019 (uint32_t *) value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303020 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003021 hddLog(LOGE,
3022 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),
3023 status);
3024 ret = -EIO;
3025 }
3026 break;
3027
3028 case QCSAP_PARAM_AUTO_CHANNEL:
3029 *value = (WLAN_HDD_GET_CTX
3030 (pHostapdAdapter))->config->force_sap_acs;
3031 break;
3032
3033 case QCSAP_PARAM_GET_WLAN_DBG:
3034 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303035 qdf_trace_display();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003036 *value = 0;
3037 break;
3038 }
3039
3040 case QCSAP_PARAM_RTSCTS:
3041 {
3042 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3043 WMI_VDEV_PARAM_ENABLE_RTSCTS,
3044 VDEV_CMD);
3045 break;
3046 }
3047
3048 case QCASAP_SHORT_GI:
3049 {
3050 *value = (int)sme_get_ht_config(hHal,
3051 pHostapdAdapter->
3052 sessionId,
3053 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
3054 break;
3055 }
3056
3057 case QCSAP_GTX_HT_MCS:
3058 {
3059 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
3060 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3061 WMI_VDEV_PARAM_GTX_HT_MCS,
3062 GTX_CMD);
3063 break;
3064 }
3065
3066 case QCSAP_GTX_VHT_MCS:
3067 {
3068 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
3069 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3070 WMI_VDEV_PARAM_GTX_VHT_MCS,
3071 GTX_CMD);
3072 break;
3073 }
3074
3075 case QCSAP_GTX_USRCFG:
3076 {
3077 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
3078 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3079 WMI_VDEV_PARAM_GTX_USR_CFG,
3080 GTX_CMD);
3081 break;
3082 }
3083
3084 case QCSAP_GTX_THRE:
3085 {
3086 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
3087 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3088 WMI_VDEV_PARAM_GTX_THRE,
3089 GTX_CMD);
3090 break;
3091 }
3092
3093 case QCSAP_GTX_MARGIN:
3094 {
3095 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
3096 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3097 WMI_VDEV_PARAM_GTX_MARGIN,
3098 GTX_CMD);
3099 break;
3100 }
3101
3102 case QCSAP_GTX_STEP:
3103 {
3104 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
3105 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3106 WMI_VDEV_PARAM_GTX_STEP,
3107 GTX_CMD);
3108 break;
3109 }
3110
3111 case QCSAP_GTX_MINTPC:
3112 {
3113 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
3114 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3115 WMI_VDEV_PARAM_GTX_MINTPC,
3116 GTX_CMD);
3117 break;
3118 }
3119
3120 case QCSAP_GTX_BWMASK:
3121 {
3122 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
3123 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3124 WMI_VDEV_PARAM_GTX_BW_MASK,
3125 GTX_CMD);
3126 break;
3127 }
3128
3129 case QCASAP_GET_DFS_NOL:
3130 {
3131 wlansap_get_dfs_nol(
3132#ifdef WLAN_FEATURE_MBSSID
3133 WLAN_HDD_GET_SAP_CTX_PTR
3134 (pHostapdAdapter)
3135#else
3136 pHddCtx->pcds_context
3137#endif
3138 );
3139 }
3140 break;
3141
3142 case QCSAP_GET_ACL:
3143 {
3144 hddLog(LOG1, FL("QCSAP_GET_ACL"));
3145 if (hdd_print_acl(pHostapdAdapter) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303146 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003147 hddLog(LOGE,
3148 FL
3149 ("QCSAP_GET_ACL returned Error: not completed"));
3150 }
3151 *value = 0;
3152 break;
3153 }
3154
3155 case QCASAP_TX_CHAINMASK_CMD:
3156 {
3157 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD");
3158 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3159 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3160 PDEV_CMD);
3161 break;
3162 }
3163
3164 case QCASAP_RX_CHAINMASK_CMD:
3165 {
3166 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD");
3167 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3168 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3169 PDEV_CMD);
3170 break;
3171 }
3172
3173 case QCASAP_NSS_CMD:
3174 {
3175 hddLog(LOG1, "QCASAP_NSS_CMD");
3176 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3177 WMI_VDEV_PARAM_NSS,
3178 VDEV_CMD);
3179 break;
3180 }
3181 case QCASAP_GET_TEMP_CMD:
3182 {
3183 hddLog(LOG1, "QCASAP_GET_TEMP_CMD");
3184 ret = wlan_hdd_get_temperature(pHostapdAdapter, value);
3185 break;
3186 }
Govind Singha471e5e2015-10-12 17:11:14 +05303187 case QCSAP_GET_FW_PROFILE_DATA:
3188 hddLog(LOG1, "QCSAP_GET_FW_PROFILE_DATA");
3189 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3190 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
3191 0, DBG_CMD);
3192 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003193 default:
3194 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
3195 ret = -EINVAL;
3196 break;
3197
3198 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303199 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003200 return ret;
3201}
3202
3203int
3204static iw_softap_getparam(struct net_device *dev,
3205 struct iw_request_info *info,
3206 union iwreq_data *wrqu, char *extra)
3207{
3208 int ret;
3209
3210 cds_ssr_protect(__func__);
3211 ret = __iw_softap_getparam(dev, info, wrqu, extra);
3212 cds_ssr_unprotect(__func__);
3213
3214 return ret;
3215}
3216
3217/* Usage:
3218 BLACK_LIST = 0
3219 WHITE_LIST = 1
3220 ADD MAC = 0
3221 REMOVE MAC = 1
3222
3223 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3224 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3225 while using this ioctl
3226
3227 Syntax:
3228 iwpriv softap.0 modify_acl
3229 <6 octet mac addr> <list type> <cmd type>
3230
3231 Examples:
3232 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
3233 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
3234 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
3235 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
3236 */
3237static
3238int __iw_softap_modify_acl(struct net_device *dev,
3239 struct iw_request_info *info,
3240 union iwreq_data *wrqu, char *extra)
3241{
3242 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3243#ifndef WLAN_FEATURE_MBSSID
3244 v_CONTEXT_t cds_ctx;
3245#endif
3246 uint8_t *value = (uint8_t *) extra;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303247 uint8_t pPeerStaMac[QDF_MAC_ADDR_SIZE];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003248 int listType, cmd, i;
3249 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303250 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003251 hdd_context_t *hdd_ctx;
3252
Jeff Johnson02050312016-02-11 18:40:28 -08003253 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003254
3255 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3256 ret = wlan_hdd_validate_context(hdd_ctx);
3257 if (0 != ret)
3258 return ret;
3259
3260#ifndef WLAN_FEATURE_MBSSID
3261 cds_ctx = hdd_ctx->pcds_context;
3262 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303263 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003264 "%s: Vos Context is NULL", __func__);
3265 return -EINVAL;
3266 }
3267#endif
3268
Anurag Chouhan6d760662016-02-20 16:05:43 +05303269 for (i = 0; i < QDF_MAC_ADDR_SIZE; i++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003270 pPeerStaMac[i] = *(value + i);
3271
3272 listType = (int)(*(value + i));
3273 i++;
3274 cmd = (int)(*(value + i));
3275
3276 hddLog(LOG1, FL("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d"),
3277 MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
3278
3279#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303280 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281 wlansap_modify_acl(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
3282 pPeerStaMac, (eSapACLType) listType,
3283 (eSapACLCmdType) cmd);
3284#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303285 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286 wlansap_modify_acl(p_cds_context, pPeerStaMac,
3287 (eSapACLType) listType, (eSapACLCmdType) cmd);
3288#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303289 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003290 hddLog(LOGE, FL("Modify ACL failed"));
3291 ret = -EIO;
3292 }
3293 EXIT();
3294 return ret;
3295}
3296
3297static
3298int iw_softap_modify_acl(struct net_device *dev,
3299 struct iw_request_info *info,
3300 union iwreq_data *wrqu, char *extra)
3301{
3302 int ret;
3303
3304 cds_ssr_protect(__func__);
3305 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
3306 cds_ssr_unprotect(__func__);
3307
3308 return ret;
3309}
3310
3311int
3312static __iw_softap_getchannel(struct net_device *dev,
3313 struct iw_request_info *info,
3314 union iwreq_data *wrqu, char *extra)
3315{
3316 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3317 hdd_context_t *hdd_ctx;
3318 int *value = (int *)extra;
3319 int ret;
3320
Jeff Johnson02050312016-02-11 18:40:28 -08003321 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303322
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003323 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3324 ret = wlan_hdd_validate_context(hdd_ctx);
3325 if (0 != ret)
3326 return ret;
3327
3328 *value = 0;
3329 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3330 *value = (WLAN_HDD_GET_AP_CTX_PTR(
3331 pHostapdAdapter))->operatingChannel;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303332 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003333 return 0;
3334}
3335
3336int
3337static iw_softap_getchannel(struct net_device *dev,
3338 struct iw_request_info *info,
3339 union iwreq_data *wrqu, char *extra)
3340{
3341 int ret;
3342
3343 cds_ssr_protect(__func__);
3344 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
3345 cds_ssr_unprotect(__func__);
3346
3347 return ret;
3348}
3349
3350int
3351static __iw_softap_set_max_tx_power(struct net_device *dev,
3352 struct iw_request_info *info,
3353 union iwreq_data *wrqu, char *extra)
3354{
3355 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3356 hdd_context_t *hdd_ctx;
3357 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3358 int *value = (int *)extra;
3359 int set_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003360 int ret;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303361 struct qdf_mac_addr bssid = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
3362 struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003363
Jeff Johnson02050312016-02-11 18:40:28 -08003364 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303365
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003366 if (NULL == value)
3367 return -ENOMEM;
3368
3369 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3370 ret = wlan_hdd_validate_context(hdd_ctx);
3371 if (0 != ret)
3372 return ret;
3373
3374 /* Assign correct slef MAC address */
Anurag Chouhanc5548422016-02-24 18:33:27 +05303375 qdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
3376 qdf_copy_macaddr(&selfMac, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003377
3378 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303379 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003380 sme_set_max_tx_power(hHal, bssid, selfMac, set_value)) {
3381 hddLog(LOGE, FL("Setting maximum tx power failed"));
3382 return -EIO;
3383 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303384 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003385 return 0;
3386}
3387
3388int
3389static iw_softap_set_max_tx_power(struct net_device *dev,
3390 struct iw_request_info *info,
3391 union iwreq_data *wrqu, char *extra)
3392{
3393 int ret;
3394
3395 cds_ssr_protect(__func__);
3396 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
3397 cds_ssr_unprotect(__func__);
3398
3399 return ret;
3400}
3401
3402int
3403static __iw_softap_set_tx_power(struct net_device *dev,
3404 struct iw_request_info *info,
3405 union iwreq_data *wrqu, char *extra)
3406{
3407 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3408 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3409 hdd_context_t *hdd_ctx;
3410 int *value = (int *)extra;
3411 int set_value;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303412 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003413 int ret;
3414
Jeff Johnson02050312016-02-11 18:40:28 -08003415 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303416
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003417 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3418 ret = wlan_hdd_validate_context(hdd_ctx);
3419 if (0 != ret)
3420 return ret;
3421
3422 if (NULL == value)
3423 return -ENOMEM;
3424
Anurag Chouhanc5548422016-02-24 18:33:27 +05303425 qdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003426
3427 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303428 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003429 sme_set_tx_power(hHal, pHostapdAdapter->sessionId, bssid,
3430 pHostapdAdapter->device_mode, set_value)) {
3431 hddLog(LOGE, FL("Setting tx power failed"));
3432 return -EIO;
3433 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303434 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003435 return 0;
3436}
3437
3438int
3439static iw_softap_set_tx_power(struct net_device *dev,
3440 struct iw_request_info *info,
3441 union iwreq_data *wrqu, char *extra)
3442{
3443 int ret;
3444
3445 cds_ssr_protect(__func__);
3446 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
3447 cds_ssr_unprotect(__func__);
3448
3449 return ret;
3450}
3451
3452#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
3453
3454int
3455static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
3456 struct iw_request_info *info,
3457 union iwreq_data *wrqu, char *extra)
3458{
3459 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3460 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
3461 hdd_context_t *hdd_ctx;
3462 char *buf;
3463 int cnt = 0;
3464 int left;
3465 int ret;
3466 /* maclist_index must be u32 to match userspace */
3467 u32 maclist_index;
3468
Jeff Johnson02050312016-02-11 18:40:28 -08003469 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303470
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003471 /*
3472 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
3473 * number, and even numbered iocts are supposed to have "set"
3474 * semantics. Hence the wireless extensions support in the kernel
3475 * won't correctly copy the result to userspace, so the ioctl
3476 * handler itself must copy the data. Output format is 32-bit
3477 * record length, followed by 0 or more 6-byte STA MAC addresses.
3478 *
3479 * Further note that due to the incorrect semantics, the "iwpriv"
3480 * userspace application is unable to correctly invoke this API,
3481 * hence it is not registered in the hostapd_private_args. This
3482 * API can only be invoked by directly invoking the ioctl() system
3483 * call.
3484 */
3485
3486 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3487 ret = wlan_hdd_validate_context(hdd_ctx);
3488 if (0 != ret)
3489 return ret;
3490
3491 /* make sure userspace allocated a reasonable buffer size */
3492 if (wrqu->data.length < sizeof(maclist_index)) {
3493 hddLog(LOG1, FL("invalid userspace buffer"));
3494 return -EINVAL;
3495 }
3496
3497 /* allocate local buffer to build the response */
3498 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
3499 if (!buf) {
3500 hddLog(LOG1, FL("failed to allocate response buffer"));
3501 return -ENOMEM;
3502 }
3503
3504 /* start indexing beyond where the record count will be written */
3505 maclist_index = sizeof(maclist_index);
3506 left = wrqu->data.length - maclist_index;
3507
3508 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303509 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003510 if ((pStaInfo[cnt].isUsed) &&
3511 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
3512 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
Anurag Chouhan6d760662016-02-20 16:05:43 +05303513 QDF_MAC_ADDR_SIZE);
3514 maclist_index += QDF_MAC_ADDR_SIZE;
3515 left -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003516 }
3517 cnt++;
3518 }
3519 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
3520
3521 *((u32 *) buf) = maclist_index;
3522 wrqu->data.length = maclist_index;
3523 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
3524 hddLog(LOG1, FL("failed to copy response to user buffer"));
3525 ret = -EFAULT;
3526 }
3527 kfree(buf);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303528 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003529 return ret;
3530}
3531
3532int
3533static iw_softap_getassoc_stamacaddr(struct net_device *dev,
3534 struct iw_request_info *info,
3535 union iwreq_data *wrqu, char *extra)
3536{
3537 int ret;
3538
3539 cds_ssr_protect(__func__);
3540 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
3541 cds_ssr_unprotect(__func__);
3542
3543 return ret;
3544}
3545
3546/* Usage:
3547 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3548 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3549 while using this ioctl
3550
3551 Syntax:
3552 iwpriv softap.0 disassoc_sta <6 octet mac address>
3553
3554 e.g.
3555 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
3556 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
3557 */
3558
3559int
3560static __iw_softap_disassoc_sta(struct net_device *dev,
3561 struct iw_request_info *info,
3562 union iwreq_data *wrqu, char *extra)
3563{
3564 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3565 hdd_context_t *hdd_ctx;
3566 uint8_t *peerMacAddr;
3567 int ret;
3568
Jeff Johnson02050312016-02-11 18:40:28 -08003569 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003570
Mukul Sharma744420f2015-11-02 19:49:13 +05303571 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303572 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharma744420f2015-11-02 19:49:13 +05303573 FL("permission check failed"));
3574 return -EPERM;
3575 }
3576
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003577 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3578 ret = wlan_hdd_validate_context(hdd_ctx);
3579 if (0 != ret)
3580 return ret;
3581
3582 /* iwpriv tool or framework calls this ioctl with
3583 * data passed in extra (less than 16 octets);
3584 */
3585 peerMacAddr = (uint8_t *) (extra);
3586
3587 hddLog(LOG1, FL("data " MAC_ADDRESS_STR),
3588 MAC_ADDR_ARRAY(peerMacAddr));
3589 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
3590 EXIT();
3591 return 0;
3592}
3593
3594int
3595static iw_softap_disassoc_sta(struct net_device *dev,
3596 struct iw_request_info *info,
3597 union iwreq_data *wrqu, char *extra)
3598{
3599 int ret;
3600
3601 cds_ssr_protect(__func__);
3602 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
3603 cds_ssr_unprotect(__func__);
3604
3605 return ret;
3606}
3607
Govind Singha471e5e2015-10-12 17:11:14 +05303608/**
3609 * iw_get_char_setnone() - Generic "get char" private ioctl handler
3610 * @dev: device upon which the ioctl was received
3611 * @info: ioctl request information
3612 * @wrqu: ioctl request data
3613 * @extra: ioctl extra data
3614 *
3615 * Return: 0 on success, non-zero on error
3616 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003617static int __iw_get_char_setnone(struct net_device *dev,
3618 struct iw_request_info *info,
3619 union iwreq_data *wrqu, char *extra)
3620{
3621 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Govind Singha471e5e2015-10-12 17:11:14 +05303622 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003623 int sub_cmd = wrqu->data.flags;
3624 hdd_context_t *hdd_ctx;
3625
Jeff Johnson02050312016-02-11 18:40:28 -08003626 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003627
3628 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Govind Singha471e5e2015-10-12 17:11:14 +05303629 ret = wlan_hdd_validate_context(hdd_ctx);
3630 if (ret != 0)
3631 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003632
3633 switch (sub_cmd) {
3634 case QCSAP_GET_STATS:
3635 hdd_wlan_get_stats(adapter, &(wrqu->data.length),
3636 extra, WE_MAX_STR_LEN);
3637 break;
Govind Singha471e5e2015-10-12 17:11:14 +05303638 case QCSAP_LIST_FW_PROFILE:
3639 hdd_wlan_list_fw_profile(&(wrqu->data.length),
3640 extra, WE_MAX_STR_LEN);
3641 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003642 }
3643
3644 EXIT();
Govind Singha471e5e2015-10-12 17:11:14 +05303645 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003646}
3647
3648static int iw_get_char_setnone(struct net_device *dev,
3649 struct iw_request_info *info,
3650 union iwreq_data *wrqu, char *extra)
3651{
3652 int ret;
3653
3654 cds_ssr_protect(__func__);
3655 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
3656 cds_ssr_unprotect(__func__);
3657
3658 return ret;
3659}
3660
3661static int wlan_hdd_set_force_acs_ch_range(struct net_device *dev,
3662 struct iw_request_info *info,
3663 union iwreq_data *wrqu, char *extra)
3664{
3665 hdd_adapter_t *adapter = (netdev_priv(dev));
3666 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3667 int *value = (int *)extra;
3668
Jeff Johnson02050312016-02-11 18:40:28 -08003669 ENTER_DEV(dev);
3670
Hanumantha Reddy Pothula3b8c0a52015-11-05 10:59:21 +05303671 if (!capable(CAP_NET_ADMIN)) {
3672 hddLog(LOGE, FL("permission check failed"));
3673 return -EPERM;
3674 }
3675
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003676 if (wlan_hdd_validate_operation_channel(adapter, value[0]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303677 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003678 wlan_hdd_validate_operation_channel(adapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303679 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003680 return -EINVAL;
3681 } else {
3682 hdd_ctx->config->force_sap_acs_st_ch = value[0];
3683 hdd_ctx->config->force_sap_acs_end_ch = value[1];
3684 }
3685
3686 return 0;
3687}
3688
3689static int iw_softap_set_force_acs_ch_range(struct net_device *dev,
3690 struct iw_request_info *info,
3691 union iwreq_data *wrqu, char *extra)
3692{
3693 int ret;
3694 cds_ssr_protect(__func__);
3695 ret = wlan_hdd_set_force_acs_ch_range(dev, info, wrqu, extra);
3696 cds_ssr_unprotect(__func__);
3697 return ret;
3698}
3699
3700static int __iw_softap_get_channel_list(struct net_device *dev,
3701 struct iw_request_info *info,
3702 union iwreq_data *wrqu, char *extra)
3703{
3704 uint32_t num_channels = 0;
3705 uint8_t i = 0;
3706 uint8_t bandStartChannel = RF_CHAN_1;
3707 uint8_t bandEndChannel = RF_CHAN_184;
3708 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3709 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3710 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
3711 eCsrBand curBand = eCSR_BAND_ALL;
3712 hdd_context_t *hdd_ctx;
3713 int ret;
3714
Jeff Johnson02050312016-02-11 18:40:28 -08003715 ENTER_DEV(dev);
3716
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003717 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3718 ret = wlan_hdd_validate_context(hdd_ctx);
3719 if (0 != ret)
3720 return ret;
3721
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303722 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &curBand)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003723 hddLog(LOGE, FL("not able get the current frequency band"));
3724 return -EIO;
3725 }
3726 wrqu->data.length = sizeof(tChannelListInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003727
3728 if (eCSR_BAND_24 == curBand) {
3729 bandStartChannel = RF_CHAN_1;
3730 bandEndChannel = RF_CHAN_14;
3731 } else if (eCSR_BAND_5G == curBand) {
3732 bandStartChannel = RF_CHAN_36;
3733 bandEndChannel = RF_CHAN_184;
3734 }
3735
3736 hddLog(LOG1, FL("curBand = %d, StartChannel = %hu, EndChannel = %hu "),
3737 curBand, bandStartChannel, bandEndChannel);
3738
3739 for (i = bandStartChannel; i <= bandEndChannel; i++) {
Amar Singhal7a1726a2015-10-14 16:28:11 -07003740 if ((CHANNEL_STATE_ENABLE == CDS_CHANNEL_STATE(i)) ||
3741 (CHANNEL_STATE_DFS == CDS_CHANNEL_STATE(i))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003742 channel_list->channels[num_channels] =
Amar Singhal7a1726a2015-10-14 16:28:11 -07003743 CDS_CHANNEL_NUM(i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003744 num_channels++;
3745 }
3746 }
3747
3748 hddLog(LOG1, FL(" number of channels %d"), num_channels);
3749
3750 if (num_channels > IW_MAX_FREQUENCIES) {
3751 num_channels = IW_MAX_FREQUENCIES;
3752 }
3753
3754 channel_list->num_channels = num_channels;
3755 EXIT();
3756
3757 return 0;
3758}
3759
3760int iw_softap_get_channel_list(struct net_device *dev,
3761 struct iw_request_info *info,
3762 union iwreq_data *wrqu, char *extra)
3763{
3764 int ret;
3765
3766 cds_ssr_protect(__func__);
3767 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
3768 cds_ssr_unprotect(__func__);
3769
3770 return ret;
3771}
3772
3773static
3774int __iw_get_genie(struct net_device *dev,
3775 struct iw_request_info *info,
3776 union iwreq_data *wrqu, char *extra)
3777{
3778 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3779 hdd_context_t *hdd_ctx;
3780 int ret;
3781#ifndef WLAN_FEATURE_MBSSID
3782 v_CONTEXT_t cds_ctx;
3783#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303784 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
3786 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
3787
Jeff Johnson02050312016-02-11 18:40:28 -08003788 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003789
3790 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3791 ret = wlan_hdd_validate_context(hdd_ctx);
3792 if (0 != ret)
3793 return ret;
3794
3795#ifndef WLAN_FEATURE_MBSSID
3796 cds_ctx = hdd_ctx->pcds_context;
3797 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303798 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003799 "%s: vos context is not valid ", __func__);
3800 return -EINVAL;
3801 }
3802#endif
3803
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804 /*
3805 * Actually retrieve the RSN IE from CSR.
3806 * (We previously sent it down in the CSR Roam Profile.)
3807 */
3808 status = wlan_sap_getstation_ie_information(
3809#ifdef WLAN_FEATURE_MBSSID
3810 WLAN_HDD_GET_SAP_CTX_PTR
3811 (pHostapdAdapter),
3812#else
3813 cds_ctx,
3814#endif
3815 &length, genIeBytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303816 if (status == QDF_STATUS_SUCCESS) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05303817 length = QDF_MIN(length, DOT11F_IE_RSN_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003818 if (wrqu->data.length < length ||
3819 copy_to_user(wrqu->data.pointer, (void *)genIeBytes, length)) {
3820 hddLog(LOG1, FL("failed to copy data to user buffer"));
3821 return -EFAULT;
3822 }
3823 wrqu->data.length = length;
3824 hddLog(LOG1, FL(" RSN IE of %d bytes returned"),
3825 wrqu->data.length);
3826 } else {
3827 wrqu->data.length = 0;
3828 hddLog(LOG1, FL(" RSN IE failed to populate"));
3829 }
3830
3831 EXIT();
3832 return 0;
3833}
3834
3835static
3836int iw_get_genie(struct net_device *dev,
3837 struct iw_request_info *info,
3838 union iwreq_data *wrqu, char *extra)
3839{
3840 int ret;
3841
3842 cds_ssr_protect(__func__);
3843 ret = __iw_get_genie(dev, info, wrqu, extra);
3844 cds_ssr_unprotect(__func__);
3845
3846 return ret;
3847}
3848
3849static
3850int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3851 struct iw_request_info *info,
3852 union iwreq_data *wrqu, char *extra)
3853{
3854 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3855 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
3856 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3857 hdd_context_t *hdd_ctx;
3858 int ret;
3859
Jeff Johnson02050312016-02-11 18:40:28 -08003860 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003861
3862 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3863 ret = wlan_hdd_validate_context(hdd_ctx);
3864 if (0 != ret)
3865 return ret;
3866
3867 hddLog(LOG1, FL("get_WPSPBCProbeReqIEs ioctl"));
3868 memset((void *)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
3869
3870 WPSPBCProbeReqIEs.probeReqIELen =
3871 pHddApCtx->WPSPBCProbeReq.probeReqIELen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303872 qdf_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 pHddApCtx->WPSPBCProbeReq.probeReqIE,
3874 WPSPBCProbeReqIEs.probeReqIELen);
Anurag Chouhanc5548422016-02-24 18:33:27 +05303875 qdf_copy_macaddr(&WPSPBCProbeReqIEs.macaddr,
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003876 &pHddApCtx->WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003877 if (copy_to_user(wrqu->data.pointer,
3878 (void *)&WPSPBCProbeReqIEs,
3879 sizeof(WPSPBCProbeReqIEs))) {
3880 hddLog(LOG1, FL("failed to copy data to user buffer"));
3881 return -EFAULT;
3882 }
3883 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003884 hdd_info("Macaddress : " MAC_ADDRESS_STR,
3885 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003886 up(&pHddApCtx->semWpsPBCOverlapInd);
3887 EXIT();
3888 return 0;
3889}
3890
3891static
3892int iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3893 struct iw_request_info *info,
3894 union iwreq_data *wrqu, char *extra)
3895{
3896 int ret;
3897
3898 cds_ssr_protect(__func__);
3899 ret = __iw_get_wpspbc_probe_req_ies(dev, info, wrqu, extra);
3900 cds_ssr_unprotect(__func__);
3901
3902 return ret;
3903}
3904
3905/**
3906 * __iw_set_auth_hostap() -
3907 * This function sets the auth type received from the wpa_supplicant.
3908 *
3909 * @dev: pointer to the net device.
3910 * @info: pointer to the iw_request_info.
3911 * @wrqu: pointer to the iwreq_data.
3912 * @extra: pointer to the data.
3913 *
3914 * Return: 0 for success, non zero for failure
3915 */
3916static
3917int __iw_set_auth_hostap(struct net_device *dev, struct iw_request_info *info,
3918 union iwreq_data *wrqu, char *extra)
3919{
3920 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3921 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3922 hdd_context_t *hdd_ctx;
3923 int ret;
3924
Jeff Johnson651f9f22016-02-11 18:16:11 -08003925 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003926
3927 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3928 ret = wlan_hdd_validate_context(hdd_ctx);
3929 if (0 != ret)
3930 return ret;
3931
3932 switch (wrqu->param.flags & IW_AUTH_INDEX) {
3933 case IW_AUTH_TKIP_COUNTERMEASURES:
3934 {
3935 if (wrqu->param.value) {
3936 hddLog(LOG2,
3937 "Counter Measure started %d", wrqu->param.value);
3938 pWextState->mTKIPCounterMeasures =
3939 TKIP_COUNTER_MEASURE_STARTED;
3940 } else {
3941 hddLog(LOG2,
3942 "Counter Measure stopped=%d", wrqu->param.value);
3943 pWextState->mTKIPCounterMeasures =
3944 TKIP_COUNTER_MEASURE_STOPED;
3945 }
3946
3947 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
3948 wrqu->param.
3949 value);
3950 }
3951 break;
3952
3953 default:
3954
3955 hddLog(LOGW, FL("called with unsupported auth type %d"),
3956 wrqu->param.flags & IW_AUTH_INDEX);
3957 break;
3958 }
3959
3960 EXIT();
3961 return 0;
3962}
3963
3964/**
3965 * iw_set_auth_hostap() - Wrapper function to protect __iw_set_auth_hostap
3966 * from the SSR.
3967 *
3968 * @dev - Pointer to the net device.
3969 * @info - Pointer to the iw_request_info.
3970 * @wrqu - Pointer to the iwreq_data.
3971 * @extra - Pointer to the data.
3972 *
3973 * Return: 0 for success, non zero for failure.
3974 */
3975static int
3976iw_set_auth_hostap(struct net_device *dev,
3977 struct iw_request_info *info,
3978 union iwreq_data *wrqu, char *extra)
3979{
3980 int ret;
3981
3982 cds_ssr_protect(__func__);
3983 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
3984 cds_ssr_unprotect(__func__);
3985
3986 return ret;
3987}
3988
3989/**
3990 * __iw_set_ap_encodeext() - set ap encode
3991 *
3992 * @dev - Pointer to the net device.
3993 * @info - Pointer to the iw_request_info.
3994 * @wrqu - Pointer to the iwreq_data.
3995 * @extra - Pointer to the data.
3996 *
3997 * Return: 0 for success, non zero for failure.
3998 */
3999static int __iw_set_ap_encodeext(struct net_device *dev,
4000 struct iw_request_info *info,
4001 union iwreq_data *wrqu, char *extra)
4002{
4003 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4004#ifndef WLAN_FEATURE_MBSSID
4005 v_CONTEXT_t cds_ctx;
4006#endif
4007 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4008 hdd_context_t *hdd_ctx;
4009 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304010 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004011 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4012 int key_index;
4013 struct iw_point *encoding = &wrqu->encoding;
4014 tCsrRoamSetKey setKey;
4015 int i;
4016
Jeff Johnson651f9f22016-02-11 18:16:11 -08004017 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004018
4019 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4020 ret = wlan_hdd_validate_context(hdd_ctx);
4021 if (0 != ret)
4022 return ret;
4023
4024#ifndef WLAN_FEATURE_MBSSID
4025 cds_ctx = hdd_ctx->pcds_context;
4026 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304027 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004028 "%s: pVosContext is NULL", __func__);
4029 return -EINVAL;
4030 }
4031#endif
4032
4033 key_index = encoding->flags & IW_ENCODE_INDEX;
4034
4035 if (key_index > 0) {
4036 /*Convert from 1-based to 0-based keying */
4037 key_index--;
4038 }
4039 if (!ext->key_len)
4040 return ret;
4041
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304042 qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043
4044 setKey.keyId = key_index;
4045 setKey.keyLength = ext->key_len;
4046
4047 if (ext->key_len <= CSR_MAX_KEY_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304048 qdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 }
4050
4051 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4052 /*Key direction for group is RX only */
4053 setKey.keyDirection = eSIR_RX_ONLY;
Anurag Chouhanc5548422016-02-24 18:33:27 +05304054 qdf_set_macaddr_broadcast(&setKey.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004055 } else {
4056
4057 setKey.keyDirection = eSIR_TX_RX;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304058 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304059 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004060 }
4061 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
4062 setKey.keyDirection = eSIR_TX_DEFAULT;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304063 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304064 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004065 }
4066
4067 /*For supplicant pae role is zero */
4068 setKey.paeRole = 0;
4069
4070 switch (ext->alg) {
4071 case IW_ENCODE_ALG_NONE:
4072 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4073 break;
4074
4075 case IW_ENCODE_ALG_WEP:
4076 setKey.encType =
4077 (ext->key_len ==
4078 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4079 pHddApCtx->uPrivacy = 1;
4080 hddLog(LOG1, FL("uPrivacy=%d"), pHddApCtx->uPrivacy);
4081 break;
4082
4083 case IW_ENCODE_ALG_TKIP:
4084 {
4085 uint8_t *pKey = &setKey.Key[0];
4086
4087 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4088
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304089 qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004090
4091 /*Supplicant sends the 32bytes key in this order
4092
4093 |--------------|----------|----------|
4094 | Tk1 |TX-MIC | RX Mic |
4095 |||--------------|----------|----------|
4096 <---16bytes---><--8bytes--><--8bytes-->
4097
4098 */
4099 /*Sme expects the 32 bytes key to be in the below order
4100
4101 |--------------|----------|----------|
4102 | Tk1 |RX-MIC | TX Mic |
4103 |||--------------|----------|----------|
4104 <---16bytes---><--8bytes--><--8bytes-->
4105 */
4106 /* Copy the Temporal Key 1 (TK1) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304107 qdf_mem_copy(pKey, ext->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004108
4109 /*Copy the rx mic first */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304110 qdf_mem_copy(&pKey[16], &ext->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004111
4112 /*Copy the tx mic */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304113 qdf_mem_copy(&pKey[24], &ext->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004114
4115 }
4116 break;
4117
4118 case IW_ENCODE_ALG_CCMP:
4119 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4120 break;
4121
4122 default:
4123 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4124 break;
4125 }
4126
4127 hddLog(LOG1, FL(":EncryptionType:%d key_len:%d, KeyId:%d"),
4128 setKey.encType, setKey.keyLength, setKey.keyId);
4129 for (i = 0; i < ext->key_len; i++)
4130 hddLog(LOG1, "%02x", setKey.Key[i]);
4131
4132#ifdef WLAN_FEATURE_MBSSID
4133 vstatus =
4134 wlansap_set_key_sta(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
4135 &setKey);
4136#else
4137 vstatus = wlansap_set_key_sta(cds_ctx, &setKey);
4138#endif
4139
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304140 if (vstatus != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 hddLog(LOGE, FL("wlansap_set_key_sta failed, status= %d"),
4142 vstatus);
4143 ret = -EINVAL;
4144 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304145 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004146 return ret;
4147}
4148
4149/**
4150 * iw_set_ap_encodeext() - Wrapper function to protect __iw_set_ap_encodeext
4151 * from the SSR.
4152 *
4153 * @dev - Pointer to the net device.
4154 * @info - Pointer to the iw_request_info.
4155 * @wrqu - Pointer to the iwreq_data.
4156 * @extra - Pointer to the data.
4157 *
4158 * Return: 0 for success, non zero for failure.
4159 */
4160static int iw_set_ap_encodeext(struct net_device *dev,
4161 struct iw_request_info *info,
4162 union iwreq_data *wrqu, char *extra)
4163{
4164 int ret;
4165
4166 cds_ssr_protect(__func__);
4167 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
4168 cds_ssr_unprotect(__func__);
4169
4170 return ret;
4171}
4172
4173/**
4174 * __iw_set_ap_mlme() - set ap mlme
4175 * @dev: pointer to net_device
4176 * @info: pointer to iw_request_info
4177 * @wrqu; pointer to iwreq_data
4178 * @extra: extra
4179 *
4180 * Return; 0 on success, error number otherwise
4181 */
4182static int __iw_set_ap_mlme(struct net_device *dev,
4183 struct iw_request_info *info,
4184 union iwreq_data *wrqu, char *extra)
4185{
Jeff Johnson651f9f22016-02-11 18:16:11 -08004186 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187 return 0;
4188}
4189
4190/**
4191 * iw_set_ap_mlme() - SSR wrapper for __iw_set_ap_mlme
4192 * @dev: pointer to net_device
4193 * @info: pointer to iw_request_info
4194 * @wrqu; pointer to iwreq_data
4195 * @extra: extra
4196 *
4197 * Return; 0 on success, error number otherwise
4198 */
4199static int iw_set_ap_mlme(struct net_device *dev,
4200 struct iw_request_info *info,
4201 union iwreq_data *wrqu,
4202 char *extra)
4203{
4204 int ret;
4205
4206 cds_ssr_protect(__func__);
4207 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
4208 cds_ssr_unprotect(__func__);
4209
4210 return ret;
4211}
4212
4213/**
4214 * __iw_get_ap_rts_threshold() - get ap rts threshold
4215 * @dev - Pointer to the net device.
4216 * @info - Pointer to the iw_request_info.
4217 * @wrqu - Pointer to the iwreq_data.
4218 * @extra - Pointer to the data.
4219 *
4220 * Return: 0 for success, non zero for failure.
4221 */
4222static int __iw_get_ap_rts_threshold(struct net_device *dev,
4223 struct iw_request_info *info,
4224 union iwreq_data *wrqu, char *extra) {
4225
4226 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4227 int ret;
4228 hdd_context_t *hdd_ctx;
4229
Jeff Johnson651f9f22016-02-11 18:16:11 -08004230 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004231
4232 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4233 ret = wlan_hdd_validate_context(hdd_ctx);
4234 if (0 != ret)
4235 return ret;
4236 ret = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
4237
4238 return ret;
4239}
4240
4241/**
4242 * iw_get_ap_rts_threshold() - Wrapper function to protect
4243 * __iw_get_ap_rts_threshold from the SSR.
4244 * @dev - Pointer to the net device.
4245 * @info - Pointer to the iw_request_info.
4246 * @wrqu - Pointer to the iwreq_data.
4247 * @extra - Pointer to the data.
4248 *
4249 * Return: 0 for success, non zero for failure.
4250 */
4251static int iw_get_ap_rts_threshold(struct net_device *dev,
4252 struct iw_request_info *info,
4253 union iwreq_data *wrqu, char *extra)
4254{
4255 int ret;
4256
4257 cds_ssr_protect(__func__);
4258 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
4259 cds_ssr_unprotect(__func__);
4260
4261 return ret;
4262}
4263
4264/**
4265 * __iw_get_ap_frag_threshold() - get ap fragmentation threshold
4266 * @dev - Pointer to the net device.
4267 * @info - Pointer to the iw_request_info.
4268 * @wrqu - Pointer to the iwreq_data.
4269 * @extra - Pointer to the data.
4270 *
4271 * Return: 0 for success, non zero for failure.
4272 */
4273static int __iw_get_ap_frag_threshold(struct net_device *dev,
4274 struct iw_request_info *info,
4275 union iwreq_data *wrqu, char *extra) {
4276
4277 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4278 hdd_context_t *hdd_ctx;
4279 int ret = 0;
4280
Jeff Johnson651f9f22016-02-11 18:16:11 -08004281 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004282
4283 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4284 ret = wlan_hdd_validate_context(hdd_ctx);
4285 if (0 != ret)
4286 return ret;
4287
4288 ret = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
4289
4290 return ret;
4291}
4292
4293/**
4294 * iw_get_ap_frag_threshold() - Wrapper function to protect
4295 * __iw_get_ap_frag_threshold from the SSR.
4296 * @dev - Pointer to the net device.
4297 * @info - Pointer to the iw_request_info.
4298 * @wrqu - Pointer to the iwreq_data.
4299 * @extra - Pointer to the data.
4300 *
4301 * Return: 0 for success, non zero for failure.
4302 */
4303static int iw_get_ap_frag_threshold(struct net_device *dev,
4304 struct iw_request_info *info,
4305 union iwreq_data *wrqu, char *extra)
4306{
4307 int ret;
4308
4309 cds_ssr_protect(__func__);
4310 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
4311 cds_ssr_unprotect(__func__);
4312
4313 return ret;
4314}
4315
4316/**
4317 * __iw_get_ap_freq() - get ap frequency
4318 * @dev - Pointer to the net device.
4319 * @info - Pointer to the iw_request_info.
4320 * @wrqu - Pointer to the iwreq_data.
4321 * @extra - Pointer to the data.
4322 *
4323 * Return: 0 for success, non zero for failure.
4324 */
4325static int __iw_get_ap_freq(struct net_device *dev,
4326 struct iw_request_info *info, struct iw_freq *fwrq,
4327 char *extra) {
4328 uint32_t status = false, channel = 0, freq = 0;
4329 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4330 hdd_context_t *hdd_ctx;
4331 tHalHandle hHal;
4332 hdd_hostapd_state_t *pHostapdState;
4333 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4334 int ret;
4335
Jeff Johnson651f9f22016-02-11 18:16:11 -08004336 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004337
4338 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4339 ret = wlan_hdd_validate_context(hdd_ctx);
4340 if (0 != ret)
4341 return ret;
4342
4343 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4344 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
4345
4346 if (pHostapdState->bssState == BSS_STOP) {
4347 if (sme_cfg_get_int(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304348 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004349 return -EIO;
4350 } else {
4351 status = hdd_wlan_get_freq(channel, &freq);
4352 if (true == status) {
4353 /* Set Exponent parameter as 6 (MHZ) in struct
4354 * iw_freq * iwlist & iwconfig command
4355 * shows frequency into proper
4356 * format (2.412 GHz instead of 246.2 MHz)
4357 */
4358 fwrq->m = freq;
4359 fwrq->e = MHZ;
4360 }
4361 }
4362 } else {
4363 channel = pHddApCtx->operatingChannel;
4364 status = hdd_wlan_get_freq(channel, &freq);
4365 if (true == status) {
4366 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
4367 * iwlist & iwconfig command shows frequency into proper
4368 * format (2.412 GHz instead of 246.2 MHz)*/
4369 fwrq->m = freq;
4370 fwrq->e = MHZ;
4371 }
4372 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304373 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004374 return 0;
4375}
4376
4377/**
4378 * iw_get_ap_freq() - Wrapper function to protect
4379 * __iw_get_ap_freq from the SSR.
4380 * @dev - Pointer to the net device.
4381 * @info - Pointer to the iw_request_info.
4382 * @wrqu - Pointer to the iwreq_data.
4383 * @extra - Pointer to the data.
4384 *
4385 * Return: 0 for success, non zero for failure.
4386 */
4387static int iw_get_ap_freq(struct net_device *dev,
4388 struct iw_request_info *info,
4389 struct iw_freq *wrqu, char *extra)
4390{
4391 int ret;
4392
4393 cds_ssr_protect(__func__);
4394 ret = __iw_get_ap_freq(dev, info, wrqu, extra);
4395 cds_ssr_unprotect(__func__);
4396
4397 return ret;
4398}
4399
4400/**
4401 * __iw_get_mode() - get mode
4402 * @dev - Pointer to the net device.
4403 * @info - Pointer to the iw_request_info.
4404 * @wrqu - Pointer to the iwreq_data.
4405 * @extra - Pointer to the data.
4406 *
4407 * Return: 0 for success, non zero for failure.
4408 */
4409static int __iw_get_mode(struct net_device *dev,
4410 struct iw_request_info *info,
4411 union iwreq_data *wrqu, char *extra) {
4412
4413 hdd_adapter_t *adapter;
4414 hdd_context_t *hdd_ctx;
4415 int ret;
4416
Jeff Johnson651f9f22016-02-11 18:16:11 -08004417 ENTER_DEV(dev);
4418
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004419 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4420 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4421 ret = wlan_hdd_validate_context(hdd_ctx);
4422 if (0 != ret)
4423 return ret;
4424
4425 wrqu->mode = IW_MODE_MASTER;
4426
4427 return ret;
4428}
4429
4430/**
4431 * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR.
4432 * @dev - Pointer to the net device.
4433 * @info - Pointer to the iw_request_info.
4434 * @wrqu - Pointer to the iwreq_data.
4435 * @extra - Pointer to the data.
4436 *
4437 * Return: 0 for success, non zero for failure.
4438 */
4439static int iw_get_mode(struct net_device *dev,
4440 struct iw_request_info *info,
4441 union iwreq_data *wrqu, char *extra)
4442{
4443 int ret;
4444
4445 cds_ssr_protect(__func__);
4446 ret = __iw_get_mode(dev, info, wrqu, extra);
4447 cds_ssr_unprotect(__func__);
4448
4449 return ret;
4450}
4451
4452static int
4453__iw_softap_setwpsie(struct net_device *dev,
4454 struct iw_request_info *info,
4455 union iwreq_data *wrqu, char *extra)
4456{
4457 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4458#ifndef WLAN_FEATURE_MBSSID
4459 v_CONTEXT_t cds_ctx;
4460#endif
4461 hdd_hostapd_state_t *pHostapdState;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304462 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004463 uint8_t *wps_genie;
4464 uint8_t *fwps_genie;
4465 uint8_t *pos;
4466 tpSap_WPSIE pSap_WPSIe;
4467 uint8_t WPSIeType;
4468 uint16_t length;
4469 struct iw_point s_priv_data;
4470 hdd_context_t *hdd_ctx;
4471 int ret;
4472
Jeff Johnson02050312016-02-11 18:40:28 -08004473 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004474
Mukul Sharmaa42b0622015-11-02 19:57:31 +05304475 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304476 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharmaa42b0622015-11-02 19:57:31 +05304477 FL("permission check failed"));
4478 return -EPERM;
4479 }
4480
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004481 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4482 ret = wlan_hdd_validate_context(hdd_ctx);
4483 if (0 != ret)
4484 return ret;
4485
4486#ifndef WLAN_FEATURE_MBSSID
4487 cds_ctx = hdd_ctx->pcds_context;
4488 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304489 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004490 "%s: HDD context is not valid ", __func__);
4491 return -EINVAL;
4492 }
4493#endif
4494
4495 /* helper function to get iwreq_data with compat handling. */
4496 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
4497 return -EINVAL;
4498 }
4499
4500 if ((NULL == s_priv_data.pointer) ||
4501 (s_priv_data.length < QCSAP_MAX_WSC_IE)) {
4502 return -EINVAL;
4503 }
4504
4505 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
4506 s_priv_data.length);
4507
4508 if (NULL == wps_genie) {
4509 hddLog(LOG1, FL("failed to alloc mem and copy data"));
4510 return -EFAULT;
4511 }
4512
4513 fwps_genie = wps_genie;
4514
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304515 pSap_WPSIe = qdf_mem_malloc(sizeof(tSap_WPSIE));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004516 if (NULL == pSap_WPSIe) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304517 hddLog(LOGE, "QDF unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004518 kfree(fwps_genie);
4519 return -ENOMEM;
4520 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304521 qdf_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004522
4523 hddLog(LOG1, FL("WPS IE type[0x%X] IE[0x%X], LEN[%d]"),
4524 wps_genie[0], wps_genie[1], wps_genie[2]);
4525 WPSIeType = wps_genie[0];
4526 if (wps_genie[0] == eQC_WPS_BEACON_IE) {
4527 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
4528 wps_genie = wps_genie + 1;
4529 switch (wps_genie[0]) {
4530 case DOT11F_EID_WPA:
4531 if (wps_genie[1] < 2 + 4) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304532 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004533 kfree(fwps_genie);
4534 return -EINVAL;
4535 } else if (memcmp(&wps_genie[2],
4536 "\x00\x50\xf2\x04", 4) == 0) {
4537 hddLog(LOG1, FL("Set WPS BEACON IE(len %d)"),
4538 wps_genie[1] + 2);
4539 pos = &wps_genie[6];
4540 while (((size_t) pos -
4541 (size_t) &wps_genie[6]) <
4542 (wps_genie[1] - 4)) {
4543 switch ((uint16_t) (*pos << 8) |
4544 *(pos + 1)) {
4545 case HDD_WPS_ELEM_VERSION:
4546 pos += 4;
4547 pSap_WPSIe->sapwpsie.
4548 sapWPSBeaconIE.Version =
4549 *pos;
4550 hddLog(LOG1, "WPS version %d",
4551 pSap_WPSIe->sapwpsie.
4552 sapWPSBeaconIE.Version);
4553 pSap_WPSIe->sapwpsie.
4554 sapWPSBeaconIE.
4555 FieldPresent |=
4556 WPS_BEACON_VER_PRESENT;
4557 pos += 1;
4558 break;
4559
4560 case HDD_WPS_ELEM_WPS_STATE:
4561 pos += 4;
4562 pSap_WPSIe->sapwpsie.
4563 sapWPSBeaconIE.wpsState =
4564 *pos;
4565 hddLog(LOG1, "WPS State %d",
4566 pSap_WPSIe->sapwpsie.
4567 sapWPSBeaconIE.wpsState);
4568 pSap_WPSIe->sapwpsie.
4569 sapWPSBeaconIE.
4570 FieldPresent |=
4571 WPS_BEACON_STATE_PRESENT;
4572 pos += 1;
4573 break;
4574 case HDD_WPS_ELEM_APSETUPLOCK:
4575 pos += 4;
4576 pSap_WPSIe->sapwpsie.
4577 sapWPSBeaconIE.
4578 APSetupLocked = *pos;
4579 hddLog(LOG1, "AP setup lock %d",
4580 pSap_WPSIe->sapwpsie.
4581 sapWPSBeaconIE.
4582 APSetupLocked);
4583 pSap_WPSIe->sapwpsie.
4584 sapWPSBeaconIE.
4585 FieldPresent |=
4586 WPS_BEACON_APSETUPLOCK_PRESENT;
4587 pos += 1;
4588 break;
4589 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4590 pos += 4;
4591 pSap_WPSIe->sapwpsie.
4592 sapWPSBeaconIE.
4593 SelectedRegistra = *pos;
4594 hddLog(LOG1,
4595 "Selected Registra %d",
4596 pSap_WPSIe->sapwpsie.
4597 sapWPSBeaconIE.
4598 SelectedRegistra);
4599 pSap_WPSIe->sapwpsie.
4600 sapWPSBeaconIE.
4601 FieldPresent |=
4602 WPS_BEACON_SELECTEDREGISTRA_PRESENT;
4603 pos += 1;
4604 break;
4605 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4606 pos += 4;
4607 pSap_WPSIe->sapwpsie.
4608 sapWPSBeaconIE.
4609 DevicePasswordID =
4610 (*pos << 8) | *(pos + 1);
4611 hddLog(LOG1, "Password ID: %x",
4612 pSap_WPSIe->sapwpsie.
4613 sapWPSBeaconIE.
4614 DevicePasswordID);
4615 pSap_WPSIe->sapwpsie.
4616 sapWPSBeaconIE.
4617 FieldPresent |=
4618 WPS_BEACON_DEVICEPASSWORDID_PRESENT;
4619 pos += 2;
4620 break;
4621 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4622 pos +=
4623 4;
4624 pSap_WPSIe->sapwpsie.
4625 sapWPSBeaconIE.
4626 SelectedRegistraCfgMethod =
4627 (*pos << 8) | *(pos + 1);
4628 hddLog(LOG1,
4629 "Select Registra Config Methods: %x",
4630 pSap_WPSIe->sapwpsie.
4631 sapWPSBeaconIE.
4632 SelectedRegistraCfgMethod);
4633 pSap_WPSIe->sapwpsie.
4634 sapWPSBeaconIE.
4635 FieldPresent |=
4636 WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
4637 pos += 2;
4638 break;
4639
4640 case HDD_WPS_ELEM_UUID_E:
4641 pos += 2;
4642 length = *pos << 8 | *(pos + 1);
4643 pos += 2;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304644 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004645 sapwpsie.
4646 sapWPSBeaconIE.
4647 UUID_E, pos,
4648 length);
4649 pSap_WPSIe->sapwpsie.
4650 sapWPSBeaconIE.
4651 FieldPresent |=
4652 WPS_BEACON_UUIDE_PRESENT;
4653 pos += length;
4654 break;
4655 case HDD_WPS_ELEM_RF_BANDS:
4656 pos += 4;
4657 pSap_WPSIe->sapwpsie.
4658 sapWPSBeaconIE.RFBand =
4659 *pos;
4660 hddLog(LOG1, "RF band: %d",
4661 pSap_WPSIe->sapwpsie.
4662 sapWPSBeaconIE.RFBand);
4663 pSap_WPSIe->sapwpsie.
4664 sapWPSBeaconIE.
4665 FieldPresent |=
4666 WPS_BEACON_RF_BANDS_PRESENT;
4667 pos += 1;
4668 break;
4669
4670 default:
4671 hddLog(LOGW,
4672 "UNKNOWN TLV in WPS IE(%x)",
4673 (*pos << 8 |
4674 *(pos + 1)));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304675 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004676 kfree(fwps_genie);
4677 return -EINVAL;
4678 }
4679 }
4680 } else {
4681 hddLog(LOGE, FL("WPS IE Mismatch %X"),
4682 wps_genie[0]);
4683 }
4684 break;
4685
4686 default:
4687 hddLog(LOGE, FL("Set UNKNOWN IE %X"), wps_genie[0]);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304688 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004689 kfree(fwps_genie);
4690 return 0;
4691 }
4692 } else if (wps_genie[0] == eQC_WPS_PROBE_RSP_IE) {
4693 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
4694 wps_genie = wps_genie + 1;
4695 switch (wps_genie[0]) {
4696 case DOT11F_EID_WPA:
4697 if (wps_genie[1] < 2 + 4) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304698 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004699 kfree(fwps_genie);
4700 return -EINVAL;
4701 } else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4)
4702 == 0) {
4703 hddLog(LOG1, FL("Set WPS PROBE RSP IE(len %d)"),
4704 wps_genie[1] + 2);
4705 pos = &wps_genie[6];
4706 while (((size_t) pos -
4707 (size_t) &wps_genie[6]) <
4708 (wps_genie[1] - 4)) {
4709 switch ((uint16_t) (*pos << 8) |
4710 *(pos + 1)) {
4711 case HDD_WPS_ELEM_VERSION:
4712 pos += 4;
4713 pSap_WPSIe->sapwpsie.
4714 sapWPSProbeRspIE.Version =
4715 *pos;
4716 hddLog(LOG1, "WPS version %d",
4717 pSap_WPSIe->sapwpsie.
4718 sapWPSProbeRspIE.
4719 Version);
4720 pSap_WPSIe->sapwpsie.
4721 sapWPSProbeRspIE.
4722 FieldPresent |=
4723 WPS_PROBRSP_VER_PRESENT;
4724 pos += 1;
4725 break;
4726
4727 case HDD_WPS_ELEM_WPS_STATE:
4728 pos += 4;
4729 pSap_WPSIe->sapwpsie.
4730 sapWPSProbeRspIE.wpsState =
4731 *pos;
4732 hddLog(LOG1, "WPS State %d",
4733 pSap_WPSIe->sapwpsie.
4734 sapWPSProbeRspIE.
4735 wpsState);
4736 pSap_WPSIe->sapwpsie.
4737 sapWPSProbeRspIE.
4738 FieldPresent |=
4739 WPS_PROBRSP_STATE_PRESENT;
4740 pos += 1;
4741 break;
4742 case HDD_WPS_ELEM_APSETUPLOCK:
4743 pos += 4;
4744 pSap_WPSIe->sapwpsie.
4745 sapWPSProbeRspIE.
4746 APSetupLocked = *pos;
4747 hddLog(LOG1, "AP setup lock %d",
4748 pSap_WPSIe->sapwpsie.
4749 sapWPSProbeRspIE.
4750 APSetupLocked);
4751 pSap_WPSIe->sapwpsie.
4752 sapWPSProbeRspIE.
4753 FieldPresent |=
4754 WPS_PROBRSP_APSETUPLOCK_PRESENT;
4755 pos += 1;
4756 break;
4757 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4758 pos += 4;
4759 pSap_WPSIe->sapwpsie.
4760 sapWPSProbeRspIE.
4761 SelectedRegistra = *pos;
4762 hddLog(LOG1,
4763 "Selected Registra %d",
4764 pSap_WPSIe->sapwpsie.
4765 sapWPSProbeRspIE.
4766 SelectedRegistra);
4767 pSap_WPSIe->sapwpsie.
4768 sapWPSProbeRspIE.
4769 FieldPresent |=
4770 WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
4771 pos += 1;
4772 break;
4773 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4774 pos += 4;
4775 pSap_WPSIe->sapwpsie.
4776 sapWPSProbeRspIE.
4777 DevicePasswordID =
4778 (*pos << 8) | *(pos + 1);
4779 hddLog(LOG1, "Password ID: %d",
4780 pSap_WPSIe->sapwpsie.
4781 sapWPSProbeRspIE.
4782 DevicePasswordID);
4783 pSap_WPSIe->sapwpsie.
4784 sapWPSProbeRspIE.
4785 FieldPresent |=
4786 WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
4787 pos += 2;
4788 break;
4789 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4790 pos +=
4791 4;
4792 pSap_WPSIe->sapwpsie.
4793 sapWPSProbeRspIE.
4794 SelectedRegistraCfgMethod =
4795 (*pos << 8) | *(pos + 1);
4796 hddLog(LOG1,
4797 "Select Registra Config Methods: %x",
4798 pSap_WPSIe->sapwpsie.
4799 sapWPSProbeRspIE.
4800 SelectedRegistraCfgMethod);
4801 pSap_WPSIe->sapwpsie.
4802 sapWPSProbeRspIE.
4803 FieldPresent |=
4804 WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
4805 pos += 2;
4806 break;
4807 case HDD_WPS_ELEM_RSP_TYPE:
4808 pos += 4;
4809 pSap_WPSIe->sapwpsie.
4810 sapWPSProbeRspIE.
4811 ResponseType = *pos;
4812 hddLog(LOG1,
4813 "Config Methods: %d",
4814 pSap_WPSIe->sapwpsie.
4815 sapWPSProbeRspIE.
4816 ResponseType);
4817 pSap_WPSIe->sapwpsie.
4818 sapWPSProbeRspIE.
4819 FieldPresent |=
4820 WPS_PROBRSP_RESPONSETYPE_PRESENT;
4821 pos += 1;
4822 break;
4823 case HDD_WPS_ELEM_UUID_E:
4824 pos += 2;
4825 length = *pos << 8 | *(pos + 1);
4826 pos += 2;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304827 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004828 sapwpsie.
4829 sapWPSProbeRspIE.
4830 UUID_E, pos,
4831 length);
4832 pSap_WPSIe->sapwpsie.
4833 sapWPSProbeRspIE.
4834 FieldPresent |=
4835 WPS_PROBRSP_UUIDE_PRESENT;
4836 pos += length;
4837 break;
4838
4839 case HDD_WPS_ELEM_MANUFACTURER:
4840 pos += 2;
4841 length = *pos << 8 | *(pos + 1);
4842 pos += 2;
4843 pSap_WPSIe->sapwpsie.
4844 sapWPSProbeRspIE.
4845 Manufacture.num_name =
4846 length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304847 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848 sapwpsie.
4849 sapWPSProbeRspIE.
4850 Manufacture.name,
4851 pos, length);
4852 pSap_WPSIe->sapwpsie.
4853 sapWPSProbeRspIE.
4854 FieldPresent |=
4855 WPS_PROBRSP_MANUFACTURE_PRESENT;
4856 pos += length;
4857 break;
4858
4859 case HDD_WPS_ELEM_MODEL_NAME:
4860 pos += 2;
4861 length = *pos << 8 | *(pos + 1);
4862 pos += 2;
4863 pSap_WPSIe->sapwpsie.
4864 sapWPSProbeRspIE.ModelName.
4865 num_text = length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304866 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004867 sapwpsie.
4868 sapWPSProbeRspIE.
4869 ModelName.text,
4870 pos, length);
4871 pSap_WPSIe->sapwpsie.
4872 sapWPSProbeRspIE.
4873 FieldPresent |=
4874 WPS_PROBRSP_MODELNAME_PRESENT;
4875 pos += length;
4876 break;
4877 case HDD_WPS_ELEM_MODEL_NUM:
4878 pos += 2;
4879 length = *pos << 8 | *(pos + 1);
4880 pos += 2;
4881 pSap_WPSIe->sapwpsie.
4882 sapWPSProbeRspIE.
4883 ModelNumber.num_text =
4884 length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304885 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004886 sapwpsie.
4887 sapWPSProbeRspIE.
4888 ModelNumber.text,
4889 pos, length);
4890 pSap_WPSIe->sapwpsie.
4891 sapWPSProbeRspIE.
4892 FieldPresent |=
4893 WPS_PROBRSP_MODELNUMBER_PRESENT;
4894 pos += length;
4895 break;
4896 case HDD_WPS_ELEM_SERIAL_NUM:
4897 pos += 2;
4898 length = *pos << 8 | *(pos + 1);
4899 pos += 2;
4900 pSap_WPSIe->sapwpsie.
4901 sapWPSProbeRspIE.
4902 SerialNumber.num_text =
4903 length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304904 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004905 sapwpsie.
4906 sapWPSProbeRspIE.
4907 SerialNumber.text,
4908 pos, length);
4909 pSap_WPSIe->sapwpsie.
4910 sapWPSProbeRspIE.
4911 FieldPresent |=
4912 WPS_PROBRSP_SERIALNUMBER_PRESENT;
4913 pos += length;
4914 break;
4915 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
4916 pos += 4;
4917 pSap_WPSIe->sapwpsie.
4918 sapWPSProbeRspIE.
4919 PrimaryDeviceCategory =
4920 (*pos << 8 | *(pos + 1));
4921 hddLog(LOG1,
4922 "primary dev category: %d",
4923 pSap_WPSIe->sapwpsie.
4924 sapWPSProbeRspIE.
4925 PrimaryDeviceCategory);
4926 pos += 2;
4927
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304928 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004929 sapwpsie.
4930 sapWPSProbeRspIE.
4931 PrimaryDeviceOUI,
4932 pos,
4933 HDD_WPS_DEVICE_OUI_LEN);
4934 hddLog(LOG1,
4935 "primary dev oui: %02x, %02x, %02x, %02x",
4936 pos[0], pos[1], pos[2],
4937 pos[3]);
4938 pos += 4;
4939 pSap_WPSIe->sapwpsie.
4940 sapWPSProbeRspIE.
4941 DeviceSubCategory =
4942 (*pos << 8 | *(pos + 1));
4943 hddLog(LOG1,
4944 "primary dev sub category: %d",
4945 pSap_WPSIe->sapwpsie.
4946 sapWPSProbeRspIE.
4947 DeviceSubCategory);
4948 pos += 2;
4949 pSap_WPSIe->sapwpsie.
4950 sapWPSProbeRspIE.
4951 FieldPresent |=
4952 WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
4953 break;
4954 case HDD_WPS_ELEM_DEVICE_NAME:
4955 pos += 2;
4956 length = *pos << 8 | *(pos + 1);
4957 pos += 2;
4958 pSap_WPSIe->sapwpsie.
4959 sapWPSProbeRspIE.DeviceName.
4960 num_text = length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304961 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004962 sapwpsie.
4963 sapWPSProbeRspIE.
4964 DeviceName.text,
4965 pos, length);
4966 pos += length;
4967 pSap_WPSIe->sapwpsie.
4968 sapWPSProbeRspIE.
4969 FieldPresent |=
4970 WPS_PROBRSP_DEVICENAME_PRESENT;
4971 break;
4972 case HDD_WPS_ELEM_CONFIG_METHODS:
4973 pos += 4;
4974 pSap_WPSIe->sapwpsie.
4975 sapWPSProbeRspIE.
4976 ConfigMethod =
4977 (*pos << 8) | *(pos + 1);
4978 hddLog(LOG1,
4979 "Config Methods: %d",
4980 pSap_WPSIe->sapwpsie.
4981 sapWPSProbeRspIE.
4982 SelectedRegistraCfgMethod);
4983 pos += 2;
4984 pSap_WPSIe->sapwpsie.
4985 sapWPSProbeRspIE.
4986 FieldPresent |=
4987 WPS_PROBRSP_CONFIGMETHODS_PRESENT;
4988 break;
4989
4990 case HDD_WPS_ELEM_RF_BANDS:
4991 pos += 4;
4992 pSap_WPSIe->sapwpsie.
4993 sapWPSProbeRspIE.RFBand =
4994 *pos;
4995 hddLog(LOG1, "RF band: %d",
4996 pSap_WPSIe->sapwpsie.
4997 sapWPSProbeRspIE.RFBand);
4998 pos += 1;
4999 pSap_WPSIe->sapwpsie.
5000 sapWPSProbeRspIE.
5001 FieldPresent |=
5002 WPS_PROBRSP_RF_BANDS_PRESENT;
5003 break;
5004 } /* switch */
5005 }
5006 } else {
5007 hddLog(LOGE,
5008 FL("WPS IE Mismatch %X"), wps_genie[0]);
5009 }
5010
5011 } /* switch */
5012 }
5013#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305014 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005015 wlansap_set_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
5016 pSap_WPSIe);
5017#else
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305018 qdf_ret_status = wlansap_set_wps_ie(p_cds_context, pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005019#endif
5020 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5021 if (pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE) {
5022#ifdef WLAN_FEATURE_MBSSID
5023 wlansap_update_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
5024#else
5025 wlansap_update_wps_ie(p_cds_context);
5026#endif
5027 }
5028
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305029 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005030 kfree(fwps_genie);
5031 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305032 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005033}
5034
5035static int iw_softap_setwpsie(struct net_device *dev,
5036 struct iw_request_info *info,
5037 union iwreq_data *wrqu,
5038 char *extra)
5039{
5040 int ret;
5041
5042 cds_ssr_protect(__func__);
5043 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
5044 cds_ssr_unprotect(__func__);
5045
5046 return ret;
5047}
5048
5049static int
5050__iw_softap_stopbss(struct net_device *dev,
5051 struct iw_request_info *info,
5052 union iwreq_data *wrqu, char *extra)
5053{
5054 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305055 QDF_STATUS status = QDF_STATUS_SUCCESS;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305056 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005057 hdd_context_t *hdd_ctx;
5058
Jeff Johnson02050312016-02-11 18:40:28 -08005059 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005060
5061 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5062 status = wlan_hdd_validate_context(hdd_ctx);
5063 if (0 != status)
5064 return status;
5065
5066 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
5067 hdd_hostapd_state_t *pHostapdState =
5068 WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5069
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305070 qdf_event_reset(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005071#ifdef WLAN_FEATURE_MBSSID
5072 status =
5073 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
5074#else
5075 status =
5076 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
5077 pcds_context);
5078#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305079 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05305080 qdf_status =
5081 qdf_wait_single_event(&pHostapdState->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305082 qdf_stop_bss_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005083 10000);
5084
Anurag Chouhance0dc992016-02-16 18:18:03 +05305085 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005086 hddLog(LOGE,
5087 FL("wait for single_event failed!!"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305088 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005089 }
5090 }
5091 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08005092 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005093 pHostapdAdapter->sessionId);
5094 }
5095 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305096 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005097}
5098
5099static int iw_softap_stopbss(struct net_device *dev,
5100 struct iw_request_info *info,
5101 union iwreq_data *wrqu,
5102 char *extra)
5103{
5104 int ret;
5105
5106 cds_ssr_protect(__func__);
5107 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
5108 cds_ssr_unprotect(__func__);
5109
5110 return ret;
5111}
5112
5113static int
5114__iw_softap_version(struct net_device *dev,
5115 struct iw_request_info *info,
5116 union iwreq_data *wrqu, char *extra)
5117{
5118 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5119 hdd_context_t *hdd_ctx;
5120 int ret;
5121
Jeff Johnson02050312016-02-11 18:40:28 -08005122 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005123
5124 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5125 ret = wlan_hdd_validate_context(hdd_ctx);
5126 if (0 != ret)
5127 return ret;
5128
5129 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
5130 EXIT();
5131 return 0;
5132}
5133
5134static int iw_softap_version(struct net_device *dev,
5135 struct iw_request_info *info,
5136 union iwreq_data *wrqu,
5137 char *extra)
5138{
5139 int ret;
5140
5141 cds_ssr_protect(__func__);
5142 ret = __iw_softap_version(dev, info, wrqu, extra);
5143 cds_ssr_unprotect(__func__);
5144
5145 return ret;
5146}
5147
5148static
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305149QDF_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, uint8_t *pBuf,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005150 int buf_len) {
5151 uint8_t i;
5152 uint8_t maxSta = 0;
5153 int len = 0;
5154 const char sta_info_header[] = "staId staAddress";
5155 hdd_context_t *hdd_ctx;
5156
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305157 ENTER();
5158
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005159 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305160 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005161 "%s: Adapter is NULL", __func__);
5162 return -EINVAL;
5163 }
5164
5165 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5166 if (0 != wlan_hdd_validate_context(hdd_ctx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305167 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005168
5169 len = scnprintf(pBuf, buf_len, sta_info_header);
5170 pBuf += len;
5171 buf_len -= len;
5172
5173 maxSta = hdd_ctx->config->maxNumberOfPeers;
5174
5175 for (i = 0; i <= maxSta; i++) {
5176 if (pAdapter->aStaInfo[i].isUsed) {
5177 len =
5178 scnprintf(pBuf, buf_len,
5179 "%5d .%02x:%02x:%02x:%02x:%02x:%02x",
5180 pAdapter->aStaInfo[i].ucSTAId,
5181 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
5182 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
5183 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
5184 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
5185 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
5186 pAdapter->aStaInfo[i].macAddrSTA.
5187 bytes[5]);
5188 pBuf += len;
5189 buf_len -= len;
5190 }
5191 if (WE_GET_STA_INFO_SIZE > buf_len) {
5192 break;
5193 }
5194 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305195 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305196 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005197}
5198
5199static int __iw_softap_get_sta_info(struct net_device *dev,
5200 struct iw_request_info *info,
5201 union iwreq_data *wrqu, char *extra)
5202{
5203 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305204 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005205 hdd_context_t *hdd_ctx;
5206 int ret;
5207
Jeff Johnson02050312016-02-11 18:40:28 -08005208 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005209
5210 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5211 ret = wlan_hdd_validate_context(hdd_ctx);
5212 if (0 != ret)
5213 return ret;
5214
5215 status =
5216 hdd_softap_get_sta_info(pHostapdAdapter, extra,
5217 WE_SAP_MAX_STA_INFO);
5218
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305219 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005220 hddLog(LOGE, FL("Failed to get sta info: %d"), status);
5221 return -EINVAL;
5222 }
5223 wrqu->data.length = strlen(extra);
5224 EXIT();
5225 return 0;
5226}
5227
5228static int iw_softap_get_sta_info(struct net_device *dev,
5229 struct iw_request_info *info,
5230 union iwreq_data *wrqu,
5231 char *extra)
5232{
5233 int ret;
5234
5235 cds_ssr_protect(__func__);
5236 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
5237 cds_ssr_unprotect(__func__);
5238
5239 return ret;
5240}
5241
5242/**
5243 * __iw_set_ap_genie() - set ap wpa/rsn ie
5244 *
5245 * @dev - Pointer to the net device.
5246 * @info - Pointer to the iw_request_info.
5247 * @wrqu - Pointer to the iwreq_data.
5248 * @extra - Pointer to the data.
5249 *
5250 * Return: 0 for success, non zero for failure.
5251 */
5252static int __iw_set_ap_genie(struct net_device *dev,
5253 struct iw_request_info *info,
5254 union iwreq_data *wrqu, char *extra) {
5255
5256 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5257#ifndef WLAN_FEATURE_MBSSID
5258 v_CONTEXT_t cds_ctx;
5259#endif
5260 hdd_context_t *hdd_ctx;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305261 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005262 uint8_t *genie = (uint8_t *)extra;
5263 int ret;
5264
Jeff Johnson651f9f22016-02-11 18:16:11 -08005265 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005266
5267 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5268 ret = wlan_hdd_validate_context(hdd_ctx);
5269 if (0 != ret)
5270 return ret;
5271
5272#ifndef WLAN_FEATURE_MBSSID
5273 cds_ctx = hdd_ctx->pcds_context;
5274 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305275 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305276 "%s: QDF Context is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005277 return -EINVAL;
5278 }
5279#endif
5280
5281 if (!wrqu->data.length) {
5282 EXIT();
5283 return 0;
5284 }
5285
5286 switch (genie[0]) {
5287 case DOT11F_EID_WPA:
5288 case DOT11F_EID_RSN:
5289 if ((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) {
5290 hdd_softap_deregister_bc_sta(pHostapdAdapter);
5291 hdd_softap_register_bc_sta(pHostapdAdapter, 1);
5292 }
5293 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
5294#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305295 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005296 wlansap_set_wparsn_ies(WLAN_HDD_GET_SAP_CTX_PTR
5297 (pHostapdAdapter), genie,
5298 wrqu->data.length);
5299#else
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305300 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005301 wlansap_set_wparsn_ies(cds_ctx, genie,
5302 wrqu->data.length);
5303#endif
5304 break;
5305
5306 default:
5307 hddLog(LOGE, FL("Set UNKNOWN IE %X"), genie[0]);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305308 qdf_ret_status = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005309 }
5310
5311 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305312 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005313}
5314
5315/**
5316 * iw_set_ap_genie() - Wrapper function to protect __iw_set_ap_genie
5317 * from the SSR.
5318 *
5319 * @dev - Pointer to the net device.
5320 * @info - Pointer to the iw_request_info.
5321 * @wrqu - Pointer to the iwreq_data.
5322 * @extra - Pointer to the data.
5323 *
5324 * Return: 0 for success, non zero for failure.
5325 */
5326static int
5327iw_set_ap_genie(struct net_device *dev,
5328 struct iw_request_info *info,
5329 union iwreq_data *wrqu, char *extra)
5330{
5331 int ret;
5332
5333 cds_ssr_protect(__func__);
5334 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
5335 cds_ssr_unprotect(__func__);
5336
5337 return ret;
5338}
5339
5340static
5341int __iw_get_softap_linkspeed(struct net_device *dev,
5342 struct iw_request_info *info,
5343 union iwreq_data *wrqu, char *extra)
5344{
5345 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
5346 hdd_context_t *hdd_ctx;
5347 char *pLinkSpeed = (char *)extra;
5348 uint32_t link_speed = 0;
5349 int len = sizeof(uint32_t) + 1;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305350 struct qdf_mac_addr macAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005351 char pmacAddress[MAC_ADDRESS_STR_LEN + 1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305352 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005353 int rc, valid, i;
5354
Jeff Johnson02050312016-02-11 18:40:28 -08005355 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305356
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005357 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5358 valid = wlan_hdd_validate_context(hdd_ctx);
5359 if (0 != valid)
5360 return valid;
5361
5362 hddLog(LOG1, FL("wrqu->data.length(%d)"), wrqu->data.length);
5363
5364 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
5365 if (copy_from_user((void *)pmacAddress,
5366 wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
5367 hddLog(LOG1, FL("failed to copy data to user buffer"));
5368 return -EFAULT;
5369 }
5370 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
5371
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005372 if (!mac_pton(pmacAddress, macAddress.bytes)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005373 hddLog(LOGE, FL("String to Hex conversion Failed"));
5374 return -EINVAL;
5375 }
5376 }
5377 /* If no mac address is passed and/or its length is less than 17,
5378 * link speed for first connected client will be returned.
5379 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305380 if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005381 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
5382 if (pHostapdAdapter->aStaInfo[i].isUsed &&
Anurag Chouhanc5548422016-02-24 18:33:27 +05305383 (!qdf_is_macaddr_broadcast
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005384 (&pHostapdAdapter->aStaInfo[i].macAddrSTA))) {
Anurag Chouhanc5548422016-02-24 18:33:27 +05305385 qdf_copy_macaddr(
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005386 &macAddress,
5387 &pHostapdAdapter->aStaInfo[i].
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005388 macAddrSTA);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305389 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005390 break;
5391 }
5392 }
5393 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305394 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005395 hddLog(LOGE, FL("Invalid peer macaddress"));
5396 return -EINVAL;
5397 }
5398 status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter,
5399 macAddress);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305400 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005401 hddLog(LOGE, FL("Unable to retrieve SME linkspeed"));
5402 return -EINVAL;
5403 }
5404
5405 link_speed = pHostapdAdapter->ls_stats.estLinkSpeed;
5406
5407 /* linkspeed in units of 500 kbps */
5408 link_speed = link_speed / 500;
5409 wrqu->data.length = len;
5410 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
5411 if ((rc < 0) || (rc >= len)) {
5412 /* encoding or length error? */
5413 hddLog(LOGE, FL("Unable to encode link speed"));
5414 return -EIO;
5415 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305416 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005417 return 0;
5418}
5419
5420static int
5421iw_get_softap_linkspeed(struct net_device *dev,
5422 struct iw_request_info *info,
5423 union iwreq_data *wrqu,
5424 char *extra)
5425{
5426 int ret;
5427
5428 cds_ssr_protect(__func__);
5429 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
5430 cds_ssr_unprotect(__func__);
5431
5432 return ret;
5433}
5434
5435static const iw_handler hostapd_handler[] = {
5436 (iw_handler) NULL, /* SIOCSIWCOMMIT */
5437 (iw_handler) NULL, /* SIOCGIWNAME */
5438 (iw_handler) NULL, /* SIOCSIWNWID */
5439 (iw_handler) NULL, /* SIOCGIWNWID */
5440 (iw_handler) NULL, /* SIOCSIWFREQ */
5441 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
5442 (iw_handler) NULL, /* SIOCSIWMODE */
5443 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
5444 (iw_handler) NULL, /* SIOCSIWSENS */
5445 (iw_handler) NULL, /* SIOCGIWSENS */
5446 (iw_handler) NULL, /* SIOCSIWRANGE */
5447 (iw_handler) NULL, /* SIOCGIWRANGE */
5448 (iw_handler) NULL, /* SIOCSIWPRIV */
5449 (iw_handler) NULL, /* SIOCGIWPRIV */
5450 (iw_handler) NULL, /* SIOCSIWSTATS */
5451 (iw_handler) NULL, /* SIOCGIWSTATS */
5452 (iw_handler) NULL, /* SIOCSIWSPY */
5453 (iw_handler) NULL, /* SIOCGIWSPY */
5454 (iw_handler) NULL, /* SIOCSIWTHRSPY */
5455 (iw_handler) NULL, /* SIOCGIWTHRSPY */
5456 (iw_handler) NULL, /* SIOCSIWAP */
5457 (iw_handler) NULL, /* SIOCGIWAP */
5458 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
5459 (iw_handler) NULL, /* SIOCGIWAPLIST */
5460 (iw_handler) NULL, /* SIOCSIWSCAN */
5461 (iw_handler) NULL, /* SIOCGIWSCAN */
5462 (iw_handler) NULL, /* SIOCSIWESSID */
5463 (iw_handler) NULL, /* SIOCGIWESSID */
5464 (iw_handler) NULL, /* SIOCSIWNICKN */
5465 (iw_handler) NULL, /* SIOCGIWNICKN */
5466 (iw_handler) NULL, /* -- hole -- */
5467 (iw_handler) NULL, /* -- hole -- */
5468 (iw_handler) NULL, /* SIOCSIWRATE */
5469 (iw_handler) NULL, /* SIOCGIWRATE */
5470 (iw_handler) NULL, /* SIOCSIWRTS */
5471 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
5472 (iw_handler) NULL, /* SIOCSIWFRAG */
5473 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
5474 (iw_handler) NULL, /* SIOCSIWTXPOW */
5475 (iw_handler) NULL, /* SIOCGIWTXPOW */
5476 (iw_handler) NULL, /* SIOCSIWRETRY */
5477 (iw_handler) NULL, /* SIOCGIWRETRY */
5478 (iw_handler) NULL, /* SIOCSIWENCODE */
5479 (iw_handler) NULL, /* SIOCGIWENCODE */
5480 (iw_handler) NULL, /* SIOCSIWPOWER */
5481 (iw_handler) NULL, /* SIOCGIWPOWER */
5482 (iw_handler) NULL, /* -- hole -- */
5483 (iw_handler) NULL, /* -- hole -- */
5484 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
5485 (iw_handler) NULL, /* SIOCGIWGENIE */
5486 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
5487 (iw_handler) NULL, /* SIOCGIWAUTH */
5488 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
5489 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
5490 (iw_handler) NULL, /* SIOCSIWPMKSA */
5491};
5492
5493/*
5494 * Note that the following ioctls were defined with semantics which
5495 * cannot be handled by the "iwpriv" userspace application and hence
5496 * they are not included in the hostapd_private_args array
5497 * QCSAP_IOCTL_ASSOC_STA_MACADDR
5498 */
5499
5500static const struct iw_priv_args hostapd_private_args[] = {
5501 {
5502 QCSAP_IOCTL_SETPARAM,
5503 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
5504 }, {
5505 QCSAP_IOCTL_SETPARAM,
5506 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
5507 }, {
5508 QCSAP_PARAM_MAX_ASSOC,
5509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5510 "setMaxAssoc"
5511 }, {
5512 QCSAP_PARAM_HIDE_SSID,
5513 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
5514 }, {
5515 QCSAP_PARAM_SET_MC_RATE,
5516 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
5517 },
5518 {
5519 QCSAP_PARAM_SET_TXRX_FW_STATS,
5520 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5521 "txrx_fw_stats"
5522 }, {
5523 QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
5524 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5525 "setMccLatency"
5526 }, {
5527 QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
5528 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5529 "setMccQuota"
5530 }, {
5531 QCSAP_PARAM_SET_CHANNEL_CHANGE,
5532 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5533 "setChanChange"
5534 }, {
5535 QCSAP_PARAM_AUTO_CHANNEL,
5536 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5537 "setAutoChannel"
5538 },
5539 /* Sub-cmds DBGLOG specific commands */
5540 {
5541 QCSAP_DBGLOG_LOG_LEVEL,
5542 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5543 0, "dl_loglevel"
5544 }, {
5545 QCSAP_DBGLOG_VAP_ENABLE,
5546 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
5547 }, {
5548 QCSAP_DBGLOG_VAP_DISABLE,
5549 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5550 0, "dl_vapoff"
5551 }, {
5552 QCSAP_DBGLOG_MODULE_ENABLE,
5553 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
5554 }, {
5555 QCSAP_DBGLOG_MODULE_DISABLE,
5556 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5557 0, "dl_modoff"
5558 }, {
5559 QCSAP_DBGLOG_MOD_LOG_LEVEL,
5560 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5561 0, "dl_mod_loglevel"
5562 }, {
5563 QCSAP_DBGLOG_TYPE,
5564 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
5565 }, {
5566 QCSAP_DBGLOG_REPORT_ENABLE,
5567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5568 0, "dl_report"
5569 }, {
5570 QCASAP_TXRX_FWSTATS_RESET,
5571 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5572 0, "txrx_fw_st_rst"
5573 }, {
5574 QCSAP_PARAM_RTSCTS,
5575 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5576 0, "enablertscts"
5577 }, {
5578 QCASAP_SET_11N_RATE,
5579 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5580 0, "set11NRates"
5581 }, {
5582 QCASAP_SET_VHT_RATE,
5583 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5584 0, "set11ACRates"
5585 }, {
5586 QCASAP_SHORT_GI,
5587 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5588 0, "enable_short_gi"
5589 }, {
5590 QCSAP_SET_AMPDU,
5591 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
5592 }, {
5593 QCSAP_SET_AMSDU,
5594 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
5595 }, {
5596 QCSAP_GTX_HT_MCS,
5597 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
5598 }, {
5599 QCSAP_GTX_VHT_MCS,
5600 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5601 0, "gtxVHTMcs"
5602 }, {
5603 QCSAP_GTX_USRCFG,
5604 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5605 0, "gtxUsrCfg"
5606 }, {
5607 QCSAP_GTX_THRE,
5608 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
5609 }, {
5610 QCSAP_GTX_MARGIN,
5611 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5612 0, "gtxMargin"
5613 }, {
5614 QCSAP_GTX_STEP,
5615 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
5616 }, {
5617 QCSAP_GTX_MINTPC,
5618 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5619 0, "gtxMinTpc"
5620 }, {
5621 QCSAP_GTX_BWMASK,
5622 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5623 0, "gtxBWMask"
5624 }, {
5625 QCSAP_PARAM_CLR_ACL,
5626 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5627 0, "setClearAcl"
5628 }, {
5629 QCSAP_PARAM_ACL_MODE,
5630 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
5631 },
5632#ifdef QCA_PKT_PROTO_TRACE
5633 {
5634 QCASAP_SET_DEBUG_LOG,
5635 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setDbgLvl"
5636 },
5637#endif /* QCA_PKT_PROTO_TRACE */
5638 {
5639 QCASAP_SET_TM_LEVEL,
5640 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5641 0, "setTmLevel"
5642 }, {
5643 QCASAP_SET_DFS_IGNORE_CAC,
5644 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5645 0, "setDfsIgnoreCAC"
5646 }, {
5647 QCASAP_SET_DFS_NOL,
5648 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5649 0, "setdfsnol"
5650 }, {
5651 QCASAP_SET_DFS_TARGET_CHNL,
5652 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5653 0, "setNextChnl"
5654 }, {
5655 QCASAP_SET_RADAR_CMD,
5656 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
5657 },
5658 {
5659 QCSAP_IPA_UC_STAT,
5660 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
5661 },
5662 {
5663 QCASAP_TX_CHAINMASK_CMD,
5664 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5665 0, "set_txchainmask"
5666 }, {
5667 QCASAP_RX_CHAINMASK_CMD,
5668 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5669 0, "set_rxchainmask"
5670 }, {
5671 QCASAP_NSS_CMD,
5672 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
5673 }, {
5674 QCASAP_SET_PHYMODE,
5675 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5676 0, "setphymode"
5677 }, {
5678 QCASAP_DUMP_STATS,
5679 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5680 0, "dumpStats"
5681 }, {
5682 QCASAP_CLEAR_STATS,
5683 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5684 0, "clearStats"
5685 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305686 QCSAP_START_FW_PROFILING,
5687 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5688 0, "startProfile"
5689 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005690 QCSAP_IOCTL_GETPARAM, 0,
5691 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
5692 }, {
5693 QCSAP_IOCTL_GETPARAM, 0,
5694 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
5695 }, {
5696 QCSAP_PARAM_MAX_ASSOC, 0,
5697 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
5698 }, {
5699 QCSAP_PARAM_GET_WLAN_DBG, 0,
5700 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
5701 }, {
5702 QCSAP_PARAM_AUTO_CHANNEL, 0,
5703 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel"
5704 }, {
5705 QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5706 "get_gtxBWMask"
5707 }, {
5708 QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5709 "get_gtxMinTpc"
5710 }, {
5711 QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5712 "get_gtxStep"
5713 }, {
5714 QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5715 "get_gtxMargin"
5716 }, {
5717 QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5718 "get_gtxThre"
5719 }, {
5720 QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5721 "get_gtxUsrCfg"
5722 }, {
5723 QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5724 "get_gtxVHTMcs"
5725 }, {
5726 QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5727 "get_gtxHTMcs"
5728 }, {
5729 QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5730 "get_short_gi"
5731 }, {
5732 QCSAP_PARAM_RTSCTS, 0,
5733 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
5734 }, {
5735 QCASAP_GET_DFS_NOL, 0,
5736 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
5737 }, {
5738 QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5739 "get_acl_list"
5740 }, {
5741 QCASAP_TX_CHAINMASK_CMD, 0,
5742 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5743 "get_txchainmask"
5744 }, {
5745 QCASAP_RX_CHAINMASK_CMD, 0,
5746 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5747 "get_rxchainmask"
5748 }, {
5749 QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5750 "get_nss"
5751 }, {
5752 QCASAP_GET_TEMP_CMD, 0,
5753 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
5754 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305755 QCSAP_GET_FW_PROFILE_DATA, 0,
5756 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
5757 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005758 QCSAP_IOCTL_GET_STAWPAIE,
5759 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
5760 "get_staWPAIE"
5761 }, {
5762 QCSAP_IOCTL_SETWPAIE,
5763 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE |
5764 IW_PRIV_SIZE_FIXED, 0, "setwpaie"
5765 }, {
5766 QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
5767 "stopbss"
5768 }, {
5769 QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE,
5770 "version"
5771 }, {
5772 QCSAP_IOCTL_GET_STA_INFO, 0,
5773 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
5774 }, {
5775 QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
5776 IW_PRIV_TYPE_BYTE |
5777 sizeof(sQcSapreq_WPSPBCProbeReqIES_t) |
5778 IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs"
5779 }
5780 , {
5781 QCSAP_IOCTL_GET_CHANNEL, 0,
5782 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
5783 }
5784 , {
5785 QCSAP_IOCTL_DISASSOC_STA,
5786 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
5787 "disassoc_sta"
5788 }
5789 /* handler for main ioctl */
5790 , {
5791 QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
5792 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
5793 }
5794 /* handler for sub-ioctl */
5795 , {
5796 QCSAP_GET_STATS, 0,
5797 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
5798 }
5799 , {
Govind Singha471e5e2015-10-12 17:11:14 +05305800 QCSAP_LIST_FW_PROFILE, 0,
5801 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
5802 }
5803 , {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005804 QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
5805 IW_PRIV_TYPE_CHAR | 18,
5806 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
5807 }
5808 , {
5809 QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
5810 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
5811 }
5812 ,
5813 /* handlers for sub-ioctl */
5814 {
5815 WE_SET_WLAN_DBG,
5816 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
5817 }, {
5818 WE_SET_SAP_CHANNELS,
5819 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setsapchannels"
5820 }
5821 ,
5822 /* handlers for sub-ioctl */
5823 {
5824 WE_SET_DP_TRACE,
5825 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
5826 }
5827 ,
5828 /* handlers for main ioctl */
5829 {
5830 QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
5831 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
5832 }
5833 , {
5834 WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
5835 }
5836 , {
5837 WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
5838 "setUnitTestCmd"
5839 }
5840 ,
5841 /* handlers for main ioctl */
5842 {
5843 QCSAP_IOCTL_MODIFY_ACL,
5844 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
5845 }
5846 ,
5847 /* handlers for main ioctl */
5848 {
5849 QCSAP_IOCTL_GET_CHANNEL_LIST,
5850 0,
5851 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
5852 "getChannelList"
5853 }
5854 ,
5855 /* handlers for main ioctl */
5856 {
5857 QCSAP_IOCTL_SET_TX_POWER,
5858 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
5859 }
5860 ,
5861 /* handlers for main ioctl */
5862 {
5863 QCSAP_IOCTL_SET_MAX_TX_POWER,
5864 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5865 0, "setTxMaxPower"
5866 }
5867 ,
5868 /* Set HDD CFG Ini param */
5869 {
5870 QCSAP_IOCTL_SET_INI_CFG,
5871 IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig"
5872 }
5873 ,
5874 /* Get HDD CFG Ini param */
5875 {
5876 QCSAP_IOCTL_GET_INI_CFG,
5877 0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
5878 }
5879 ,
5880 /* handlers for main ioctl */
5881 {
5882 /* handlers for main ioctl */
5883 QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
5884 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
5885 }
5886 ,
5887 /* handlers for sub-ioctl */
5888#ifdef DEBUG
5889 {
5890 QCSAP_IOCTL_SET_FW_CRASH_INJECT,
5891 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5892 0, "crash_inject"
5893 }
5894 ,
5895#endif
5896 {
5897 QCASAP_SET_RADAR_DBG,
5898 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5899 0, "setRadarDbg"
5900 }
5901 ,
5902 /* dump dp trace - descriptor or dp trace records */
5903 {
5904 QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
5905 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5906 0, "dump_dp_trace"
5907 }
5908 ,
Govind Singha471e5e2015-10-12 17:11:14 +05305909 {
5910 QCSAP_ENABLE_FW_PROFILE,
5911 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5912 0, "enableProfile"
5913 }
5914 ,
5915 {
5916 QCSAP_SET_FW_PROFILE_HIST_INTVL,
5917 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5918 0, "set_hist_intvl"
5919 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005920};
5921
5922static const iw_handler hostapd_private[] = {
5923 /* set priv ioctl */
5924 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
5925 /* get priv ioctl */
5926 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
5927 /* get station genIE */
5928 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
5929 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
5930 /* stop bss */
5931 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
5932 /* get driver version */
5933 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
5934 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] =
5935 iw_get_wpspbc_probe_req_ies,
5936 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
5937 iw_softap_getchannel,
5938 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
5939 iw_softap_getassoc_stamacaddr,
5940 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
5941 iw_softap_disassoc_sta,
5942 [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
5943 iw_get_char_setnone,
5944 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
5945 SIOCIWFIRSTPRIV] =
5946 iw_set_three_ints_getnone,
5947 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
5948 SIOCIWFIRSTPRIV] =
5949 iw_set_var_ints_getnone,
5950 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] =
5951 iw_softap_set_force_acs_ch_range,
5952 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
5953 iw_softap_modify_acl,
5954 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
5955 iw_softap_get_channel_list,
5956 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
5957 iw_softap_get_sta_info,
5958 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
5959 SIOCIWFIRSTPRIV] =
5960 iw_get_softap_linkspeed,
5961 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
5962 iw_softap_set_tx_power,
5963 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
5964 iw_softap_set_max_tx_power,
5965 [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
5966 iw_softap_set_ini_cfg,
5967 [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
5968 iw_softap_get_ini_cfg,
5969 [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
5970 iw_softap_set_two_ints_getnone,
5971};
5972const struct iw_handler_def hostapd_handler_def = {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305973 .num_standard = QDF_ARRAY_SIZE(hostapd_handler),
5974 .num_private = QDF_ARRAY_SIZE(hostapd_private),
5975 .num_private_args = QDF_ARRAY_SIZE(hostapd_private_args),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005976 .standard = (iw_handler *) hostapd_handler,
5977 .private = (iw_handler *) hostapd_private,
5978 .private_args = hostapd_private_args,
5979 .get_wireless_stats = NULL,
5980};
5981
5982struct net_device_ops net_ops_struct = {
5983 .ndo_open = hdd_hostapd_open,
5984 .ndo_stop = hdd_hostapd_stop,
5985 .ndo_uninit = hdd_hostapd_uninit,
5986 .ndo_start_xmit = hdd_softap_hard_start_xmit,
5987 .ndo_tx_timeout = hdd_softap_tx_timeout,
5988 .ndo_get_stats = hdd_get_stats,
5989 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
5990 .ndo_do_ioctl = hdd_ioctl,
5991 .ndo_change_mtu = hdd_hostapd_change_mtu,
5992 .ndo_select_queue = hdd_hostapd_select_queue,
5993};
5994
5995static int hdd_set_hostapd(hdd_adapter_t *pAdapter)
5996{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305997 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005998}
5999
6000void hdd_set_ap_ops(struct net_device *pWlanHostapdDev)
6001{
6002 pWlanHostapdDev->netdev_ops = &net_ops_struct;
6003}
6004
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306005QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006006{
6007 hdd_hostapd_state_t *phostapdBuf;
6008 struct net_device *dev = pAdapter->dev;
6009 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306010 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05306011 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006012#ifdef WLAN_FEATURE_MBSSID
6013 v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(pAdapter))->pcds_context;
6014 v_CONTEXT_t sapContext = NULL;
6015#endif
6016 int ret;
6017
6018 ENTER();
6019
6020#ifdef WLAN_FEATURE_MBSSID
6021 sapContext = wlansap_open(p_cds_context);
6022 if (sapContext == NULL) {
6023 hddLog(LOGE, ("ERROR: wlansap_open failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306024 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006025 }
6026
6027 pAdapter->sessionCtx.ap.sapContext = sapContext;
6028
6029 status = wlansap_start(sapContext);
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: wlansap_start failed!!"));
6032 wlansap_close(sapContext);
6033 return status;
6034 }
6035#endif
6036
6037 /* Allocate the Wireless Extensions state structure */
6038 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6039
6040 sme_set_curr_device_mode(pHddCtx->hHal, pAdapter->device_mode);
6041
6042 /* Zero the memory. This zeros the profile structure. */
6043 memset(phostapdBuf, 0, sizeof(hdd_hostapd_state_t));
6044
6045 /* Set up the pointer to the Wireless Extensions state structure */
6046 /* NOP */
6047 status = hdd_set_hostapd(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306048 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006049 hddLog(LOGE, ("ERROR: hdd_set_hostapd failed!!"));
6050#ifdef WLAN_FEATURE_MBSSID
6051 wlansap_close(sapContext);
6052#endif
6053 return status;
6054 }
6055
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306056 qdf_status = qdf_event_create(&phostapdBuf->qdf_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05306057 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306058 hddLog(LOGE, ("ERROR: Hostapd HDD qdf event init failed!!"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006059#ifdef WLAN_FEATURE_MBSSID
6060 wlansap_close(sapContext);
6061#endif
Anurag Chouhance0dc992016-02-16 18:18:03 +05306062 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006063 }
6064
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306065 qdf_status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05306066 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306067 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006068 ("ERROR: Hostapd HDD stop bss event init failed!!"));
6069#ifdef WLAN_FEATURE_MBSSID
6070 wlansap_close(sapContext);
6071#endif
Anurag Chouhance0dc992016-02-16 18:18:03 +05306072 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006073 }
6074
6075 init_completion(&pAdapter->session_close_comp_var);
6076 init_completion(&pAdapter->session_open_comp_var);
6077
6078 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
6079
6080 /* Register as a wireless device */
6081 dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
6082
6083 /* Initialize the data path module */
6084 status = hdd_softap_init_tx_rx(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306085 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006086 hddLog(LOGP, FL("hdd_softap_init_tx_rx failed"));
6087 }
6088
6089 status = hdd_wmm_adapter_init(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306090 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006091 hddLog(LOGE,
6092 "hdd_wmm_adapter_init() failed code %08d [x%08x]",
6093 status, status);
6094 goto error_wmm_init;
6095 }
6096
6097 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6098
6099 ret = wma_cli_set_command(pAdapter->sessionId,
6100 WMI_PDEV_PARAM_BURST_ENABLE,
6101 pHddCtx->config->enableSifsBurst,
6102 PDEV_CMD);
6103
6104 if (0 != ret) {
6105 hddLog(LOGE,
6106 FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"), ret);
6107 }
6108 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306109 qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
6110 qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006111 sizeof(struct sap_acs_cfg));
6112 return status;
6113
6114error_wmm_init:
6115 hdd_softap_deinit_tx_rx(pAdapter);
6116#ifdef WLAN_FEATURE_MBSSID
6117 wlansap_close(sapContext);
6118#endif
6119 EXIT();
6120 return status;
6121}
6122
6123/**
6124 * hdd_wlan_create_ap_dev() - create an AP-mode device
6125 * @pHddCtx: Global HDD context
6126 * @macAddr: MAC address to assign to the interface
6127 * @iface_name: User-visible name of the interface
6128 *
6129 * This function will allocate a Linux net_device and configuration it
6130 * for an AP mode of operation. Note that the device is NOT actually
6131 * registered with the kernel at this time.
6132 *
6133 * Return: A pointer to the private data portion of the net_device if
6134 * the allocation and initialization was successful, NULL otherwise.
6135 */
6136hdd_adapter_t *hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx,
6137 tSirMacAddr macAddr,
6138 uint8_t *iface_name) {
6139 struct net_device *pWlanHostapdDev = NULL;
6140 hdd_adapter_t *pHostapdAdapter = NULL;
6141
6142 hddLog(LOG4, FL("iface_name = %s"), iface_name);
6143
6144 pWlanHostapdDev =
6145 alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name,
6146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
6147 NET_NAME_UNKNOWN,
6148#endif
6149 ether_setup,
6150 NUM_TX_QUEUES);
6151
6152 if (pWlanHostapdDev != NULL) {
6153 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
6154
6155 /* Init the net_device structure */
6156 ether_setup(pWlanHostapdDev);
6157
6158 /* Initialize the adapter context to zeros. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306159 qdf_mem_zero(pHostapdAdapter, sizeof(hdd_adapter_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006160 pHostapdAdapter->dev = pWlanHostapdDev;
6161 pHostapdAdapter->pHddCtx = pHddCtx;
6162 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6163
6164 hddLog(LOG4,
6165 FL("pWlanHostapdDev = %p, pHostapdAdapter = %p, concurrency_mode=0x%x"),
6166 pWlanHostapdDev,
6167 pHostapdAdapter,
6168 (int)cds_get_concurrency_mode());
6169
6170 /* Init the net_device structure */
6171 strlcpy(pWlanHostapdDev->name, (const char *)iface_name,
6172 IFNAMSIZ);
6173
6174 hdd_set_ap_ops(pHostapdAdapter->dev);
6175
6176 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
6177 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
Mohit Khannaee9e80f2015-11-10 11:32:49 -08006178 pWlanHostapdDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006179
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306180 qdf_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006181 sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306182 qdf_mem_copy(pHostapdAdapter->macAddressCurrent.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006183 (void *)macAddr, sizeof(tSirMacAddr));
6184
6185 pHostapdAdapter->offloads_configured = false;
6186 pWlanHostapdDev->destructor = free_netdev;
6187 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev;
6188 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
6189 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
Dhanashri Atre83d373d2015-07-28 16:45:59 -07006190 hdd_set_tso_flags(pHddCtx, pWlanHostapdDev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006191 init_completion(&pHostapdAdapter->tx_action_cnf_event);
6192 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
6193 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
6194 init_completion(&pHostapdAdapter->sta_authorized_event);
6195 init_completion(&pHostapdAdapter->offchannel_tx_event);
6196 init_completion(&pHostapdAdapter->scan_info.
6197 abortscan_event_var);
6198
6199 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
6200 spin_lock_init(&pHostapdAdapter->pause_map_lock);
6201 }
6202 return pHostapdAdapter;
6203}
6204
6205/**
6206 * hdd_register_hostapd() - register hostapd
6207 * @pAdapter: Pointer to hostapd adapter
6208 * @rtnl_lock_held: RTNL lock held
6209 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306210 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006211 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306212QDF_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006213 uint8_t rtnl_lock_held) {
6214 struct net_device *dev = pAdapter->dev;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306215 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006216
6217 ENTER();
6218
6219 if (rtnl_lock_held) {
6220 if (strnchr(dev->name, strlen(dev->name), '%')) {
6221 if (dev_alloc_name(dev, dev->name) < 0) {
6222 hddLog(LOGE, FL("Failed:dev_alloc_name"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306223 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006224 }
6225 }
6226 if (register_netdevice(dev)) {
6227 hddLog(LOGE, FL("Failed:register_netdevice"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306228 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006229 }
6230 } else {
6231 if (register_netdev(dev)) {
6232 hddLog(LOGE, FL("Failed:register_netdev"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306233 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006234 }
6235 }
6236 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6237
6238 EXIT();
6239 return status;
6240}
6241
6242/**
6243 * hdd_unregister_hostapd() - unregister hostapd
6244 * @pAdapter: Pointer to hostapd adapter
6245 * @rtnl_held: true if rtnl lock held; false otherwise
6246 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306247 * Return: QDF_STATUS enumaration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006248 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306249QDF_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006250{
6251#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306252 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006253 void *sapContext = WLAN_HDD_GET_SAP_CTX_PTR(pAdapter);
6254#endif
6255
6256 ENTER();
6257
6258 hdd_softap_deinit_tx_rx(pAdapter);
6259
6260 /* if we are being called during driver unload,
6261 * then the dev has already been invalidated.
6262 * if we are being called at other times, then we can
6263 * detach the wireless device handlers
6264 */
6265 if (pAdapter->dev) {
6266 if (rtnl_held)
6267 pAdapter->dev->wireless_handlers = NULL;
6268 else {
6269 rtnl_lock();
6270 pAdapter->dev->wireless_handlers = NULL;
6271 rtnl_unlock();
6272 }
6273 }
6274
6275#ifdef WLAN_FEATURE_MBSSID
6276 status = wlansap_stop(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306277 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006278 hddLog(LOGE, FL("Failed:wlansap_stop"));
6279
6280 status = wlansap_close(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306281 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006282 hddLog(LOGE, FL("Failed:WLANSAP_close"));
6283 pAdapter->sessionCtx.ap.sapContext = NULL;
6284#endif
6285
6286 EXIT();
6287 return 0;
6288}
6289
6290/**
6291 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
6292 * @rate: Rate to be checked
6293 *
6294 * Return: true if rate if 11g else false
6295 */
6296static bool wlan_hdd_rate_is_11g(u8 rate)
6297{
6298 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
6299 96, 108}; /* actual rate * 2 */
6300 u8 i;
6301 for (i = 0; i < 8; i++) {
6302 if (rate == gRateArray[i])
6303 return true;
6304 }
6305 return false;
6306}
6307
6308#ifdef QCA_HT_2040_COEX
6309/**
6310 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
6311 * @pHostapdAdapter: Pointer to hostapd adapter
6312 *
6313 * Return: HT support channel width config value
6314 */
6315static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6316{
6317 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
6318 tDot11fIEHTCaps dot11_ht_cap_ie = {0};
6319 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
6320 beacon_data_t *beacon = pHostapdAdapter->sessionCtx.ap.beacon;
6321 uint8_t *ie = NULL;
6322
6323 ie = wlan_hdd_cfg80211_get_ie_ptr(beacon->tail, beacon->tail_len,
6324 WLAN_EID_HT_CAPABILITY);
6325 if (ie && ie[1]) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306326 qdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006327 dot11f_unpack_ie_ht_caps((tpAniSirGlobal)hdd_ctx->hHal,
6328 ht_cap_ie, ie[1], &dot11_ht_cap_ie);
6329 return dot11_ht_cap_ie.supportedChannelWidthSet;
6330 }
6331
6332 return false;
6333}
6334#else
6335static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6336{
6337 return false;
6338}
6339#endif
6340/**
6341 * wlan_hdd_set_channel() - set channel in sap mode
6342 * @wiphy: Pointer to wiphy structure
6343 * @dev: Pointer to net_device structure
6344 * @chandef: Pointer to channel definition structure
6345 * @channel_type: Channel type
6346 *
6347 * Return: 0 for success non-zero for failure
6348 */
6349static int wlan_hdd_set_channel(struct wiphy *wiphy,
6350 struct net_device *dev,
6351 struct cfg80211_chan_def *chandef,
6352 enum nl80211_channel_type channel_type)
6353{
6354 hdd_adapter_t *pAdapter = NULL;
6355 uint32_t num_ch = 0;
6356 int channel = 0;
6357 int channel_seg2 = 0;
6358 hdd_context_t *pHddCtx;
6359 int status;
6360
6361 tSmeConfigParams smeConfig;
6362 tsap_Config_t *sap_config;
6363
6364 ENTER();
6365
6366
6367 if (NULL == dev) {
6368 hddLog(LOGE, FL("Called with dev = NULL."));
6369 return -ENODEV;
6370 }
6371 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6372
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306373 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006374 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
6375 pAdapter->sessionId, channel_type));
6376
6377 hddLog(LOG1, FL("Device_mode %s(%d) freq = %d"),
6378 hdd_device_mode_to_string(pAdapter->device_mode),
6379 pAdapter->device_mode, chandef->chan->center_freq);
6380
6381 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6382 status = wlan_hdd_validate_context(pHddCtx);
6383
6384 if (0 != status) {
6385 hddLog(LOGE, FL("HDD context is not valid"));
6386 return status;
6387 }
6388
6389 /*
6390 * Do freq to chan conversion
6391 * TODO: for 11a
6392 */
6393
6394 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
6395 if (NL80211_CHAN_WIDTH_80P80 == chandef->width)
6396 channel_seg2 = ieee80211_frequency_to_channel(chandef->center_freq2);
6397 else
6398 channel_seg2 = 0;
6399
6400 /* Check freq range */
6401 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6402 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
6403 hddLog(LOGE,
6404 FL("Channel [%d] is outside valid range from %d to %d"),
6405 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6406 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6407 return -EINVAL;
6408 }
6409
6410 /* Check freq range */
6411
6412 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
6413 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
6414 hddLog(LOGE,
6415 FL("Channel [%d] is outside valid range from %d to %d"),
6416 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6417 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6418 return -EINVAL;
6419 }
6420
6421 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6422
6423 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6424 (WLAN_HDD_P2P_GO != pAdapter->device_mode)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306425 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006426 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
6427 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
6428 return -EINVAL;
6429 }
6430 hddLog(LOG2,
6431 FL("set channel to [%d] for device mode %s(%d)"),
6432 channel,
6433 hdd_device_mode_to_string(pAdapter->device_mode),
6434 pAdapter->device_mode);
6435 }
6436
6437 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6438 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6439 ) {
6440 hdd_wext_state_t *pWextState =
6441 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6442 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
6443 hdd_station_ctx_t *pHddStaCtx =
6444 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6445
6446 if (eConnectionState_IbssConnected ==
6447 pHddStaCtx->conn_info.connState) {
6448 /* Link is up then return cant set channel */
6449 hddLog(LOGE,
6450 FL("IBSS Associated, can't set the channel"));
6451 return -EINVAL;
6452 }
6453
6454 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6455 pHddStaCtx->conn_info.operationChannel = channel;
6456 pRoamProfile->ChannelInfo.ChannelList =
6457 &pHddStaCtx->conn_info.operationChannel;
6458 } else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6459 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
6460 ) {
6461 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig);
6462 if (WLAN_HDD_P2P_GO == pAdapter->device_mode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306463 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006464 wlan_hdd_validate_operation_channel(pAdapter,
6465 channel)) {
6466 hddLog(LOGE,
6467 FL("Invalid Channel [%d]"), channel);
6468 return -EINVAL;
6469 }
6470 sap_config->channel = channel;
6471 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6472 } else {
6473 /* set channel to what hostapd configured */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306474 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006475 wlan_hdd_validate_operation_channel(pAdapter,
6476 channel)) {
6477 hddLog(LOGE,
6478 FL("Invalid Channel [%d]"), channel);
6479 return -EINVAL;
6480 }
6481
6482 sap_config->channel = channel;
6483 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6484
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306485 qdf_mem_zero(&smeConfig, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006486 sme_get_config_param(pHddCtx->hHal, &smeConfig);
6487 switch (channel_type) {
6488 case NL80211_CHAN_HT20:
6489 case NL80211_CHAN_NO_HT:
6490 smeConfig.csrConfig.obssEnabled = false;
6491 if (channel <= 14)
6492 smeConfig.csrConfig.
6493 channelBondingMode24GHz =
6494 eCSR_INI_SINGLE_CHANNEL_CENTERED;
6495 else
6496 smeConfig.csrConfig.
6497 channelBondingMode5GHz =
6498 eCSR_INI_SINGLE_CHANNEL_CENTERED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006499 sap_config->sec_ch = 0;
6500 break;
6501
6502 case NL80211_CHAN_HT40MINUS:
6503 if (channel <= 14)
6504 smeConfig.csrConfig.
6505 channelBondingMode24GHz =
6506 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6507 else
6508 smeConfig.csrConfig.
6509 channelBondingMode5GHz =
6510 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6511 sap_config->sec_ch = sap_config->channel - 4;
6512 break;
6513 case NL80211_CHAN_HT40PLUS:
6514 if (channel <= 14)
6515 smeConfig.csrConfig.
6516 channelBondingMode24GHz =
6517 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6518 else
6519 smeConfig.csrConfig.
6520 channelBondingMode5GHz =
6521 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6522 sap_config->sec_ch = sap_config->channel + 4;
6523 break;
6524 default:
6525 hddLog(LOGE,
6526 FL("Error!!! Invalid HT20/40 mode !"));
6527 return -EINVAL;
6528 }
6529 smeConfig.csrConfig.obssEnabled = wlan_hdd_get_sap_obss(
6530 pAdapter);
6531 sme_update_config(pHddCtx->hHal, &smeConfig);
6532 }
6533 } else {
6534 hddLog(LOGE,
6535 FL("Invalid device mode failed to set valid channel"));
6536 return -EINVAL;
6537 }
6538 EXIT();
6539 return status;
6540}
6541
6542/**
6543 * wlan_hdd_check_11gmode() - check for 11g mode
6544 * @pIe: Pointer to IE
6545 * @require_ht: Pointer to require ht
6546 * @require_vht: Pointer to require vht
6547 * @pCheckRatesfor11g: Pointer to check rates for 11g mode
6548 * @pSapHw_mode: SAP HW mode
6549 *
6550 * Check for 11g rate and set proper 11g only mode
6551 *
6552 * Return: none
6553 */
6554static void wlan_hdd_check_11gmode(u8 *pIe, u8 *require_ht, u8 *require_vht,
6555 u8 *pCheckRatesfor11g,
6556 eCsrPhyMode *pSapHw_mode)
6557{
6558 u8 i, num_rates = pIe[0];
6559
6560 pIe += 1;
6561 for (i = 0; i < num_rates; i++) {
6562 if (*pCheckRatesfor11g
6563 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
6564 /* If rate set have 11g rate than change the mode
6565 * to 11G
6566 */
6567 *pSapHw_mode = eCSR_DOT11_MODE_11g;
6568 if (pIe[i] & BASIC_RATE_MASK) {
6569 /* If we have 11g rate as basic rate, it
6570 * means mode is 11g only mode.
6571 */
6572 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
6573 *pCheckRatesfor11g = false;
6574 }
6575 } else {
6576 if ((BASIC_RATE_MASK |
6577 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6578 *require_ht = true;
6579 else if ((BASIC_RATE_MASK |
6580 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
6581 *require_vht = true;
6582 }
6583 }
6584 return;
6585}
6586
6587/**
6588 * wlan_hdd_add_ie() - add ie
6589 * @pHostapdAdapter: Pointer to hostapd adapter
6590 * @genie: Pointer to ie to be added
6591 * @total_ielen: Pointer to store total ie length
6592 * @oui: Pointer to oui
6593 * @oui_size: Size of oui
6594 *
6595 * Return: 0 for success non-zero for failure
6596 */
6597static int wlan_hdd_add_ie(hdd_adapter_t *pHostapdAdapter, uint8_t *genie,
6598 uint8_t *total_ielen, uint8_t *oui,
6599 uint8_t oui_size)
6600{
6601 uint16_t ielen = 0;
6602 uint8_t *pIe = NULL;
6603 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6604
6605 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6606 pBeacon->tail, pBeacon->tail_len);
6607
6608 if (pIe) {
6609 ielen = pIe[1] + 2;
6610 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306611 qdf_mem_copy(&genie[*total_ielen], pIe, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006612 } else {
6613 hddLog(LOGE,
6614 "**Ie Length is too big***");
6615 return -EINVAL;
6616 }
6617 *total_ielen += ielen;
6618 }
6619 return 0;
6620}
6621
6622/**
6623 * wlan_hdd_add_hostapd_conf_vsie() - configure vsie in sap mode
6624 * @pHostapdAdapter: Pointer to hostapd adapter
6625 * @genie: Pointer to vsie
6626 * @total_ielen: Pointer to store total ie length
6627 *
6628 * Return: none
6629 */
6630static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t *pHostapdAdapter,
6631 uint8_t *genie,
6632 uint8_t *total_ielen)
6633{
6634 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6635 int left = pBeacon->tail_len;
6636 uint8_t *ptr = pBeacon->tail;
6637 uint8_t elem_id, elem_len;
6638 uint16_t ielen = 0;
6639
6640 if (NULL == ptr || 0 == left)
6641 return;
6642
6643 while (left >= 2) {
6644 elem_id = ptr[0];
6645 elem_len = ptr[1];
6646 left -= 2;
6647 if (elem_len > left) {
6648 hddLog(LOGE,
6649 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6650 elem_id, elem_len, left);
6651 return;
6652 }
6653 if (IE_EID_VENDOR == elem_id) {
6654 /* skipping the VSIE's which we don't want to include or
6655 * it will be included by existing code
6656 */
6657 if ((memcmp(&ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) !=
6658 0) &&
6659#ifdef WLAN_FEATURE_WFD
6660 (memcmp(&ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) !=
6661 0) &&
6662#endif
6663 (memcmp
6664 (&ptr[2], WHITELIST_OUI_TYPE,
6665 WPA_OUI_TYPE_SIZE) != 0)
6666 &&
6667 (memcmp
6668 (&ptr[2], BLACKLIST_OUI_TYPE,
6669 WPA_OUI_TYPE_SIZE) != 0)
6670 &&
6671 (memcmp
6672 (&ptr[2], "\x00\x50\xf2\x02",
6673 WPA_OUI_TYPE_SIZE) != 0)
6674 && (memcmp(&ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE)
6675 != 0)
6676 && (memcmp(&ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)
6677 != 0)) {
6678 ielen = ptr[1] + 2;
6679 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306680 qdf_mem_copy(&genie[*total_ielen], ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006681 ielen);
6682 *total_ielen += ielen;
6683 } else {
6684 hddLog(LOGE,
6685 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6686 elem_id, elem_len, *total_ielen);
6687 }
6688 }
6689 }
6690
6691 left -= elem_len;
6692 ptr += (elem_len + 2);
6693 }
6694 return;
6695}
6696
6697/**
6698 * wlan_hdd_add_extra_ie() - add extra ies in beacon
6699 * @pHostapdAdapter: Pointer to hostapd adapter
6700 * @genie: Pointer to extra ie
6701 * @total_ielen: Pointer to store total ie length
6702 * @temp_ie_id: ID of extra ie
6703 *
6704 * Return: none
6705 */
6706static void wlan_hdd_add_extra_ie(hdd_adapter_t *pHostapdAdapter,
6707 uint8_t *genie, uint8_t *total_ielen,
6708 uint8_t temp_ie_id)
6709{
6710 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6711 int left = pBeacon->tail_len;
6712 uint8_t *ptr = pBeacon->tail;
6713 uint8_t elem_id, elem_len;
6714 uint16_t ielen = 0;
6715
6716 if (NULL == ptr || 0 == left)
6717 return;
6718
6719 while (left >= 2) {
6720 elem_id = ptr[0];
6721 elem_len = ptr[1];
6722 left -= 2;
6723 if (elem_len > left) {
6724 hddLog(LOGE,
6725 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6726 elem_id, elem_len, left);
6727 return;
6728 }
6729
6730 if (temp_ie_id == elem_id) {
6731 ielen = ptr[1] + 2;
6732 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306733 qdf_mem_copy(&genie[*total_ielen], ptr, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006734 *total_ielen += ielen;
6735 } else {
6736 hddLog(LOGE,
6737 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6738 elem_id, elem_len, *total_ielen);
6739 }
6740 }
6741
6742 left -= elem_len;
6743 ptr += (elem_len + 2);
6744 }
6745 return;
6746}
6747
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006748/**
6749 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
6750 * @pAdapter: Pointer to hostapd adapter
6751 * @ppBeacon: Pointer to pointer to beacon data
6752 * @params: Pointer to beacon parameters
6753 * @dtim_period: DTIM period
6754 *
6755 * Return: 0 for success non-zero for failure
6756 */
6757int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
6758 beacon_data_t **ppBeacon,
6759 struct cfg80211_beacon_data *params,
6760 int dtim_period)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006761{
6762 int size;
6763 beacon_data_t *beacon = NULL;
6764 beacon_data_t *old = NULL;
6765 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
6766 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
6767
6768 ENTER();
6769 if (params->head && !params->head_len) {
6770 hddLog(LOGE, FL("head_len is NULL"));
6771 return -EINVAL;
6772 }
6773
6774 old = pAdapter->sessionCtx.ap.beacon;
6775
6776 if (!params->head && !old) {
6777 hddLog(LOGE, FL("session(%d) old and new heads points to NULL"),
6778 pAdapter->sessionId);
6779 return -EINVAL;
6780 }
6781
6782 if (params->head) {
6783 head_len = params->head_len;
6784 head = params->head;
6785 } else {
6786 head_len = old->head_len;
6787 head = old->head;
6788 }
6789
6790 if (params->tail || !old) {
6791 tail_len = params->tail_len;
6792 tail = params->tail;
6793 } else {
6794 tail_len = old->tail_len;
6795 tail = old->tail;
6796 }
6797
6798 if (params->proberesp_ies || !old) {
6799 proberesp_ies_len = params->proberesp_ies_len;
6800 proberesp_ies = params->proberesp_ies;
6801 } else {
6802 proberesp_ies_len = old->proberesp_ies_len;
6803 proberesp_ies = old->proberesp_ies;
6804 }
6805
6806 if (params->assocresp_ies || !old) {
6807 assocresp_ies_len = params->assocresp_ies_len;
6808 assocresp_ies = params->assocresp_ies;
6809 } else {
6810 assocresp_ies_len = old->assocresp_ies_len;
6811 assocresp_ies = old->assocresp_ies;
6812 }
6813
6814 size = sizeof(beacon_data_t) + head_len + tail_len +
6815 proberesp_ies_len + assocresp_ies_len;
6816
6817 beacon = kzalloc(size, GFP_KERNEL);
6818
6819 if (beacon == NULL) {
6820 hddLog(LOGE,
6821 FL("Mem allocation for beacon failed"));
6822 return -ENOMEM;
6823 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006824 if (dtim_period)
6825 beacon->dtim_period = dtim_period;
6826 else if (old)
6827 beacon->dtim_period = old->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006828 /* -----------------------------------------------
6829 * | head | tail | proberesp_ies | assocresp_ies |
6830 * -----------------------------------------------
6831 */
6832 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6833 beacon->tail = beacon->head + head_len;
6834 beacon->proberesp_ies = beacon->tail + tail_len;
6835 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
6836
6837 beacon->head_len = head_len;
6838 beacon->tail_len = tail_len;
6839 beacon->proberesp_ies_len = proberesp_ies_len;
6840 beacon->assocresp_ies_len = assocresp_ies_len;
6841
6842 if (head && head_len)
6843 memcpy(beacon->head, head, head_len);
6844 if (tail && tail_len)
6845 memcpy(beacon->tail, tail, tail_len);
6846 if (proberesp_ies && proberesp_ies_len)
6847 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
6848 if (assocresp_ies && assocresp_ies_len)
6849 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
6850
6851 *ppBeacon = beacon;
6852
6853 kfree(old);
6854
6855 return 0;
6856
6857}
6858
6859/**
6860 * wlan_hdd_cfg80211_update_apies() - update ap mode ies
6861 * @adapter: Pointer to hostapd adapter
6862 *
6863 * Return: 0 for success non-zero for failure
6864 */
6865int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *adapter)
6866{
6867 uint8_t *genie;
6868 uint8_t total_ielen = 0;
6869 int ret = 0;
6870 tsap_Config_t *pConfig;
6871 tSirUpdateIE updateIE;
6872 beacon_data_t *beacon = NULL;
6873
6874 pConfig = &adapter->sessionCtx.ap.sapConfig;
6875 beacon = adapter->sessionCtx.ap.beacon;
6876
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306877 genie = qdf_mem_malloc(MAX_GENIE_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006878
6879 if (genie == NULL)
6880 return -ENOMEM;
6881
6882 if (0 != wlan_hdd_add_ie(adapter, genie,
6883 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) {
6884 hddLog(LOGE, FL("Adding WPS IE failed"));
6885 ret = -EINVAL;
6886 goto done;
6887 }
6888#ifdef WLAN_FEATURE_WFD
6889 if (0 != wlan_hdd_add_ie(adapter, genie,
6890 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) {
6891 hddLog(LOGE, FL("Adding WFD IE failed"));
6892 ret = -EINVAL;
6893 goto done;
6894 }
6895#endif
6896
6897#ifdef FEATURE_WLAN_WAPI
6898 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6899 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6900 WLAN_EID_WAPI);
6901 }
6902#endif
6903
6904 if (adapter->device_mode == WLAN_HDD_SOFTAP ||
6905 adapter->device_mode == WLAN_HDD_P2P_GO)
6906 wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
6907 &total_ielen);
6908
6909 if (wlan_hdd_add_ie(adapter, genie,
6910 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0) {
6911 hddLog(LOGE, FL("Adding P2P IE failed"));
6912 ret = -EINVAL;
6913 goto done;
6914 }
6915
6916#ifdef QCA_HT_2040_COEX
6917 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6918 tSmeConfigParams smeConfig;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306919 qdf_mem_zero(&smeConfig, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006920 sme_get_config_param(WLAN_HDD_GET_HAL_CTX(adapter),
6921 &smeConfig);
6922 if (smeConfig.csrConfig.obssEnabled)
6923 wlan_hdd_add_extra_ie(adapter, genie,
6924 &total_ielen,
6925 WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
6926 }
6927#endif
Anurag Chouhanc5548422016-02-24 18:33:27 +05306928 qdf_copy_macaddr(&updateIE.bssid, &adapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006929 updateIE.smeSessionId = adapter->sessionId;
6930
6931 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6932 updateIE.ieBufferlength = total_ielen;
6933 updateIE.pAdditionIEBuffer = genie;
6934 updateIE.append = false;
6935 updateIE.notify = true;
6936 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6937 &updateIE,
6938 eUPDATE_IE_PROBE_BCN) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306939 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006940 hddLog(LOGE,
6941 FL("Could not pass on Add Ie probe beacon data"));
6942 ret = -EINVAL;
6943 goto done;
6944 }
6945 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
6946 } else {
6947 wlansap_update_sap_config_add_ie(pConfig,
6948 genie,
6949 total_ielen,
6950 eUPDATE_IE_PROBE_BCN);
6951 }
6952
6953 /* Added for Probe Response IE */
6954 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6955 updateIE.ieBufferlength = beacon->proberesp_ies_len;
6956 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->proberesp_ies;
6957 updateIE.append = false;
6958 updateIE.notify = false;
6959 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6960 &updateIE,
6961 eUPDATE_IE_PROBE_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306962 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006963 hddLog(LOGE,
6964 FL("Could not pass on PROBE_RESP add Ie data"));
6965 ret = -EINVAL;
6966 goto done;
6967 }
6968 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
6969 } else {
6970 wlansap_update_sap_config_add_ie(pConfig,
6971 beacon->proberesp_ies,
6972 beacon->proberesp_ies_len,
6973 eUPDATE_IE_PROBE_RESP);
6974 }
6975
6976 /* Assoc resp Add ie Data */
6977 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6978 updateIE.ieBufferlength = beacon->assocresp_ies_len;
6979 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
6980 updateIE.append = false;
6981 updateIE.notify = false;
6982 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6983 &updateIE,
6984 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306985 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006986 hddLog(LOGE,
6987 FL("Could not pass on Add Ie Assoc Response data"));
6988 ret = -EINVAL;
6989 goto done;
6990 }
6991 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
6992 } else {
6993 wlansap_update_sap_config_add_ie(pConfig,
6994 beacon->assocresp_ies,
6995 beacon->assocresp_ies_len,
6996 eUPDATE_IE_ASSOC_RESP);
6997 }
6998
6999done:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307000 qdf_mem_free(genie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007001 return ret;
7002}
7003
7004/**
7005 * wlan_hdd_set_sap_hwmode() - set sap hw mode
7006 * @pHostapdAdapter: Pointer to hostapd adapter
7007 *
7008 * Return: none
7009 */
7010static void wlan_hdd_set_sap_hwmode(hdd_adapter_t *pHostapdAdapter)
7011{
7012 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7013 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7014 struct ieee80211_mgmt *pMgmt_frame =
7015 (struct ieee80211_mgmt *)pBeacon->head;
7016 u8 checkRatesfor11g = true;
7017 u8 require_ht = false, require_vht = false;
7018 u8 *pIe = NULL;
7019
7020 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
7021
7022 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7023 pBeacon->head_len,
7024 WLAN_EID_SUPP_RATES);
7025 if (pIe != NULL) {
7026 pIe += 1;
7027 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
7028 &checkRatesfor11g, &pConfig->SapHw_mode);
7029 }
7030
7031 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7032 WLAN_EID_EXT_SUPP_RATES);
7033 if (pIe != NULL) {
7034 pIe += 1;
7035 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
7036 &checkRatesfor11g, &pConfig->SapHw_mode);
7037 }
7038
7039 if (pConfig->channel > 14)
7040 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
7041
7042 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7043 WLAN_EID_HT_CAPABILITY);
7044
7045 if (pIe) {
7046 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
7047 if (require_ht)
7048 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
7049 }
7050
7051 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7052 WLAN_EID_VHT_CAPABILITY);
7053
7054 if (pIe) {
7055 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
7056 if (require_vht)
7057 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
7058 }
7059}
7060
7061/**
7062 * wlan_hdd_config_acs() - config ACS needed parameters
7063 * @hdd_ctx: HDD context
7064 * @adapter: Adapter pointer
7065 *
7066 * This function get ACS related INI paramters and populated
7067 * sap config and smeConfig for ACS needed configurations.
7068 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307069 * Return: The QDF_STATUS code associated with performing the operation.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007070 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307071QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007072{
7073 tsap_Config_t *sap_config;
7074 struct hdd_config *ini_config;
7075 tHalHandle hal;
7076
7077 hal = WLAN_HDD_GET_HAL_CTX(adapter);
7078 sap_config = &adapter->sessionCtx.ap.sapConfig;
7079 ini_config = hdd_ctx->config;
7080
7081 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
7082
7083#if defined(WLAN_FEATURE_MBSSID) && defined(FEATURE_WLAN_AP_AP_ACS_OPTIMIZE)
7084 hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"),
7085 hdd_ctx->skip_acs_scan_status);
7086 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
7087 hdd_adapter_t *con_sap_adapter;
7088 tsap_Config_t *con_sap_config = NULL;
7089
7090 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
7091
7092 if (con_sap_adapter)
7093 con_sap_config =
7094 &con_sap_adapter->sessionCtx.ap.sapConfig;
7095
7096 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
7097
7098 if (con_sap_config &&
7099 con_sap_config->acs_cfg.acs_mode == true &&
7100 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
7101 con_sap_config->acs_cfg.hw_mode ==
7102 sap_config->acs_cfg.hw_mode) {
7103 uint8_t con_sap_st_ch, con_sap_end_ch;
7104 uint8_t cur_sap_st_ch, cur_sap_end_ch;
7105 uint8_t bandStartChannel, bandEndChannel;
7106
7107 con_sap_st_ch =
7108 con_sap_config->acs_cfg.start_ch;
7109 con_sap_end_ch =
7110 con_sap_config->acs_cfg.end_ch;
7111 cur_sap_st_ch = sap_config->acs_cfg.start_ch;
7112 cur_sap_end_ch = sap_config->acs_cfg.end_ch;
7113
7114 wlansap_extend_to_acs_range(
7115 &cur_sap_st_ch, &cur_sap_end_ch,
7116 &bandStartChannel, &bandEndChannel);
7117
7118 wlansap_extend_to_acs_range(
7119 &con_sap_st_ch, &con_sap_end_ch,
7120 &bandStartChannel, &bandEndChannel);
7121
7122 if (con_sap_st_ch <= cur_sap_st_ch &&
7123 con_sap_end_ch >= cur_sap_end_ch) {
7124 sap_config->acs_cfg.skip_scan_status =
7125 eSAP_SKIP_ACS_SCAN;
7126
7127 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7128 con_sap_end_ch >= cur_sap_end_ch) {
7129 sap_config->acs_cfg.skip_scan_status =
7130 eSAP_DO_PAR_ACS_SCAN;
7131
7132 sap_config->acs_cfg.skip_scan_range1_stch =
7133 cur_sap_st_ch;
7134 sap_config->acs_cfg.skip_scan_range1_endch =
7135 con_sap_st_ch - 1;
7136 sap_config->acs_cfg.skip_scan_range2_stch =
7137 0;
7138 sap_config->acs_cfg.skip_scan_range2_endch =
7139 0;
7140
7141 } else if (con_sap_st_ch <= cur_sap_st_ch &&
7142 con_sap_end_ch <= cur_sap_end_ch) {
7143 sap_config->acs_cfg.skip_scan_status =
7144 eSAP_DO_PAR_ACS_SCAN;
7145
7146 sap_config->acs_cfg.skip_scan_range1_stch =
7147 con_sap_end_ch + 1;
7148 sap_config->acs_cfg.skip_scan_range1_endch =
7149 cur_sap_end_ch;
7150 sap_config->acs_cfg.skip_scan_range2_stch =
7151 0;
7152 sap_config->acs_cfg.skip_scan_range2_endch =
7153 0;
7154
7155 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7156 con_sap_end_ch <= cur_sap_end_ch) {
7157 sap_config->acs_cfg.skip_scan_status =
7158 eSAP_DO_PAR_ACS_SCAN;
7159
7160 sap_config->acs_cfg.skip_scan_range1_stch =
7161 cur_sap_st_ch;
7162 sap_config->acs_cfg.skip_scan_range1_endch =
7163 con_sap_st_ch - 1;
7164 sap_config->acs_cfg.skip_scan_range2_stch =
7165 con_sap_end_ch;
7166 sap_config->acs_cfg.skip_scan_range2_endch =
7167 cur_sap_end_ch + 1;
7168
7169 } else
7170 sap_config->acs_cfg.skip_scan_status =
7171 eSAP_DO_NEW_ACS_SCAN;
7172
7173
7174 hddLog(LOG1, FL(
7175 "SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d"),
7176 sap_config->acs_cfg.skip_scan_status,
7177 sap_config->acs_cfg.skip_scan_range1_stch,
7178 sap_config->acs_cfg.skip_scan_range1_endch,
7179 sap_config->acs_cfg.skip_scan_range2_stch,
7180 sap_config->acs_cfg.skip_scan_range2_endch);
7181 }
7182 }
7183#endif
7184
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307185 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007186}
7187
7188/**
7189 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
7190 * @adapter: pointer to adapter struct
7191 *
7192 * This function overrides SAP / P2P Go configuration based on driver INI
7193 * parameters for 11AC override and ACS. This overrides are done to support
7194 * android legacy configuration method.
7195 *
7196 * NOTE: Non android platform supports concurrency and these overrides shall
7197 * not be used. Also future driver based overrides shall be consolidated in this
7198 * function only. Avoid random overrides in other location based on ini.
7199 *
7200 * Return: 0 for Success or Negative error codes.
7201 */
7202int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
7203{
7204 tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
7205 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
7206 tHalHandle h_hal = WLAN_HDD_GET_HAL_CTX(ap_adapter);
7207
7208 if (ap_adapter->device_mode == WLAN_HDD_SOFTAP &&
7209 hdd_ctx->config->force_sap_acs)
7210 goto setup_acs_overrides;
7211
7212 /* Fixed channel 11AC override:
7213 * 11AC override in qcacld is introduced for following reasons:
7214 * 1. P2P GO also follows start_bss and since p2p GO could not be
7215 * configured to setup VHT channel width in wpa_supplicant
7216 * 2. Android UI does not provide advanced configuration options for SAP
7217 *
7218 * Default override enabled (for android). MDM shall disable this in ini
7219 */
7220 if (hdd_ctx->config->sap_p2p_11ac_override &&
7221 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7222 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7223 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)) {
7224 hddLog(LOG1, FL("** Driver force 11AC override for SAP/Go **"));
7225
7226 /* 11n only shall not be overridden since it may be on purpose*/
7227 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
7228 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7229
7230 if (sap_cfg->channel >= 36)
7231 sap_cfg->ch_width_orig =
7232 hdd_ctx->config->vhtChannelWidth;
7233 else
7234 sap_cfg->ch_width_orig =
7235 hdd_ctx->config->nChannelBondingMode24GHz ?
7236 eHT_CHANNEL_WIDTH_40MHZ :
7237 eHT_CHANNEL_WIDTH_20MHZ;
7238 }
7239 sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
7240 sme_set_ch_params(h_hal, sap_cfg->SapHw_mode, sap_cfg->channel,
7241 sap_cfg->sec_ch, &sap_cfg->ch_params);
7242
7243 return 0;
7244
7245setup_acs_overrides:
7246 hddLog(LOGE, FL("** Driver force ACS override **"));
7247
7248 sap_cfg->channel = AUTO_CHANNEL_SELECT;
7249 sap_cfg->acs_cfg.acs_mode = true;
7250 sap_cfg->acs_cfg.start_ch = hdd_ctx->config->force_sap_acs_st_ch;
7251 sap_cfg->acs_cfg.end_ch = hdd_ctx->config->force_sap_acs_end_ch;
7252
7253 if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.end_ch) {
7254 hddLog(LOGE, FL("Driver force ACS start ch (%d) > end ch (%d)"),
7255 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7256 return -EINVAL;
7257 }
7258
7259 /* Derive ACS HW mode */
7260 sap_cfg->SapHw_mode = hdd_cfg_xlate_to_csr_phy_mode(
7261 hdd_ctx->config->dot11Mode);
7262 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_AUTO)
7263 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7264
7265 if ((sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11b ||
7266 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g ||
7267 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
7268 sap_cfg->acs_cfg.start_ch > 14) {
7269 hddLog(LOGE, FL("Invalid ACS HW Mode %d + CH range <%d - %d>"),
7270 sap_cfg->SapHw_mode, sap_cfg->acs_cfg.start_ch,
7271 sap_cfg->acs_cfg.end_ch);
7272 return -EINVAL;
7273 }
7274 sap_cfg->acs_cfg.hw_mode = sap_cfg->SapHw_mode;
7275
7276 /* Derive ACS BW */
7277 sap_cfg->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
7278 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7279 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) {
7280
7281 sap_cfg->ch_width_orig = hdd_ctx->config->vhtChannelWidth;
7282 /* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
7283 if (sap_cfg->acs_cfg.end_ch <= 14)
7284 sap_cfg->ch_width_orig =
7285 hdd_ctx->config->nChannelBondingMode24GHz ?
7286 eHT_CHANNEL_WIDTH_40MHZ :
7287 eHT_CHANNEL_WIDTH_20MHZ;
7288 }
7289
7290 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7291 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY) {
7292 if (sap_cfg->acs_cfg.end_ch <= 14)
7293 sap_cfg->ch_width_orig =
7294 hdd_ctx->config->nChannelBondingMode24GHz ?
7295 eHT_CHANNEL_WIDTH_40MHZ :
7296 eHT_CHANNEL_WIDTH_20MHZ;
7297 else
7298 sap_cfg->ch_width_orig =
7299 hdd_ctx->config->nChannelBondingMode5GHz ?
7300 eHT_CHANNEL_WIDTH_40MHZ :
7301 eHT_CHANNEL_WIDTH_20MHZ;
7302 }
7303 sap_cfg->acs_cfg.ch_width = sap_cfg->ch_width_orig;
7304
7305 hddLog(LOG1, FL("Force ACS Config: HW_MODE: %d ACS_BW: %d"),
7306 sap_cfg->acs_cfg.hw_mode, sap_cfg->acs_cfg.ch_width);
7307 hddLog(LOG1, FL("Force ACS Config: ST_CH: %d END_CH: %d"),
7308 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7309
7310 return 0;
7311}
7312
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007313/**
7314 * wlan_hdd_cfg80211_start_bss() - start bss
7315 * @pHostapdAdapter: Pointer to hostapd adapter
7316 * @params: Pointer to start bss beacon parameters
7317 * @ssid: Pointer ssid
7318 * @ssid_len: Length of ssid
7319 * @hidden_ssid: Hidden SSID parameter
7320 *
7321 * Return: 0 for success non-zero for failure
7322 */
7323static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7324 struct cfg80211_beacon_data *params,
7325 const u8 *ssid, size_t ssid_len,
7326 enum nl80211_hidden_ssid hidden_ssid)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007327{
7328 tsap_Config_t *pConfig;
7329 beacon_data_t *pBeacon = NULL;
7330 struct ieee80211_mgmt *pMgmt_frame;
7331 uint8_t *pIe = NULL;
7332 uint16_t capab_info;
7333 eCsrAuthType RSNAuthType;
7334 eCsrEncryptionType RSNEncryptType;
7335 eCsrEncryptionType mcRSNEncryptType;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307336 int status = QDF_STATUS_SUCCESS, ret;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307337 int qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007338 tpWLAN_SAPEventCB pSapEventCallback;
7339 hdd_hostapd_state_t *pHostapdState;
7340#ifndef WLAN_FEATURE_MBSSID
7341 v_CONTEXT_t p_cds_context =
7342 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
7343#endif
7344 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
7345 struct qc_mac_acl_entry *acl_entry = NULL;
7346 int32_t i;
7347 struct hdd_config *iniConfig;
7348 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
7349 tSmeConfigParams sme_config;
7350 bool MFPCapable = false;
7351 bool MFPRequired = false;
7352 uint16_t prev_rsn_length = 0;
7353 ENTER();
7354
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007355 if (cds_is_connection_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007356 hdd_err("Can't start BSS: connection is in progress");
7357 return -EINVAL;
7358 }
7359
7360 iniConfig = pHddCtx->config;
7361 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7362
7363 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
7364 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
7365
7366 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7367
7368 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7369
7370 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
7371
7372 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7373
7374 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
7375
7376 /* channel is already set in the set_channel Call back */
7377 /* pConfig->channel = pCommitConfig->channel; */
7378
7379 /* Protection parameter to enable or disable */
7380 pConfig->protEnabled = iniConfig->apProtEnabled;
7381
7382 pConfig->dtim_period = pBeacon->dtim_period;
7383
7384 hddLog(LOG2, FL("****pConfig->dtim_period=%d***"),
7385 pConfig->dtim_period);
7386
7387 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
7388 pIe =
7389 wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail,
7390 pBeacon->tail_len,
7391 WLAN_EID_COUNTRY);
7392 if (pIe) {
7393 pConfig->ieee80211d = 1;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307394 qdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007395 sme_set_reg_info(hHal, pConfig->countryCode);
7396 sme_apply_channel_power_info_to_fw(hHal);
7397 } else {
7398 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7399 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7400 pConfig->ieee80211d = 0;
7401 }
7402
7403 ret = wlan_hdd_sap_cfg_dfs_override(pHostapdAdapter);
7404 if (ret < 0) {
7405 return ret;
7406 } else {
7407 if (ret == 0) {
7408 if (CDS_IS_DFS_CH(pConfig->channel))
7409 pHddCtx->dev_dfs_cac_status =
7410 DFS_CAC_NEVER_DONE;
7411 }
7412 }
7413
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307414 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007415 wlan_hdd_validate_operation_channel(pHostapdAdapter,
7416 pConfig->channel)) {
7417 hddLog(LOGE, FL("Invalid Channel [%d]"),
7418 pConfig->channel);
7419 return -EINVAL;
7420 }
7421
7422 /* reject SAP if DFS channel scan is not allowed */
7423 if (!(pHddCtx->config->enableDFSChnlScan) &&
7424 (CHANNEL_STATE_DFS == cds_get_channel_state(
7425 pConfig->channel))) {
7426 hddLog(LOGE,
7427 FL("not allowed to start SAP on DFS channel"));
7428 return -EOPNOTSUPP;
7429 }
7430 wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC);
7431 wlansap_set_dfs_restrict_japan_w53(hHal,
7432 iniConfig->gDisableDfsJapanW53);
7433 wlansap_set_dfs_preferred_channel_location(hHal,
7434 iniConfig->gSapPreferredChanLocation);
7435#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
7436 wlan_sap_set_channel_avoidance(hHal,
7437 iniConfig->sap_channel_avoidance);
7438#endif
7439 } else if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7440 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7441 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7442 pConfig->ieee80211d = 0;
7443 } else {
7444 pConfig->ieee80211d = 0;
7445 }
7446
7447 capab_info = pMgmt_frame->u.beacon.capab_info;
7448
7449 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
7450 WLAN_CAPABILITY_PRIVACY) ? true : false;
7451
7452 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7453
7454 /*Set wps station to configured */
7455 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7456
7457 if (pIe) {
7458 if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) {
7459 hddLog(LOGE,
7460 FL("**Wps Ie Length is too small***"));
7461 return -EINVAL;
7462 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
7463 0) {
7464 hddLog(LOG1, FL("** WPS IE(len %d) ***"), (pIe[1] + 2));
7465 /* Check 15 bit of WPS IE as it contain information for
7466 * wps state
7467 */
7468 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
7469 pConfig->wps_state =
7470 SAP_WPS_ENABLED_UNCONFIGURED;
7471 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
7472 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7473 }
7474 }
7475 } else {
7476 hdd_info("WPS disabled");
7477 pConfig->wps_state = SAP_WPS_DISABLED;
7478 }
7479 /* Forward WPS PBC probe request frame up */
7480 pConfig->fwdWPSPBCProbeReq = 1;
7481
7482 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7483 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7484 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7485 eCSR_ENCRYPT_TYPE_NONE;
7486
7487 pConfig->RSNWPAReqIELength = 0;
7488 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
7489 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7490 WLAN_EID_RSN);
7491 if (pIe && pIe[1]) {
7492 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7493 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
7494 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7495 pConfig->RSNWPAReqIELength);
7496 else
7497 hddLog(LOGE,
7498 FL("RSNWPA IE MAX Length exceeded; length =%d"),
7499 pConfig->RSNWPAReqIELength);
7500 /* The actual processing may eventually be more extensive than
7501 * this. Right now, just consume any PMKIDs that are sent in
7502 * by the app.
7503 * */
7504 status =
7505 hdd_softap_unpack_ie(cds_get_context
Anurag Chouhan6d760662016-02-20 16:05:43 +05307506 (QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007507 &RSNEncryptType, &mcRSNEncryptType,
7508 &RSNAuthType, &MFPCapable,
7509 &MFPRequired,
7510 pConfig->RSNWPAReqIE[1] + 2,
7511 pConfig->RSNWPAReqIE);
7512
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307513 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007514 /* Now copy over all the security attributes you have
7515 * parsed out. Use the cipher type in the RSN IE
7516 */
7517 pConfig->RSNEncryptType = RSNEncryptType;
7518 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7519 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7520 ucEncryptType = RSNEncryptType;
7521 hddLog(LOG1,
7522 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7523 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7524 }
7525 }
7526
7527 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7528 pBeacon->tail, pBeacon->tail_len);
7529
7530 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
7531 if (pConfig->RSNWPAReqIE[0]) {
7532 /*Mixed mode WPA/WPA2 */
7533 prev_rsn_length = pConfig->RSNWPAReqIELength;
7534 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7535 if (pConfig->RSNWPAReqIELength <
7536 sizeof(pConfig->RSNWPAReqIE))
7537 memcpy(&pConfig->RSNWPAReqIE[0] +
7538 prev_rsn_length, pIe, pIe[1] + 2);
7539 else
7540 hddLog(LOGE,
7541 "RSNWPA IE MAX Length exceeded; length =%d",
7542 pConfig->RSNWPAReqIELength);
7543 } else {
7544 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7545 if (pConfig->RSNWPAReqIELength <
7546 sizeof(pConfig->RSNWPAReqIE))
7547 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7548 pConfig->RSNWPAReqIELength);
7549 else
7550 hddLog(LOGE,
7551 "RSNWPA IE MAX Length exceeded; length =%d",
7552 pConfig->RSNWPAReqIELength);
7553 status = hdd_softap_unpack_ie
Anurag Chouhan6d760662016-02-20 16:05:43 +05307554 (cds_get_context(QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007555 &RSNEncryptType,
7556 &mcRSNEncryptType, &RSNAuthType,
7557 &MFPCapable, &MFPRequired,
7558 pConfig->RSNWPAReqIE[1] + 2,
7559 pConfig->RSNWPAReqIE);
7560
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307561 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007562 /* Now copy over all the security attributes
7563 * you have parsed out. Use the cipher type
7564 * in the RSN IE
7565 */
7566 pConfig->RSNEncryptType = RSNEncryptType;
7567 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7568 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7569 ucEncryptType = RSNEncryptType;
7570 hddLog(LOG1,
7571 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7572 RSNAuthType, RSNEncryptType,
7573 mcRSNEncryptType);
7574 }
7575 }
7576 }
7577
7578 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
7579 hddLog(LOGE,
7580 FL("**RSNWPAReqIELength is too large***"));
7581 return -EINVAL;
7582 }
7583
7584 pConfig->SSIDinfo.ssidHidden = false;
7585
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007586 if (ssid != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307587 qdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007588 pConfig->SSIDinfo.ssid.length = ssid_len;
7589
7590 switch (hidden_ssid) {
7591 case NL80211_HIDDEN_SSID_NOT_IN_USE:
7592 hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
7593 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
7594 break;
7595 case NL80211_HIDDEN_SSID_ZERO_LEN:
7596 hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
7597 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
7598 break;
7599 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
7600 hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
7601 pConfig->SSIDinfo.ssidHidden =
7602 eHIDDEN_SSID_ZERO_CONTENTS;
7603 break;
7604 default:
7605 hddLog(LOGE, "Wrong hidden_ssid param %d", hidden_ssid);
7606 break;
7607 }
7608 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007609
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307610 qdf_mem_copy(pConfig->self_macaddr.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007611 pHostapdAdapter->macAddressCurrent.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05307612 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007613
7614 /* default value */
7615 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7616 pConfig->num_accept_mac = 0;
7617 pConfig->num_deny_mac = 0;
7618#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
7619 /*
7620 * We don't want P2PGO to follow STA's channel
7621 * so lets limit the logic for SAP only.
7622 * Later if we decide to make p2pgo follow STA's
7623 * channel then remove this check.
7624 */
7625 if ((0 == pHddCtx->config->conc_custom_rule1) ||
7626 (pHddCtx->config->conc_custom_rule1 &&
7627 WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode))
7628 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
7629#endif
7630
7631 pIe =
7632 wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE,
7633 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7634 pBeacon->tail_len);
7635
7636 /* pIe for black list is following form:
7637 * type : 1 byte
7638 * length : 1 byte
7639 * OUI : 4 bytes
7640 * acl type : 1 byte
7641 * no of mac addr in black list: 1 byte
7642 * list of mac_acl_entries: variable, 6 bytes per mac
7643 * address + sizeof(int) for vlan id
7644 */
7645 if ((pIe != NULL) && (pIe[1] != 0)) {
7646 pConfig->SapMacaddr_acl = pIe[6];
7647 pConfig->num_deny_mac = pIe[7];
7648 hddLog(LOG1,
7649 FL("acl type = %d no deny mac = %d"), pIe[6], pIe[7]);
7650 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7651 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
7652 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7653 for (i = 0; i < pConfig->num_deny_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307654 qdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007655 sizeof(qcmacaddr));
7656 acl_entry++;
7657 }
7658 }
7659 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE,
7660 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7661 pBeacon->tail_len);
7662
7663 /* pIe for white list is following form:
7664 * type : 1 byte
7665 * length : 1 byte
7666 * OUI : 4 bytes
7667 * acl type : 1 byte
7668 * no of mac addr in white list: 1 byte
7669 * list of mac_acl_entries: variable, 6 bytes per mac
7670 * address + sizeof(int) for vlan id
7671 */
7672 if ((pIe != NULL) && (pIe[1] != 0)) {
7673 pConfig->SapMacaddr_acl = pIe[6];
7674 pConfig->num_accept_mac = pIe[7];
7675 hddLog(LOG1, FL("acl type = %d no accept mac = %d"),
7676 pIe[6], pIe[7]);
7677 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7678 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
7679 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7680 for (i = 0; i < pConfig->num_accept_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307681 qdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007682 sizeof(qcmacaddr));
7683 acl_entry++;
7684 }
7685 }
7686
7687 wlan_hdd_set_sap_hwmode(pHostapdAdapter);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307688 qdf_mem_zero(&sme_config, sizeof(tSmeConfigParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007689 sme_get_config_param(pHddCtx->hHal, &sme_config);
7690 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
7691 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
7692 * may not be good with non QOS 11N AP
7693 * Default: enable QOS for SAP unless WMM IE not present for 11bga
7694 */
7695 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
7696 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
7697 pBeacon->tail, pBeacon->tail_len);
7698 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
7699 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
7700 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
7701 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
7702 sme_update_config(pHddCtx->hHal, &sme_config);
7703
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007704 if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80P80) {
7705 if (pHddCtx->isVHT80Allowed == false)
7706 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7707 else
7708 pConfig->ch_width_orig = CH_WIDTH_80P80MHZ;
7709 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_160) {
7710 if (pHddCtx->isVHT80Allowed == false)
7711 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7712 else
7713 pConfig->ch_width_orig = CH_WIDTH_160MHZ;
7714 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80) {
7715 if (pHddCtx->isVHT80Allowed == false)
7716 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7717 else
7718 pConfig->ch_width_orig = CH_WIDTH_80MHZ;
7719 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40) {
7720 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7721 } else {
7722 pConfig->ch_width_orig = CH_WIDTH_20MHZ;
7723 }
7724
7725 if (wlan_hdd_setup_driver_overrides(pHostapdAdapter))
7726 return -EINVAL;
7727
7728 /* ht_capab is not what the name conveys,this is used for protection
7729 * bitmap */
7730 pConfig->ht_capab = iniConfig->apProtection;
7731
7732 if (0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter)) {
7733 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7734 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7735 return -EINVAL;
7736 }
7737 /* Uapsd Enabled Bit */
7738 pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
7739 /* Enable OBSS protection */
7740 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
7741
7742 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7743 pConfig->sap_dot11mc =
7744 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->sap_dot11mc;
7745 else /* for P2P-Go case */
7746 pConfig->sap_dot11mc = 1;
7747
7748 hddLog(LOG1, FL("11MC Support Enabled : %d\n"),
7749 pConfig->sap_dot11mc);
7750
7751#ifdef WLAN_FEATURE_11W
7752 pConfig->mfpCapable = MFPCapable;
7753 pConfig->mfpRequired = MFPRequired;
7754 hddLog(LOG1, FL("Soft AP MFP capable %d, MFP required %d"),
7755 pConfig->mfpCapable, pConfig->mfpRequired);
7756#endif
7757
7758 hddLog(LOGW, FL("SOftAP macaddress : " MAC_ADDRESS_STR),
7759 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
7760 hddLog(LOGW, FL("ssid =%s, beaconint=%d, channel=%d"),
7761 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7762 (int)pConfig->channel);
7763 hddLog(LOGW, FL("hw_mode=%x, privacy=%d, authType=%d"),
7764 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
7765 hddLog(LOGW, FL("RSN/WPALen=%d, Uapsd = %d"),
7766 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7767 hddLog(LOGW, FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7768 pConfig->protEnabled, pConfig->obssProtEnabled);
7769
7770 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
7771 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7772 /* Bss already started. just return. */
7773 /* TODO Probably it should update some beacon params. */
7774 hddLog(LOGE, "Bss Already started...Ignore the request");
7775 EXIT();
7776 return 0;
7777 }
7778
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007779 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007780 cds_convert_device_mode_to_hdd_type(
7781 pHostapdAdapter->device_mode),
7782 pConfig->channel, HW_MODE_20_MHZ)) {
7783 hddLog(LOGW,
7784 FL("This concurrency combination is not allowed"));
7785 return -EINVAL;
7786 }
7787
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007788 if (!cds_set_connection_in_progress(true)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007789 hdd_err("Can't start BSS: set connnection in progress failed");
7790 return -EINVAL;
7791 }
7792
7793 pConfig->persona = pHostapdAdapter->device_mode;
7794
7795 pSapEventCallback = hdd_hostapd_sap_event_cb;
7796
7797 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = true;
7798
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307799 qdf_event_reset(&pHostapdState->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007800 status = wlansap_start_bss(
7801#ifdef WLAN_FEATURE_MBSSID
7802 WLAN_HDD_GET_SAP_CTX_PTR
7803 (pHostapdAdapter),
7804#else
7805 p_cds_context,
7806#endif
7807 pSapEventCallback, pConfig,
7808 pHostapdAdapter->dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307809 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007810 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007811 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007812 hddLog(LOGE, FL("SAP Start Bss fail"));
7813 return -EINVAL;
7814 }
7815
7816 hddLog(LOG1,
7817 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7818
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307819 qdf_status = qdf_wait_single_event(&pHostapdState->qdf_event, 10000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007820
7821 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7822
Anurag Chouhance0dc992016-02-16 18:18:03 +05307823 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007824 hddLog(LOGE,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307825 FL("ERROR: HDD qdf wait for single_event failed!!"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007826 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007827 sme_get_command_q_status(hHal);
7828#ifdef WLAN_FEATURE_MBSSID
7829 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
7830#else
7831 wlansap_stop_bss(p_cds_context);
7832#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307833 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007834 return -EINVAL;
7835 }
7836 /* Succesfully started Bss update the state bit. */
7837 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
7838 /* Initialize WMM configuation */
7839 hdd_wmm_init(pHostapdAdapter);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007840 cds_incr_active_session(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007841 pHostapdAdapter->sessionId);
7842#ifdef DHCP_SERVER_OFFLOAD
7843 if (iniConfig->enableDHCPServerOffload)
7844 wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
7845#endif /* DHCP_SERVER_OFFLOAD */
7846
7847#ifdef WLAN_FEATURE_P2P_DEBUG
7848 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7849 if (global_p2p_connection_status == P2P_GO_NEG_COMPLETED) {
7850 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7851 hddLog(LOGE,
7852 FL("[P2P State] From Go nego completed to Non-autonomous Group started"));
7853 } else if (global_p2p_connection_status == P2P_NOT_ACTIVE) {
7854 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7855 hddLog(LOGE,
7856 FL("[P2P State] From Inactive to Autonomous Group started"));
7857 }
7858 }
7859#endif
7860
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007861 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007862 pHostapdState->bCommit = true;
7863 EXIT();
7864
7865 return 0;
7866}
7867
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007868/**
7869 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
7870 * @wiphy: Pointer to wiphy structure
7871 * @dev: Pointer to net_device structure
7872 *
7873 * Return: 0 for success non-zero for failure
7874 */
7875static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7876 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007877{
7878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7879 hdd_context_t *pHddCtx = NULL;
7880 hdd_scaninfo_t *pScanInfo = NULL;
7881 hdd_adapter_t *staAdapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307882 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307883 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007884 tSirUpdateIE updateIE;
7885 beacon_data_t *old;
7886 int ret;
7887 unsigned long rc;
7888 hdd_adapter_list_node_t *pAdapterNode = NULL;
7889 hdd_adapter_list_node_t *pNext = NULL;
7890
7891 ENTER();
7892
Anurag Chouhan6d760662016-02-20 16:05:43 +05307893 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007894 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7895 return -EINVAL;
7896 }
7897
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307898 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007899 TRACE_CODE_HDD_CFG80211_STOP_AP,
7900 pAdapter->sessionId, pAdapter->device_mode));
7901
7902 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7903 ret = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307904 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007905 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007906
7907 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
7908 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
7909 return -EOPNOTSUPP;
7910 }
7911
7912 hddLog(LOG1, FL("Device_mode %s(%d)"),
7913 hdd_device_mode_to_string(pAdapter->device_mode),
7914 pAdapter->device_mode);
7915
7916 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307917 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007918 staAdapter = pAdapterNode->pAdapter;
7919
7920 if (WLAN_HDD_INFRA_STATION == staAdapter->device_mode ||
7921 (WLAN_HDD_P2P_CLIENT == staAdapter->device_mode) ||
7922 (WLAN_HDD_P2P_GO == staAdapter->device_mode)) {
7923 pScanInfo = &staAdapter->scan_info;
7924
7925 if (pScanInfo && pScanInfo->mScanPending) {
7926 hddLog(LOG1, FL("Aborting pending scan for device mode:%d"),
7927 staAdapter->device_mode);
7928 INIT_COMPLETION(pScanInfo->abortscan_event_var);
7929 hdd_abort_mac_scan(staAdapter->pHddCtx,
7930 staAdapter->sessionId,
7931 eCSR_SCAN_ABORT_DEFAULT);
7932 rc = wait_for_completion_timeout(
7933 &pScanInfo->abortscan_event_var,
7934 msecs_to_jiffies(
7935 WLAN_WAIT_TIME_ABORTSCAN));
7936 if (!rc) {
7937 hddLog(LOGE,
7938 FL("Timeout occurred while waiting for abortscan"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307939 QDF_ASSERT(pScanInfo->mScanPending);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007940 }
7941 }
7942 }
7943
7944 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
7945 pAdapterNode = pNext;
7946 }
7947 /*
7948 * When ever stop ap adapter gets called, we need to check
7949 * whether any restart AP work is pending. If any restart is pending
7950 * then lets finish it and go ahead from there.
7951 */
7952 if (pHddCtx->config->conc_custom_rule1 &&
7953 (WLAN_HDD_SOFTAP == pAdapter->device_mode)) {
7954 cds_flush_work(&pHddCtx->sap_start_work);
7955 hddLog(LOGW, FL("Canceled the pending restart work"));
7956 spin_lock(&pHddCtx->sap_update_info_lock);
7957 pHddCtx->is_sap_restart_required = false;
7958 spin_unlock(&pHddCtx->sap_update_info_lock);
7959 }
7960 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
7961 if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307962 qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
7963 qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007964 sizeof(struct sap_acs_cfg));
7965 hdd_hostapd_stop(dev);
7966
7967 old = pAdapter->sessionCtx.ap.beacon;
7968 if (!old) {
7969 hddLog(LOGE,
7970 FL("Session(%d) beacon data points to NULL"),
7971 pAdapter->sessionId);
7972 return -EINVAL;
7973 }
7974
7975 hdd_cleanup_actionframe(pHddCtx, pAdapter);
7976
7977 mutex_lock(&pHddCtx->sap_lock);
7978 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) {
7979 hdd_hostapd_state_t *pHostapdState =
7980 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7981
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307982 qdf_event_reset(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007983#ifdef WLAN_FEATURE_MBSSID
7984 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter));
7985#else
7986 status = wlansap_stop_bss(pHddCtx->pcds_context);
7987#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307988 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05307989 qdf_status =
7990 qdf_wait_single_event(&pHostapdState->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307991 qdf_stop_bss_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007992 10000);
7993
Anurag Chouhance0dc992016-02-16 18:18:03 +05307994 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007995 hddLog(LOGE,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307996 FL("HDD qdf wait for single_event failed!!"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307997 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007998 }
7999 }
8000 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
8001 /*BSS stopped, clear the active sessions for this device mode*/
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08008002 cds_decr_session_set_pcl(pAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008003 pAdapter->sessionId);
8004 pAdapter->sessionCtx.ap.beacon = NULL;
8005 kfree(old);
8006 }
8007 mutex_unlock(&pHddCtx->sap_lock);
8008
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308009 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008010 hddLog(LOGE, FL("Stopping the BSS"));
8011 return -EINVAL;
8012 }
8013
Anurag Chouhanc5548422016-02-24 18:33:27 +05308014 qdf_copy_macaddr(&updateIE.bssid, &pAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008015 updateIE.smeSessionId = pAdapter->sessionId;
8016 updateIE.ieBufferlength = 0;
8017 updateIE.pAdditionIEBuffer = NULL;
8018 updateIE.append = true;
8019 updateIE.notify = true;
8020 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
8021 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308022 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008023 hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
8024 }
8025
8026 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
8027 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308028 eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008029 hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE"));
8030 }
8031 /* Reset WNI_CFG_PROBE_RSP Flags */
8032 wlan_hdd_reset_prob_rspies(pAdapter);
8033
8034#ifdef WLAN_FEATURE_P2P_DEBUG
8035 if ((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8036 (global_p2p_connection_status == P2P_GO_COMPLETED_STATE)) {
8037 hddLog(LOGE,
8038 "[P2P State] From GO completed to Inactive state GO got removed");
8039 global_p2p_connection_status = P2P_NOT_ACTIVE;
8040 }
8041#endif
8042 EXIT();
8043 return ret;
8044}
8045
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008046/**
8047 * wlan_hdd_get_channel_bw() - get channel bandwidth
8048 * @width: input channel width in nl80211_chan_width value
8049 *
8050 * Return: channel width value defined by driver
8051 */
8052static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
8053 enum nl80211_chan_width width)
8054{
8055 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
8056
8057 switch (width) {
8058 case NL80211_CHAN_WIDTH_20_NOHT:
8059 case NL80211_CHAN_WIDTH_20:
8060 ch_bw = HW_MODE_20_MHZ;
8061 break;
8062 case NL80211_CHAN_WIDTH_40:
8063 ch_bw = HW_MODE_40_MHZ;
8064 break;
8065 case NL80211_CHAN_WIDTH_80:
8066 ch_bw = HW_MODE_80_MHZ;
8067 break;
8068 case NL80211_CHAN_WIDTH_80P80:
8069 ch_bw = HW_MODE_80_PLUS_80_MHZ;
8070 break;
8071 case NL80211_CHAN_WIDTH_160:
8072 ch_bw = HW_MODE_160_MHZ;
8073 break;
8074 default:
8075 hdd_err("Invalid width: %d, using default 20MHz", width);
8076 break;
8077 }
8078
8079 return ch_bw;
8080}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008081
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008082/**
8083 * wlan_hdd_cfg80211_stop_ap() - stop sap
8084 * @wiphy: Pointer to wiphy
8085 * @dev: Pointer to netdev
8086 *
8087 * Return: zero for success non-zero for failure
8088 */
8089int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8090 struct net_device *dev)
8091{
8092 int ret;
8093
8094 cds_ssr_protect(__func__);
8095 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8096 cds_ssr_unprotect(__func__);
8097
8098 return ret;
8099}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008100
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008101/**
8102 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
8103 * @wiphy: Pointer to wiphy structure
8104 * @dev: Pointer to net_device structure
8105 * @params: Pointer to AP settings parameters
8106 *
8107 * Return: 0 for success non-zero for failure
8108 */
8109static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8110 struct net_device *dev,
8111 struct cfg80211_ap_settings *params)
8112{
8113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8114 hdd_context_t *pHddCtx;
Chandrasekaran, Manishekar96c90962015-11-20 16:47:45 +05308115 enum hw_mode_bandwidth channel_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008116 int status;
8117 uint8_t channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008118
8119 ENTER();
8120
Anurag Chouhan6d760662016-02-20 16:05:43 +05308121 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008122 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8123 return -EINVAL;
8124 }
8125
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308126 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008127 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8128 params->beacon_interval));
8129 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
8130 hddLog(LOGE, FL("HDD adapter magic is invalid"));
8131 return -ENODEV;
8132 }
8133
8134 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8135 status = wlan_hdd_validate_context(pHddCtx);
8136
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308137 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008138 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008139
8140 hddLog(LOG2, FL("pAdapter = %p, Device mode %s(%d)"), pAdapter,
8141 hdd_device_mode_to_string(pAdapter->device_mode),
8142 pAdapter->device_mode);
8143
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008144 channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
8145 channel = ieee80211_frequency_to_channel(
8146 params->chandef.chan->center_freq);
Amar Singhal01098f72015-10-08 11:55:32 -07008147
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008148 /* check if concurrency is allowed */
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008149 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008150 cds_convert_device_mode_to_hdd_type(
8151 pAdapter->device_mode),
8152 channel,
8153 channel_width)) {
8154 hdd_err("Connection failed due to concurrency check failure");
8155 return -EINVAL;
8156 }
8157 if (pHddCtx->config->policy_manager_enabled) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308158 status = qdf_reset_connection_update();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308159 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008160 hdd_err("ERR: clear event failed");
8161
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308162 status = cds_current_connections_update(pAdapter->sessionId,
8163 channel,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05308164 SIR_UPDATE_REASON_START_AP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308165 if (QDF_STATUS_E_FAILURE == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008166 hdd_err("ERROR: connections update failed!!");
8167 return -EINVAL;
8168 }
8169
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308170 if (QDF_STATUS_SUCCESS == status) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308171 status = qdf_wait_for_connection_update();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308172 if (!QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308173 hdd_err("ERROR: qdf wait for event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008174 return -EINVAL;
8175 }
8176 }
8177 }
8178
8179 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8180 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
8181 ) {
8182 beacon_data_t *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008183 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008184
8185 old = pAdapter->sessionCtx.ap.beacon;
8186
8187 if (old)
8188 return -EALREADY;
8189
8190 status =
8191 wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new,
8192 &params->beacon,
8193 params->dtim_period);
8194
8195 if (status != 0) {
8196 hddLog(LOGE, FL("Error!!! Allocating the new beacon"));
8197 return -EINVAL;
8198 }
8199 pAdapter->sessionCtx.ap.beacon = new;
8200
8201 if (params->chandef.width < NL80211_CHAN_WIDTH_80)
8202 channel_type = cfg80211_get_chandef_type(
8203 &(params->chandef));
8204 else
8205 channel_type = NL80211_CHAN_HT40PLUS;
8206
8207
8208 wlan_hdd_set_channel(wiphy, dev,
8209 &params->chandef,
8210 channel_type);
8211
8212 /* set authentication type */
8213 switch (params->auth_type) {
8214 case NL80211_AUTHTYPE_OPEN_SYSTEM:
8215 pAdapter->sessionCtx.ap.sapConfig.authType =
8216 eSAP_OPEN_SYSTEM;
8217 break;
8218 case NL80211_AUTHTYPE_SHARED_KEY:
8219 pAdapter->sessionCtx.ap.sapConfig.authType =
8220 eSAP_SHARED_KEY;
8221 break;
8222 default:
8223 pAdapter->sessionCtx.ap.sapConfig.authType =
8224 eSAP_AUTO_SWITCH;
8225 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008226 pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
8227 params->chandef.width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008228 status =
8229 wlan_hdd_cfg80211_start_bss(pAdapter,
8230 &params->beacon,
8231 params->ssid, params->ssid_len,
8232 params->hidden_ssid);
8233 }
8234
8235 EXIT();
8236 return status;
8237}
8238
8239/**
8240 * wlan_hdd_cfg80211_start_ap() - start sap
8241 * @wiphy: Pointer to wiphy
8242 * @dev: Pointer to netdev
8243 * @params: Pointer to start ap configuration parameters
8244 *
8245 * Return: zero for success non-zero for failure
8246 */
8247int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8248 struct net_device *dev,
8249 struct cfg80211_ap_settings *params)
8250{
8251 int ret;
8252
8253 cds_ssr_protect(__func__);
8254 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8255 cds_ssr_unprotect(__func__);
8256
8257 return ret;
8258}
8259
8260/**
8261 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
8262 * @wiphy: Pointer to wiphy structure
8263 * @dev: Pointer to net_device structure
8264 * @params: Pointer to change beacon parameters
8265 *
8266 * Return: 0 for success non-zero for failure
8267 */
8268static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8269 struct net_device *dev,
8270 struct cfg80211_beacon_data *params)
8271{
8272 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8273 hdd_context_t *pHddCtx;
8274 beacon_data_t *old, *new;
8275 int status;
8276
8277 ENTER();
8278
Anurag Chouhan6d760662016-02-20 16:05:43 +05308279 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008280 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8281 return -EINVAL;
8282 }
8283
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308284 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008285 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8286 pAdapter->sessionId, pAdapter->device_mode));
8287 hddLog(LOG1, FL("Device_mode %s(%d)"),
8288 hdd_device_mode_to_string(pAdapter->device_mode),
8289 pAdapter->device_mode);
8290
8291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8292 status = wlan_hdd_validate_context(pHddCtx);
8293
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308294 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008295 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008296
8297 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
8298 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
8299 return -EOPNOTSUPP;
8300 }
8301
8302 old = pAdapter->sessionCtx.ap.beacon;
8303
8304 if (!old) {
8305 hddLog(LOGE, FL("session(%d) beacon data points to NULL"),
8306 pAdapter->sessionId);
8307 return -EINVAL;
8308 }
8309
8310 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8311
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308312 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008313 hddLog(LOGE, FL("new beacon alloc failed"));
8314 return -EINVAL;
8315 }
8316
8317 pAdapter->sessionCtx.ap.beacon = new;
8318 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
8319
8320 EXIT();
8321 return status;
8322}
8323
8324/**
8325 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
8326 * @wiphy: Pointer to wiphy
8327 * @dev: Pointer to netdev
8328 * @params: Pointer to change beacon parameters
8329 *
8330 * Return: zero for success non-zero for failure
8331 */
8332int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8333 struct net_device *dev,
8334 struct cfg80211_beacon_data *params)
8335{
8336 int ret;
8337
8338 cds_ssr_protect(__func__);
8339 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8340 cds_ssr_unprotect(__func__);
8341
8342 return ret;
8343}