blob: 682a53a346010b25c7230efeec744aecacccb599 [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;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001408 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001409 cfg80211_new_sta(dev,
1410 (const u8 *)&pSapEvent->sapevt.
1411 sapStationAssocReassocCompleteEvent.
1412 staMac.bytes[0], &staInfo,
1413 GFP_KERNEL);
1414 } else {
1415 hddLog(LOGE,
1416 FL("Assoc Ie length is too long"));
1417 }
1418 }
1419
1420 pScanInfo = &pHostapdAdapter->scan_info;
1421 /* Lets do abort scan to ensure smooth authentication for client */
1422 if ((pScanInfo != NULL) && pScanInfo->mScanPending) {
1423 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
1424 eCSR_SCAN_ABORT_DEFAULT);
1425 }
1426 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1427 /* send peer status indication to oem app */
1428 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1429 sapStationAssocReassocCompleteEvent.
1430 staMac, ePeerConnected,
1431 pSapEvent->sapevt.
1432 sapStationAssocReassocCompleteEvent.
1433 timingMeasCap,
1434 pHostapdAdapter->
1435 sessionId,
1436 &pSapEvent->sapevt.
1437 sapStationAssocReassocCompleteEvent.
1438 chan_info);
1439 }
1440 hdd_wlan_green_ap_add_sta(pHddCtx);
1441 break;
1442
1443 case eSAP_STA_DISASSOC_EVENT:
1444 memcpy(wrqu.addr.sa_data,
1445 &pSapEvent->sapevt.sapStationDisassocCompleteEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301446 staMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447 hddLog(LOG1, " disassociated " MAC_ADDRESS_STR,
1448 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1449
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301450 qdf_status = qdf_event_set(&pHostapdState->qdf_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301451 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452 hddLog(LOGE, "ERR: Station Deauth event Set failed");
1453
1454 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
1455 eSAP_USR_INITATED_DISASSOC)
1456 hddLog(LOG1, " User initiated disassociation");
1457 else
1458 hddLog(LOG1, " MAC initiated disassociation");
1459 we_event = IWEVEXPIRED;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301460 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461 hdd_softap_get_sta_id(pHostapdAdapter,
1462 &pSapEvent->sapevt.
1463 sapStationDisassocCompleteEvent.staMac,
1464 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301465 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001466 hddLog(LOGE, FL("ERROR: HDD Failed to find sta id!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301467 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001468 }
1469#ifdef IPA_OFFLOAD
1470 if (hdd_ipa_is_enabled(pHddCtx)) {
1471 status = hdd_ipa_wlan_evt(pHostapdAdapter, staId,
1472 WLAN_CLIENT_DISCONNECT,
1473 pSapEvent->sapevt.
1474 sapStationDisassocCompleteEvent.
1475 staMac.bytes);
1476
1477 if (status) {
1478 hddLog(LOGE,
1479 ("ERROR: WLAN_CLIENT_DISCONNECT event failed!!"));
1480 goto stopbss;
1481 }
1482 }
1483#endif
1484#ifdef QCA_PKT_PROTO_TRACE
1485 /* Peer dis-associated, update into trace buffer */
1486 if (pHddCtx->config->gEnableDebugLog) {
1487 cds_pkt_trace_buf_update("HA:DISASC");
1488 }
1489#endif /* QCA_PKT_PROTO_TRACE */
1490 hdd_softap_deregister_sta(pHostapdAdapter, staId);
1491
1492 pHddApCtx->bApActive = false;
1493 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1494 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
1495 if (pHostapdAdapter->aStaInfo[i].isUsed
1496 && i !=
1497 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
1498 uBCStaId) {
1499 pHddApCtx->bApActive = true;
1500 break;
1501 }
1502 }
1503 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1504
1505 /* Start AP inactivity timer if no stations associated with it */
1506 if ((0 !=
1507 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1508 nAPAutoShutOff)) {
1509 if (pHddApCtx->bApActive == false) {
1510 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301511 QDF_TIMER_STATE_STOPPED) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301512 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301513 qdf_mc_timer_start(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514 hdd_ap_inactivity_timer,
1515 (WLAN_HDD_GET_CTX
1516 (pHostapdAdapter))->
1517 config->
1518 nAPAutoShutOff *
1519 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301520 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 hddLog(LOGE,
1522 FL("Failed to init AP inactivity timer"));
1523 } else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301524 QDF_ASSERT
Anurag Chouhan210db072016-02-22 18:42:15 +05301525 (qdf_mc_timer_get_current_state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 (&pHddApCtx->
1527 hdd_ap_inactivity_timer) ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301528 QDF_TIMER_STATE_STOPPED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 }
1530 }
1531#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1532 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1533#endif
1534
1535 cfg80211_del_sta(dev,
1536 (const u8 *)&pSapEvent->sapevt.
1537 sapStationDisassocCompleteEvent.staMac.
1538 bytes[0], GFP_KERNEL);
1539
1540 /* Update the beacon Interval if it is P2P GO */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301541 qdf_status = cds_change_mcc_go_beacon_interval(pHostapdAdapter);
1542 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001543 hddLog(LOGE, FL("failed to update Beacon interval %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301544 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001545 }
1546 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1547 /* send peer status indication to oem app */
1548 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1549 sapStationDisassocCompleteEvent.
1550 staMac, ePeerDisconnected,
1551 0,
1552 pHostapdAdapter->
1553 sessionId, NULL);
1554 }
1555#ifdef MSM_PLATFORM
1556 /*stop timer in sap/p2p_go */
1557 if (pHddApCtx->bApActive == false) {
1558 spin_lock_bh(&pHddCtx->bus_bw_lock);
1559 pHostapdAdapter->prev_tx_packets = 0;
1560 pHostapdAdapter->prev_rx_packets = 0;
1561 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1562 hdd_stop_bus_bw_compute_timer(pHostapdAdapter);
1563 }
1564#endif
1565 hdd_wlan_green_ap_del_sta(pHddCtx);
1566 break;
1567
1568 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1569 {
1570 static const char *message =
1571 "MLMEWPSPBCPROBEREQ.indication";
1572 union iwreq_data wreq;
1573
1574 down(&pHddApCtx->semWpsPBCOverlapInd);
1575 pHddApCtx->WPSPBCProbeReq.probeReqIELen =
1576 pSapEvent->sapevt.sapPBCProbeReqEvent.
1577 WPSPBCProbeReq.probeReqIELen;
1578
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301579 qdf_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 pSapEvent->sapevt.sapPBCProbeReqEvent.
1581 WPSPBCProbeReq.probeReqIE,
1582 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1583
Anurag Chouhanc5548422016-02-24 18:33:27 +05301584 qdf_copy_macaddr(&pHddApCtx->WPSPBCProbeReq.peer_macaddr,
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001585 &pSapEvent->sapevt.sapPBCProbeReqEvent.
1586 WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 hddLog(LOG1, "WPS PBC probe req " MAC_ADDRESS_STR,
1588 MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001589 peer_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590 memset(&wreq, 0, sizeof(wreq));
1591 wreq.data.length = strlen(message); /* This is length of message */
1592 wireless_send_event(dev, IWEVCUSTOM, &wreq,
1593 (char *)message);
1594
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301595 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596 }
1597 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1598 pAssocStasArray =
1599 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1600 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) { /* List of associated stations */
1601 for (i = 0;
1602 i <
1603 pSapEvent->sapevt.sapAssocStaListEvent.
1604 noOfAssocSta; i++) {
1605 hddLog(LOG1,
1606 "Associated Sta Num %d:assocId=%d, staId=%d, staMac="
1607 MAC_ADDRESS_STR, i + 1,
1608 pAssocStasArray->assocId,
1609 pAssocStasArray->staId,
1610 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
1611 bytes));
1612 pAssocStasArray++;
1613 }
1614 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301615 qdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas); /* Release caller allocated memory here */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301617 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618 case eSAP_REMAIN_CHAN_READY:
1619 hdd_remain_chan_ready_handler(pHostapdAdapter,
1620 pSapEvent->sapevt.sap_roc_ind.scan_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301621 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001622 case eSAP_SEND_ACTION_CNF:
1623 hdd_send_action_cnf(pHostapdAdapter,
1624 (eSAP_STATUS_SUCCESS ==
1625 pSapEvent->sapevt.sapActionCnf.
1626 actionSendSuccess) ? true : false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301627 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 case eSAP_UNKNOWN_STA_JOIN:
1629 snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
1630 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1631 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1632 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1633 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1634 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1635 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1636 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1637 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1638 wrqu.data.pointer = unknownSTAEvent;
1639 wrqu.data.length = strlen(unknownSTAEvent);
1640 we_custom_event_generic = (uint8_t *) unknownSTAEvent;
1641 hddLog(LOGE, "%s", unknownSTAEvent);
1642 break;
1643
1644 case eSAP_MAX_ASSOC_EXCEEDED:
1645 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
1646 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1647 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1648 " one or more devices to enable the new device connection",
1649 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1650 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1651 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1652 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1653 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1654 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
1655 bytes[5]);
1656 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1657 wrqu.data.pointer = maxAssocExceededEvent;
1658 wrqu.data.length = strlen(maxAssocExceededEvent);
1659 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
1660 hddLog(LOG1, "%s", maxAssocExceededEvent);
1661 break;
1662 case eSAP_STA_ASSOC_IND:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301663 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664
1665 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
1666 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
1667 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301668 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669
1670 case eSAP_MAC_TRIG_STOP_BSS_EVENT:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301671 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301673 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674 hddLog(LOGW, FL("hdd_stop_bss_link failed %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301675 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301677 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001678
1679 case eSAP_CHANNEL_CHANGE_EVENT:
1680 hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event"));
1681 /* Prevent suspend for new channel */
1682 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1683 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1684 /* Allow suspend for old channel */
1685 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1686 pHddApCtx->operatingChannel);
1687 /* SME/PE is already updated for new operation channel. So update
1688 * HDD layer also here. This resolves issue in AP-AP mode where
1689 * AP1 channel is changed due to RADAR then CAC is going on and
1690 * START_BSS on new channel has not come to HDD. At this case if
1691 * AP2 is start it needs current operation channel for MCC DFS
1692 * restiction
1693 */
1694 pHddApCtx->operatingChannel =
1695 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1696 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1697 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1698 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1699 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1700 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1701 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1702 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1703 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1704 pHddApCtx->sapConfig.acs_cfg.ch_width =
1705 pSapEvent->sapevt.sap_ch_selected.ch_width;
1706
1707 /* Indicate operating channel change to hostapd
1708 * only for non driver override acs
1709 */
1710 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
1711 pHddCtx->config->force_sap_acs)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301712 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001713 else
1714 return hdd_chan_change_notify(pHostapdAdapter, dev,
1715 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1716
1717#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1718 case eSAP_ACS_SCAN_SUCCESS_EVENT:
1719 pHddCtx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1720 hddLog(LOG1, FL("Reusing Last ACS scan result for %d sec"),
1721 ACS_SCAN_EXPIRY_TIMEOUT_S);
Anurag Chouhan210db072016-02-22 18:42:15 +05301722 qdf_mc_timer_stop(&pHddCtx->skip_acs_scan_timer);
1723 qdf_status = qdf_mc_timer_start(&pHddCtx->skip_acs_scan_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 ACS_SCAN_EXPIRY_TIMEOUT_S *
1725 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301726 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 hddLog(LOGE,
1728 FL("Failed to start ACS scan expiry timer"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301729 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730#endif
1731
1732 case eSAP_DFS_NOL_GET:
1733 hddLog(LOG1,
1734 FL("Received eSAP_DFS_NOL_GET event"));
1735#if defined CONFIG_CNSS
1736 /* get the dfs nol from cnss */
1737 ret =
1738 cnss_wlan_get_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1739 pDfsList,
1740 pSapEvent->sapevt.sapDfsNolInfo.
1741 sDfsList);
1742
1743 if (ret > 0) {
1744 hddLog(LOG2,
1745 FL("Get %d bytes of dfs nol from cnss"), ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301746 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747 } else {
1748 hddLog(LOG2,
1749 FL("No dfs nol entry in CNSS, ret: %d"), ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301750 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751 }
1752#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301753 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754#endif
1755 case eSAP_DFS_NOL_SET:
1756 hddLog(LOG1, FL("Received eSAP_DFS_NOL_SET event"));
1757#if defined CONFIG_CNSS
1758 /* set the dfs nol to cnss */
1759 ret =
1760 cnss_wlan_set_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1761 pDfsList,
1762 pSapEvent->sapevt.sapDfsNolInfo.
1763 sDfsList);
1764
1765 if (ret) {
1766 hddLog(LOG2,
1767 FL("Failed to set dfs nol - ret: %d"),
1768 ret);
1769 } else {
1770 hddLog(LOG2, FL(" Set %d bytes dfs nol to cnss"),
1771 pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
1772 }
1773#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301774 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301776 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 case eSAP_ACS_CHANNEL_SELECTED:
1778 hddLog(LOG1, FL("ACS Completed for wlan%d"),
1779 pHostapdAdapter->dev->ifindex);
1780 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
1781 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
1782 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1783 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1784 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1785 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1786 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1787 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1788 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1789 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1790 pHddApCtx->sapConfig.acs_cfg.ch_width =
1791 pSapEvent->sapevt.sap_ch_selected.ch_width;
1792 /* send vendor event to hostapd only for hostapd based acs*/
1793 if (!pHddCtx->config->force_sap_acs)
1794 wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301795 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301796 case eSAP_ECSA_CHANGE_CHAN_IND:
1797 hddLog(LOG1,
1798 FL("Channel change indication from peer for channel %d"),
1799 pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
1800 if (hdd_softap_set_channel_change(dev,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301801 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
1802 CH_WIDTH_MAX))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301803 return QDF_STATUS_E_FAILURE;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301804 else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301805 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301806
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807 default:
1808 hddLog(LOG1, "SAP message is not handled");
1809 goto stopbss;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301810 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811 }
1812 wireless_send_event(dev, we_event, &wrqu,
1813 (char *)we_custom_event_generic);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301814 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815
1816stopbss:
1817 {
1818 uint8_t we_custom_event[64];
1819 char *stopBssEvent = "STOP-BSS.response"; /* 17 */
1820 int event_len = strlen(stopBssEvent);
1821
1822 hddLog(LOG1, FL("BSS stop status = %s"),
1823 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1824 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1825
1826 /* Change the BSS state now since, as we are shutting things down,
1827 * we don't want interfaces to become re-enabled */
1828 pHostapdState->bssState = BSS_STOP;
1829
1830 if (0 !=
1831 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1832 nAPAutoShutOff) {
Anurag Chouhan210db072016-02-22 18:42:15 +05301833 if (QDF_TIMER_STATE_RUNNING ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001834 pHddApCtx->hdd_ap_inactivity_timer.state) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301835 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301836 qdf_mc_timer_stop(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301838 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839 hddLog(LOGE,
1840 FL("Failed to stop AP inactivity timer"));
1841 }
1842 }
1843
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301844 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301845 qdf_mc_timer_destroy(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001846 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301847 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001848 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1849 }
1850#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1851 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1852#endif
1853
1854 /* Stop the pkts from n/w stack as we are going to free all of
1855 * the TX WMM queues for all STAID's */
1856 hdd_hostapd_stop(dev);
1857
1858 /* reclaim all resources allocated to the BSS */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301859 qdf_status = hdd_softap_stop_bss(pHostapdAdapter);
1860 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001861 hddLog(LOGW,
1862 FL("hdd_softap_stop_bss failed %d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301863 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 }
1865
1866 /* once the event is set, structure dev/pHostapdAdapter should
1867 * not be touched since they are now subject to being deleted
1868 * by another thread */
1869 if (eSAP_STOP_BSS_EVENT == sapEvent)
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301870 qdf_event_set(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871
1872 /* notify userspace that the BSS has stopped */
1873 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1874 memcpy(&we_custom_event, stopBssEvent, event_len);
1875 memset(&wrqu, 0, sizeof(wrqu));
1876 wrqu.data.length = event_len;
1877 we_event = IWEVCUSTOM;
1878 we_custom_event_generic = we_custom_event;
1879 wireless_send_event(dev, we_event, &wrqu,
1880 (char *)we_custom_event_generic);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001881 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882 /* Send SCC/MCC Switching event to IPA */
1883 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1884 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301885 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001886}
1887
1888int hdd_softap_unpack_ie(tHalHandle halHandle,
1889 eCsrEncryptionType *pEncryptType,
1890 eCsrEncryptionType *mcEncryptType,
1891 eCsrAuthType *pAuthType,
1892 bool *pMFPCapable,
1893 bool *pMFPRequired,
1894 uint16_t gen_ie_len, uint8_t *gen_ie)
1895{
1896 tDot11fIERSN dot11RSNIE;
1897 tDot11fIEWPA dot11WPAIE;
1898
1899 uint8_t *pRsnIe;
1900 uint16_t RSNIeLen;
1901
1902 if (NULL == halHandle) {
1903 hddLog(LOGE, FL("Error haHandle returned NULL"));
1904 return -EINVAL;
1905 }
1906 /* Validity checks */
Anurag Chouhan6d760662016-02-20 16:05:43 +05301907 if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001908 || (gen_ie_len >
Anurag Chouhan6d760662016-02-20 16:05:43 +05301909 QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910 return -EINVAL;
1911 /* Type check */
1912 if (gen_ie[0] == DOT11F_EID_RSN) {
1913 /* Validity checks */
1914 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
1915 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301916 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001917 }
1918 /* Skip past the EID byte and length byte */
1919 pRsnIe = gen_ie + 2;
1920 RSNIeLen = gen_ie_len - 2;
1921 /* Unpack the RSN IE */
1922 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1923 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
1924 pRsnIe, RSNIeLen, &dot11RSNIE);
1925 /* Copy out the encryption and authentication types */
1926 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
1927 dot11RSNIE.pwise_cipher_suite_count);
1928 hddLog(LOG1, FL("authentication suite count: %d"),
1929 dot11RSNIE.akm_suite_count);
1930 /*Here we have followed the apple base code,
1931 but probably I suspect we can do something different */
1932 /* dot11RSNIE.akm_suite_count */
1933 /* Just translate the FIRST one */
1934 *pAuthType =
1935 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suites[0]);
1936 /* dot11RSNIE.pwise_cipher_suite_count */
1937 *pEncryptType =
1938 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1939 pwise_cipher_suites[0]);
1940 /* dot11RSNIE.gp_cipher_suite_count */
1941 *mcEncryptType =
1942 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1943 gp_cipher_suite);
1944 /* Set the PMKSA ID Cache for this interface */
1945 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1946 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
1947 /* Calling csr_roam_set_pmkid_cache to configure the PMKIDs into the cache */
1948 } else if (gen_ie[0] == DOT11F_EID_WPA) {
1949 /* Validity checks */
1950 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
1951 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301952 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001953 }
1954 /* Skip past the EID byte and length byte - and four byte WiFi OUI */
1955 pRsnIe = gen_ie + 2 + 4;
1956 RSNIeLen = gen_ie_len - (2 + 4);
1957 /* Unpack the WPA IE */
1958 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1959 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
1960 pRsnIe, RSNIeLen, &dot11WPAIE);
1961 /* Copy out the encryption and authentication types */
1962 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
1963 dot11WPAIE.unicast_cipher_count);
1964 hddLog(LOG1, FL("WPA authentication suite count: %d"),
1965 dot11WPAIE.auth_suite_count);
1966 /* dot11WPAIE.auth_suite_count */
1967 /* Just translate the FIRST one */
1968 *pAuthType =
1969 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
1970 /* dot11WPAIE.unicast_cipher_count */
1971 *pEncryptType =
1972 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1973 unicast_ciphers[0]);
1974 /* dot11WPAIE.unicast_cipher_count */
1975 *mcEncryptType =
1976 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1977 multicast_cipher);
1978 *pMFPCapable = false;
1979 *pMFPRequired = false;
1980 } else {
1981 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301982 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301984 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985}
1986
1987/**
1988 * hdd_softap_set_channel_change() -
1989 * This function to support SAP channel change with CSA IE
1990 * set in the beacons.
1991 *
1992 * @dev: pointer to the net device.
1993 * @target_channel: target channel number.
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301994 * @target_bw: Target bandwidth to move.
1995 * If no bandwidth is specified, the value is CH_WIDTH_MAX
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001996 *
1997 * Return: 0 for success, non zero for failure
1998 */
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301999int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
2000 phy_ch_width target_bw)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002001{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302002 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002003 int ret = 0;
2004 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2005 hdd_context_t *pHddCtx = NULL;
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302006 hdd_adapter_t *sta_adapter;
2007 hdd_station_ctx_t *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008
2009#ifndef WLAN_FEATURE_MBSSID
2010 v_CONTEXT_t p_cds_context =
2011 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2012#endif
2013
2014 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2015 ret = wlan_hdd_validate_context(pHddCtx);
2016 if (ret) {
2017 hddLog(LOGE, FL("invalid HDD context"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 return ret;
2019 }
2020
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +05302021 ret = hdd_validate_channel_and_bandwidth(pHostapdAdapter,
2022 target_channel, target_bw);
2023 if (ret) {
2024 hdd_err("Invalid CH and BW combo");
2025 return ret;
2026 }
2027
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302028 sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
2029 /*
2030 * conc_custom_rule1:
2031 * Force SCC for SAP + STA
2032 * if STA is already connected then we shouldn't allow
2033 * channel switch in SAP interface.
2034 */
2035 if (sta_adapter && pHddCtx->config->conc_custom_rule1) {
2036 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
2037 if (hdd_conn_is_connected(sta_ctx)) {
2038 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
2039 return -EBUSY;
2040 }
2041 }
2042
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302043 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002044 if (pHddCtx->dfs_radar_found == true) {
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302045 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046 hddLog(LOGE, FL("Channel switch in progress!!"));
2047 return -EBUSY;
2048 }
2049 /*
2050 * Set the dfs_radar_found flag to mimic channel change
2051 * when a radar is found. This will enable synchronizing
2052 * SAP and HDD states similar to that of radar indication.
2053 * Suspend the netif queues to stop queuing Tx frames
2054 * from upper layers. netif queues will be resumed
2055 * once the channel change is completed and SAP will
2056 * post eSAP_START_BSS_EVENT success event to HDD.
2057 */
2058 pHddCtx->dfs_radar_found = true;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302059 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060 /*
2061 * Post the Channel Change request to SAP.
2062 */
2063 status = wlansap_set_channel_change_with_csa(
2064#ifdef WLAN_FEATURE_MBSSID
2065 WLAN_HDD_GET_SAP_CTX_PTR
2066 (pHostapdAdapter),
2067#else
2068 p_cds_context,
2069#endif
2070 (uint32_t)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302071 target_channel,
2072 target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002073
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302074 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002075 hddLog(LOGE,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302076 FL("SAP set channel failed for channel = %d, bw:%d"),
2077 target_channel, target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002078 /*
2079 * If channel change command fails then clear the
2080 * radar found flag and also restart the netif
2081 * queues.
2082 */
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302083 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002084 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302085 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086
2087 ret = -EINVAL;
2088 }
2089
2090 return ret;
2091}
2092
2093int
2094static __iw_softap_set_ini_cfg(struct net_device *dev,
2095 struct iw_request_info *info,
2096 union iwreq_data *wrqu, char *extra)
2097{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302098 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 int ret = 0; /* success */
2100 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2101 hdd_context_t *pHddCtx;
2102
Jeff Johnson02050312016-02-11 18:40:28 -08002103 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002104
2105 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2106 ret = wlan_hdd_validate_context(pHddCtx);
2107 if (ret != 0) {
2108 hddLog(LOGE, FL("HDD context is not valid"));
2109 return ret;
2110 }
2111
2112 hddLog(LOG1, FL("Received data %s"), extra);
2113
2114 vstatus = hdd_execute_global_config_command(pHddCtx, extra);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302115 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002116 ret = -EINVAL;
2117 }
2118
2119 return ret;
2120}
2121
2122int
2123static iw_softap_set_ini_cfg(struct net_device *dev,
2124 struct iw_request_info *info,
2125 union iwreq_data *wrqu, char *extra)
2126{
2127 int ret;
2128
2129 cds_ssr_protect(__func__);
2130 ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
2131 cds_ssr_unprotect(__func__);
2132
2133 return ret;
2134}
2135
2136int
2137static __iw_softap_get_ini_cfg(struct net_device *dev,
2138 struct iw_request_info *info,
2139 union iwreq_data *wrqu, char *extra)
2140{
2141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2142 hdd_context_t *pHddCtx;
2143 int ret = 0;
2144
Jeff Johnson02050312016-02-11 18:40:28 -08002145 ENTER_DEV(dev);
2146
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2148 ret = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson02050312016-02-11 18:40:28 -08002149 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 return ret;
Jeff Johnson02050312016-02-11 18:40:28 -08002151
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152 hddLog(LOG1, FL("Printing CLD global INI Config"));
2153 hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN);
2154 wrqu->data.length = strlen(extra) + 1;
2155
2156 return 0;
2157}
2158
2159int
2160static iw_softap_get_ini_cfg(struct net_device *dev,
2161 struct iw_request_info *info,
2162 union iwreq_data *wrqu, char *extra)
2163{
2164 int ret;
2165
2166 cds_ssr_protect(__func__);
2167 ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
2168 cds_ssr_unprotect(__func__);
2169
2170 return ret;
2171}
2172
Govind Singha471e5e2015-10-12 17:11:14 +05302173/**
2174 * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
2175 * @dev: device upon which the ioctl was received
2176 * @info: ioctl request information
2177 * @wrqu: ioctl request data
2178 * @extra: ioctl extra data
2179 *
2180 * Return: 0 on success, non-zero on error
2181 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
2183 struct iw_request_info *info,
2184 union iwreq_data *wrqu, char *extra)
2185{
Govind Singha471e5e2015-10-12 17:11:14 +05302186 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2187 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002188 int *value = (int *)extra;
2189 int sub_cmd = value[0];
Govind Singha471e5e2015-10-12 17:11:14 +05302190 hdd_context_t *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191
Jeff Johnson02050312016-02-11 18:40:28 -08002192 ENTER_DEV(dev);
2193
Govind Singha471e5e2015-10-12 17:11:14 +05302194 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2195 ret = wlan_hdd_validate_context(hdd_ctx);
2196 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002197 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002198
2199 switch (sub_cmd) {
2200#ifdef DEBUG
2201 case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
2202 hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
2203 value[1], value[2]);
Govind Singha471e5e2015-10-12 17:11:14 +05302204 ret = wma_cli_set2_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002205 GEN_PARAM_CRASH_INJECT,
2206 value[1], value[2],
2207 GEN_CMD);
2208 break;
2209#endif
2210 case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
2211 hdd_info("WE_DUMP_DP_TRACE: %d %d",
2212 value[1], value[2]);
2213 if (value[1] == DUMP_DP_TRACE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302214 qdf_dp_trace_dump_all(value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 break;
Govind Singha471e5e2015-10-12 17:11:14 +05302216 case QCSAP_ENABLE_FW_PROFILE:
2217 hddLog(LOG1, "QCSAP_ENABLE_FW_PROFILE: %d %d",
2218 value[1], value[2]);
2219 ret = wma_cli_set2_command(adapter->sessionId,
2220 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2221 value[1], value[2], DBG_CMD);
2222 break;
2223 case QCSAP_SET_FW_PROFILE_HIST_INTVL:
2224 hddLog(LOG1, "QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
2225 value[1], value[2]);
2226 ret = wma_cli_set2_command(adapter->sessionId,
2227 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2228 value[1], value[2], DBG_CMD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002229 default:
2230 hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
2231 break;
2232 }
2233
2234out:
2235 return ret;
2236}
2237
2238static int iw_softap_set_two_ints_getnone(struct net_device *dev,
2239 struct iw_request_info *info,
2240 union iwreq_data *wrqu, char *extra)
2241{
2242 int ret;
2243
2244 cds_ssr_protect(__func__);
2245 ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
2246 cds_ssr_unprotect(__func__);
2247
2248 return ret;
2249}
2250
Anurag Chouhan6d760662016-02-20 16:05:43 +05302251static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002252{
2253 int i;
2254 uint8_t *macArray;
2255
2256 for (i = 0; i < size; i++) {
2257 macArray = (macList + i)->bytes;
2258 pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n",
2259 i, MAC_ADDR_ARRAY(macArray));
2260 }
2261 return;
2262}
2263
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302264static QDF_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002265{
2266 eSapMacAddrACL acl_mode;
Anurag Chouhan6d760662016-02-20 16:05:43 +05302267 struct qdf_mac_addr MacList[MAX_ACL_MAC_ADDRESS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 uint8_t listnum;
2269 void *p_cds_gctx = NULL;
2270
2271#ifdef WLAN_FEATURE_MBSSID
2272 p_cds_gctx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter);
2273#else
2274 p_cds_gctx = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2275#endif
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302276 qdf_mem_zero(&MacList[0], sizeof(MacList));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302277 if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(p_cds_gctx, &acl_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002278 pr_info("******** ACL MODE *********\n");
2279 switch (acl_mode) {
2280 case eSAP_ACCEPT_UNLESS_DENIED:
2281 pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
2282 break;
2283 case eSAP_DENY_UNLESS_ACCEPTED:
2284 pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
2285 break;
2286 case eSAP_SUPPORT_ACCEPT_AND_DENY:
2287 pr_info("ACL Mode = ACCEPT_AND_DENY\n");
2288 break;
2289 case eSAP_ALLOW_ALL:
2290 pr_info("ACL Mode = ALLOW_ALL\n");
2291 break;
2292 default:
2293 pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302294 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002295 }
2296 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302297 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002298 }
2299
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302300 if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002301 &MacList[0],
2302 &listnum)) {
2303 pr_info("******* WHITE LIST ***********\n");
2304 if (listnum <= MAX_ACL_MAC_ADDRESS)
2305 print_mac_list(&MacList[0], listnum);
2306 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302307 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002308 }
2309
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302310 if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002311 &MacList[0],
2312 &listnum)) {
2313 pr_info("******* BLACK LIST ***********\n");
2314 if (listnum <= MAX_ACL_MAC_ADDRESS)
2315 print_mac_list(&MacList[0], listnum);
2316 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302317 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002318 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302319 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002320}
2321
2322int
2323static __iw_softap_setparam(struct net_device *dev,
2324 struct iw_request_info *info,
2325 union iwreq_data *wrqu, char *extra)
2326{
2327 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2328 tHalHandle hHal;
2329 int *value = (int *)extra;
2330 int sub_cmd = value[0];
2331 int set_value = value[1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302332 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 int ret = 0; /* success */
2334 v_CONTEXT_t p_cds_context;
2335 hdd_context_t *hdd_ctx;
2336
Jeff Johnson02050312016-02-11 18:40:28 -08002337 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302338
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002339 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2340 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302341 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002342 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343
2344 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2345 if (!hHal) {
2346 hddLog(LOGE, FL("Hal ctx is null"));
2347 return -EINVAL;
2348 }
2349
2350 p_cds_context = hdd_ctx->pcds_context;
2351 if (!p_cds_context) {
2352 hddLog(LOGE, FL("cds ctx is null"));
2353 return -ENOENT;
2354 }
2355
2356 switch (sub_cmd) {
2357 case QCASAP_SET_RADAR_DBG:
2358 hddLog(LOG1, FL("QCASAP_SET_RADAR_DBG called with: value: %d"),
2359 set_value);
2360 wlan_sap_enable_phy_error_logs(hHal, (bool) set_value);
2361 break;
2362
2363 case QCSAP_PARAM_CLR_ACL:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302364 if (QDF_STATUS_SUCCESS != wlansap_clear_acl(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002365#ifdef WLAN_FEATURE_MBSSID
2366 WLAN_HDD_GET_SAP_CTX_PTR
2367 (pHostapdAdapter)
2368#else
2369 p_cds_context
2370#endif
2371 )) {
2372 ret = -EIO;
2373 }
2374 break;
2375
2376 case QCSAP_PARAM_ACL_MODE:
2377 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
2378 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
2379 hddLog(LOGE, FL("Invalid ACL Mode value %d"),
2380 set_value);
2381 ret = -EINVAL;
2382 } else {
2383#ifdef WLAN_FEATURE_MBSSID
2384 wlansap_set_mode(WLAN_HDD_GET_SAP_CTX_PTR
2385 (pHostapdAdapter), set_value);
2386#else
2387 wlansap_set_mode(p_cds_context, set_value);
2388#endif
2389
2390 }
2391 break;
2392
2393 case QCSAP_PARAM_SET_CHANNEL_CHANGE:
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302394 if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) ||
2395 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002396 hddLog(LOG1,
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302397 "SET Channel Change to new channel= %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002398 set_value);
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302399 ret = hdd_softap_set_channel_change(dev, set_value,
2400 CH_WIDTH_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401 } else {
2402 hddLog(LOGE,
2403 FL("Channel Change Failed, Device in test mode"));
2404 ret = -EINVAL;
2405 }
2406 break;
2407 case QCSAP_PARAM_AUTO_CHANNEL:
2408 if (set_value == 0 || set_value == 1)
2409 (WLAN_HDD_GET_CTX(
2410 pHostapdAdapter))->config->force_sap_acs =
2411 set_value;
2412 else
2413 ret = -EINVAL;
2414 break;
2415
2416 case QCSAP_PARAM_MAX_ASSOC:
2417 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
2418 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"),
2419 set_value);
2420 ret = -EINVAL;
2421 } else {
2422 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) {
2423 hddLog(LOGW,
2424 FL("setMaxAssoc %d > max allowed %d."),
2425 set_value,
2426 WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
2427 hddLog(LOGW,
2428 FL("Setting it to max allowed and continuing"));
2429 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
2430 }
2431 status = sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
2432 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302433 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002434 hddLog(LOGE,
2435 FL("setMaxAssoc failure, status %d"),
2436 status);
2437 ret = -EIO;
2438 }
2439 }
2440 break;
2441
2442 case QCSAP_PARAM_HIDE_SSID:
2443 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302444 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002445 status =
2446 sme_hide_ssid(hHal, pHostapdAdapter->sessionId,
2447 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302448 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002449 hddLog(LOGE, FL("QCSAP_PARAM_HIDE_SSID failed"));
2450 return status;
2451 }
2452 break;
2453 }
2454 case QCSAP_PARAM_SET_MC_RATE:
2455 {
2456 tSirRateUpdateInd rateUpdate = {0};
2457 struct hdd_config *pConfig = hdd_ctx->config;
2458
2459 hddLog(LOG1, "MC Target rate %d", set_value);
Anurag Chouhanc5548422016-02-24 18:33:27 +05302460 qdf_copy_macaddr(&rateUpdate.bssid,
Srinivas Girigowdaafede182015-11-18 22:36:12 -08002461 &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1;
2463 rateUpdate.dev_mode = pHostapdAdapter->device_mode;
2464 rateUpdate.mcastDataRate24GHz = set_value;
2465 rateUpdate.mcastDataRate24GHzTxFlag = 1;
2466 rateUpdate.mcastDataRate5GHz = set_value;
2467 rateUpdate.bcastDataRate = -1;
2468 status = sme_send_rate_update_ind(hHal, &rateUpdate);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302469 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 hddLog(LOGE, FL("SET_MC_RATE failed"));
2471 ret = -1;
2472 }
2473 break;
2474 }
2475
2476 case QCSAP_PARAM_SET_TXRX_FW_STATS:
2477 {
2478 hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
2479 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2480 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
2481 set_value, VDEV_CMD);
2482 break;
2483 }
2484 /* Firmware debug log */
2485 case QCSAP_DBGLOG_LOG_LEVEL:
2486 {
2487 hddLog(LOG1, "QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
2488 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2489 WMI_DBGLOG_LOG_LEVEL,
2490 set_value, DBG_CMD);
2491 break;
2492 }
2493
2494 case QCSAP_DBGLOG_VAP_ENABLE:
2495 {
2496 hddLog(LOG1, "QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
2497 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2498 WMI_DBGLOG_VAP_ENABLE,
2499 set_value, DBG_CMD);
2500 break;
2501 }
2502
2503 case QCSAP_DBGLOG_VAP_DISABLE:
2504 {
2505 hddLog(LOG1, "QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
2506 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2507 WMI_DBGLOG_VAP_DISABLE,
2508 set_value, DBG_CMD);
2509 break;
2510 }
2511
2512 case QCSAP_DBGLOG_MODULE_ENABLE:
2513 {
2514 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
2515 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2516 WMI_DBGLOG_MODULE_ENABLE,
2517 set_value, DBG_CMD);
2518 break;
2519 }
2520
2521 case QCSAP_DBGLOG_MODULE_DISABLE:
2522 {
2523 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
2524 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2525 WMI_DBGLOG_MODULE_DISABLE,
2526 set_value, DBG_CMD);
2527 break;
2528 }
2529
2530 case QCSAP_DBGLOG_MOD_LOG_LEVEL:
2531 {
2532 hddLog(LOG1, "QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
2533 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2534 WMI_DBGLOG_MOD_LOG_LEVEL,
2535 set_value, DBG_CMD);
2536 break;
2537 }
2538
2539 case QCSAP_DBGLOG_TYPE:
2540 {
2541 hddLog(LOG1, "QCSAP_DBGLOG_TYPE val %d", set_value);
2542 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2543 WMI_DBGLOG_TYPE,
2544 set_value, DBG_CMD);
2545 break;
2546 }
2547 case QCSAP_DBGLOG_REPORT_ENABLE:
2548 {
2549 hddLog(LOG1, "QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
2550 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2551 WMI_DBGLOG_REPORT_ENABLE,
2552 set_value, DBG_CMD);
2553 break;
2554 }
2555 case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
2556 {
2557 cds_set_mcc_latency(pHostapdAdapter, set_value);
2558 break;
2559 }
2560
2561 case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
2562 {
2563 hddLog(LOG1,
2564 FL("iwpriv cmd to set MCC quota value %dms"),
2565 set_value);
2566 ret = cds_go_set_mcc_p2p_quota(pHostapdAdapter,
2567 set_value);
2568 break;
2569 }
2570
2571 case QCASAP_TXRX_FWSTATS_RESET:
2572 {
2573 hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
2574 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2575 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
2576 set_value, VDEV_CMD);
2577 break;
2578 }
2579
2580 case QCSAP_PARAM_RTSCTS:
2581 {
2582 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2583 WMI_VDEV_PARAM_ENABLE_RTSCTS,
2584 set_value, VDEV_CMD);
2585 if (ret) {
2586 hddLog(LOGE, "FAILED TO SET RTSCTS at SAP");
2587 ret = -EIO;
2588 }
2589 break;
2590 }
2591 case QCASAP_SET_11N_RATE:
2592 {
2593 uint8_t preamble = 0, nss = 0, rix = 0;
2594 tsap_Config_t *pConfig =
2595 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2596
2597 hddLog(LOG1, "SET_HT_RATE val %d", set_value);
2598
2599 if (set_value != 0xff) {
2600 rix = RC_2_RATE_IDX(set_value);
2601 if (set_value & 0x80) {
2602 if (pConfig->SapHw_mode ==
2603 eCSR_DOT11_MODE_11b
2604 || pConfig->SapHw_mode ==
2605 eCSR_DOT11_MODE_11b_ONLY
2606 || pConfig->SapHw_mode ==
2607 eCSR_DOT11_MODE_11g
2608 || pConfig->SapHw_mode ==
2609 eCSR_DOT11_MODE_11g_ONLY
2610 || pConfig->SapHw_mode ==
2611 eCSR_DOT11_MODE_abg
2612 || pConfig->SapHw_mode ==
2613 eCSR_DOT11_MODE_11a) {
2614 hddLog(LOGE,
2615 "Not valid mode for HT");
2616 ret = -EIO;
2617 break;
2618 }
2619 preamble = WMI_RATE_PREAMBLE_HT;
2620 nss = HT_RC_2_STREAMS(set_value) - 1;
2621 } else if (set_value & 0x10) {
2622 if (pConfig->SapHw_mode ==
2623 eCSR_DOT11_MODE_11a) {
2624 hddLog(LOGE, "Not valid for cck");
2625 ret = -EIO;
2626 break;
2627 }
2628 preamble = WMI_RATE_PREAMBLE_CCK;
2629 /* Enable Short preamble always
2630 * for CCK except 1mbps
2631 */
2632 if (rix != 0x3)
2633 rix |= 0x4;
2634 } else {
2635 if (pConfig->SapHw_mode ==
2636 eCSR_DOT11_MODE_11b
2637 || pConfig->SapHw_mode ==
2638 eCSR_DOT11_MODE_11b_ONLY) {
2639 hddLog(LOGE, "Not valid for OFDM");
2640 ret = -EIO;
2641 break;
2642 }
2643 preamble = WMI_RATE_PREAMBLE_OFDM;
2644 }
2645 set_value = (preamble << 6) | (nss << 4) | rix;
2646 }
2647 hddLog(LOG1, "SET_HT_RATE val %d rix %d preamble %x nss %d",
2648 set_value, rix, preamble, nss);
2649 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2650 WMI_VDEV_PARAM_FIXED_RATE,
2651 set_value, VDEV_CMD);
2652 break;
2653 }
2654
2655 case QCASAP_SET_VHT_RATE:
2656 {
2657 uint8_t preamble = 0, nss = 0, rix = 0;
2658 tsap_Config_t *pConfig =
2659 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2660
2661 if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
2662 pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
2663 hddLog(LOGE,
2664 FL("SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d"),
2665 pConfig->SapHw_mode, pConfig->channel);
2666 ret = -EIO;
2667 break;
2668 }
2669
2670 if (set_value != 0xff) {
2671 rix = RC_2_RATE_IDX_11AC(set_value);
2672 preamble = WMI_RATE_PREAMBLE_VHT;
2673 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
2674
2675 set_value = (preamble << 6) | (nss << 4) | rix;
2676 }
2677 hddLog(LOG1, "SET_VHT_RATE val %d rix %d preamble %x nss %d",
2678 set_value, rix, preamble, nss);
2679
2680 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2681 WMI_VDEV_PARAM_FIXED_RATE,
2682 set_value, VDEV_CMD);
2683 break;
2684 }
2685
2686 case QCASAP_SHORT_GI:
2687 {
2688 hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value);
2689
2690 /* same as 40MHZ */
2691 ret = sme_update_ht_config(hHal, pHostapdAdapter->sessionId,
2692 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
2693 set_value);
2694 if (ret)
2695 hddLog(LOGE,
2696 "Failed to set ShortGI value ret(%d)", ret);
2697 break;
2698 }
2699
2700 case QCSAP_SET_AMPDU:
2701 {
2702 hddLog(LOG1, "QCSAP_SET_AMPDU %d", set_value);
2703 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2704 GEN_VDEV_PARAM_AMPDU,
2705 set_value, GEN_CMD);
2706 break;
2707 }
2708
2709 case QCSAP_SET_AMSDU:
2710 {
2711 hddLog(LOG1, "QCSAP_SET_AMSDU %d", set_value);
2712 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2713 GEN_VDEV_PARAM_AMSDU,
2714 set_value, GEN_CMD);
2715 break;
2716 }
2717 case QCSAP_GTX_HT_MCS:
2718 {
2719 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
2720 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2721 WMI_VDEV_PARAM_GTX_HT_MCS,
2722 set_value, GTX_CMD);
2723 break;
2724 }
2725
2726 case QCSAP_GTX_VHT_MCS:
2727 {
2728 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
2729 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2730 WMI_VDEV_PARAM_GTX_VHT_MCS,
2731 set_value, GTX_CMD);
2732 break;
2733 }
2734
2735 case QCSAP_GTX_USRCFG:
2736 {
2737 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
2738 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2739 WMI_VDEV_PARAM_GTX_USR_CFG,
2740 set_value, GTX_CMD);
2741 break;
2742 }
2743
2744 case QCSAP_GTX_THRE:
2745 {
2746 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
2747 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2748 WMI_VDEV_PARAM_GTX_THRE,
2749 set_value, GTX_CMD);
2750 break;
2751 }
2752
2753 case QCSAP_GTX_MARGIN:
2754 {
2755 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
2756 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2757 WMI_VDEV_PARAM_GTX_MARGIN,
2758 set_value, GTX_CMD);
2759 break;
2760 }
2761
2762 case QCSAP_GTX_STEP:
2763 {
2764 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
2765 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2766 WMI_VDEV_PARAM_GTX_STEP,
2767 set_value, GTX_CMD);
2768 break;
2769 }
2770
2771 case QCSAP_GTX_MINTPC:
2772 {
2773 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
2774 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2775 WMI_VDEV_PARAM_GTX_MINTPC,
2776 set_value, GTX_CMD);
2777 break;
2778 }
2779
2780 case QCSAP_GTX_BWMASK:
2781 {
2782 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
2783 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2784 WMI_VDEV_PARAM_GTX_BW_MASK,
2785 set_value, GTX_CMD);
2786 break;
2787 }
2788
2789#ifdef QCA_PKT_PROTO_TRACE
2790 case QCASAP_SET_DEBUG_LOG:
2791 {
2792 hdd_context_t *pHddCtx =
2793 WLAN_HDD_GET_CTX(pHostapdAdapter);
2794
2795 hddLog(LOG1, "QCASAP_SET_DEBUG_LOG val %d", set_value);
2796 /* Trace buffer dump only */
2797 if (CDS_PKT_TRAC_DUMP_CMD == set_value) {
2798 cds_pkt_trace_buf_dump();
2799 break;
2800 }
2801 pHddCtx->config->gEnableDebugLog = set_value;
2802 break;
2803 }
2804#endif /* QCA_PKT_PROTO_TRACE */
2805
2806 case QCASAP_SET_TM_LEVEL:
2807 {
2808 hddLog(LOG1, "Set Thermal Mitigation Level %d", set_value);
2809 (void)sme_set_thermal_level(hHal, set_value);
2810 break;
2811 }
2812
2813 case QCASAP_SET_DFS_IGNORE_CAC:
2814 {
2815 hddLog(LOG1, "Set Dfs ignore CAC %d", set_value);
2816
2817 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2818 return -EINVAL;
2819
2820 ret = wlansap_set_dfs_ignore_cac(hHal, set_value);
2821 break;
2822 }
2823
2824 case QCASAP_SET_DFS_TARGET_CHNL:
2825 {
2826 hddLog(LOG1, "Set Dfs target channel %d", set_value);
2827
2828 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2829 return -EINVAL;
2830
2831 ret = wlansap_set_dfs_target_chnl(hHal, set_value);
2832 break;
2833 }
2834
2835 case QCASAP_SET_DFS_NOL:
2836 wlansap_set_dfs_nol(
2837#ifdef WLAN_FEATURE_MBSSID
2838 WLAN_HDD_GET_SAP_CTX_PTR
2839 (pHostapdAdapter),
2840#else
2841 p_cds_context,
2842#endif
2843 (eSapDfsNolType) set_value);
2844 break;
2845
2846 case QCASAP_SET_RADAR_CMD:
2847 {
2848 hdd_context_t *pHddCtx =
2849 WLAN_HDD_GET_CTX(pHostapdAdapter);
2850 uint8_t ch =
2851 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
2852 operatingChannel;
2853 bool isDfsch;
2854
2855 isDfsch = (CHANNEL_STATE_DFS ==
2856 cds_get_channel_state(ch));
2857
2858 hddLog(LOG1, FL("Set QCASAP_SET_RADAR_CMD val %d"), set_value);
2859
2860 if (!pHddCtx->dfs_radar_found && isDfsch) {
2861 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2862 WMA_VDEV_DFS_CONTROL_CMDID,
2863 set_value, VDEV_CMD);
2864 } else {
2865 hddLog(LOGE,
2866 FL("Ignore, radar_found: %d, dfs_channel: %d"),
2867 pHddCtx->dfs_radar_found, isDfsch);
2868 }
2869 break;
2870 }
2871 case QCASAP_TX_CHAINMASK_CMD:
2872 {
2873 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD val %d", set_value);
2874 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2875 WMI_PDEV_PARAM_TX_CHAIN_MASK,
2876 set_value, PDEV_CMD);
2877 break;
2878 }
2879
2880 case QCASAP_RX_CHAINMASK_CMD:
2881 {
2882 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD val %d", set_value);
2883 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2884 WMI_PDEV_PARAM_RX_CHAIN_MASK,
2885 set_value, PDEV_CMD);
2886 break;
2887 }
2888
2889 case QCASAP_NSS_CMD:
2890 {
2891 hddLog(LOG1, "QCASAP_NSS_CMD val %d", set_value);
2892 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2893 WMI_VDEV_PARAM_NSS,
2894 set_value, VDEV_CMD);
2895 break;
2896 }
2897
2898 case QCSAP_IPA_UC_STAT:
2899 {
2900 /* If input value is non-zero get stats */
2901 switch (set_value) {
2902 case 1:
2903 hdd_ipa_uc_stat_request(pHostapdAdapter, set_value);
2904 break;
2905 case 3:
2906 hdd_ipa_uc_rt_debug_host_dump(
2907 WLAN_HDD_GET_CTX(pHostapdAdapter));
2908 break;
2909 default:
2910 /* place holder for stats clean up
2911 * Stats clean not implemented yet on firmware and ipa
2912 */
2913 break;
2914 }
2915 return ret;
2916 }
2917
2918 case QCASAP_SET_PHYMODE:
2919 {
2920 hdd_context_t *phddctx =
2921 WLAN_HDD_GET_CTX(pHostapdAdapter);
2922
2923 ret =
2924 wlan_hdd_update_phymode(dev, hHal, set_value,
2925 phddctx);
2926 break;
2927 }
2928 case QCASAP_DUMP_STATS:
2929 {
2930 hddLog(LOG1, "QCASAP_DUMP_STATS val %d", set_value);
2931 hdd_wlan_dump_stats(pHostapdAdapter, set_value);
2932 break;
2933 }
2934 case QCASAP_CLEAR_STATS:
2935 {
2936 hdd_context_t *hdd_ctx =
2937 WLAN_HDD_GET_CTX(pHostapdAdapter);
2938 hddLog(LOG1, "QCASAP_CLEAR_STATS val %d", set_value);
2939 switch (set_value) {
2940 case WLAN_HDD_STATS:
2941 memset(&pHostapdAdapter->stats, 0,
2942 sizeof(pHostapdAdapter->stats));
2943 memset(&pHostapdAdapter->hdd_stats, 0,
2944 sizeof(pHostapdAdapter->hdd_stats));
2945 break;
2946 case WLAN_TXRX_HIST_STATS:
2947 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
2948 break;
2949 case WLAN_HDD_NETIF_OPER_HISTORY:
2950 wlan_hdd_clear_netif_queue_history(hdd_ctx);
2951 break;
2952 default:
2953 ol_txrx_clear_stats(set_value);
2954 }
2955 break;
2956 }
Govind Singha471e5e2015-10-12 17:11:14 +05302957 case QCSAP_START_FW_PROFILING:
2958 hddLog(LOG1, "QCSAP_START_FW_PROFILING %d", set_value);
2959 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2960 WMI_WLAN_PROFILE_TRIGGER_CMDID,
2961 set_value, DBG_CMD);
2962 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002963 default:
2964 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
2965 sub_cmd, set_value);
2966 ret = -EINVAL;
2967 break;
2968 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302969 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002970 return ret;
2971}
2972
2973int
2974static iw_softap_setparam(struct net_device *dev,
2975 struct iw_request_info *info,
2976 union iwreq_data *wrqu, char *extra)
2977{
2978 int ret;
2979
2980 cds_ssr_protect(__func__);
2981 ret = __iw_softap_setparam(dev, info, wrqu, extra);
2982 cds_ssr_unprotect(__func__);
2983
2984 return ret;
2985}
2986
2987int
2988static __iw_softap_getparam(struct net_device *dev,
2989 struct iw_request_info *info,
2990 union iwreq_data *wrqu, char *extra)
2991{
2992 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2993 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2994 int *value = (int *)extra;
2995 int sub_cmd = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302996 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002997 int ret;
2998 hdd_context_t *hdd_ctx;
2999
Jeff Johnson02050312016-02-11 18:40:28 -08003000 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303001
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003002 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3003 ret = wlan_hdd_validate_context(hdd_ctx);
3004 if (0 != ret)
3005 return ret;
3006
3007 switch (sub_cmd) {
3008 case QCSAP_PARAM_MAX_ASSOC:
3009 status =
3010 sme_cfg_get_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
3011 (uint32_t *) value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303012 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003013 hddLog(LOGE,
3014 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),
3015 status);
3016 ret = -EIO;
3017 }
3018 break;
3019
3020 case QCSAP_PARAM_AUTO_CHANNEL:
3021 *value = (WLAN_HDD_GET_CTX
3022 (pHostapdAdapter))->config->force_sap_acs;
3023 break;
3024
3025 case QCSAP_PARAM_GET_WLAN_DBG:
3026 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303027 qdf_trace_display();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003028 *value = 0;
3029 break;
3030 }
3031
3032 case QCSAP_PARAM_RTSCTS:
3033 {
3034 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3035 WMI_VDEV_PARAM_ENABLE_RTSCTS,
3036 VDEV_CMD);
3037 break;
3038 }
3039
3040 case QCASAP_SHORT_GI:
3041 {
3042 *value = (int)sme_get_ht_config(hHal,
3043 pHostapdAdapter->
3044 sessionId,
3045 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
3046 break;
3047 }
3048
3049 case QCSAP_GTX_HT_MCS:
3050 {
3051 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
3052 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3053 WMI_VDEV_PARAM_GTX_HT_MCS,
3054 GTX_CMD);
3055 break;
3056 }
3057
3058 case QCSAP_GTX_VHT_MCS:
3059 {
3060 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
3061 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3062 WMI_VDEV_PARAM_GTX_VHT_MCS,
3063 GTX_CMD);
3064 break;
3065 }
3066
3067 case QCSAP_GTX_USRCFG:
3068 {
3069 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
3070 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3071 WMI_VDEV_PARAM_GTX_USR_CFG,
3072 GTX_CMD);
3073 break;
3074 }
3075
3076 case QCSAP_GTX_THRE:
3077 {
3078 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
3079 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3080 WMI_VDEV_PARAM_GTX_THRE,
3081 GTX_CMD);
3082 break;
3083 }
3084
3085 case QCSAP_GTX_MARGIN:
3086 {
3087 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
3088 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3089 WMI_VDEV_PARAM_GTX_MARGIN,
3090 GTX_CMD);
3091 break;
3092 }
3093
3094 case QCSAP_GTX_STEP:
3095 {
3096 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
3097 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3098 WMI_VDEV_PARAM_GTX_STEP,
3099 GTX_CMD);
3100 break;
3101 }
3102
3103 case QCSAP_GTX_MINTPC:
3104 {
3105 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
3106 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3107 WMI_VDEV_PARAM_GTX_MINTPC,
3108 GTX_CMD);
3109 break;
3110 }
3111
3112 case QCSAP_GTX_BWMASK:
3113 {
3114 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
3115 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3116 WMI_VDEV_PARAM_GTX_BW_MASK,
3117 GTX_CMD);
3118 break;
3119 }
3120
3121 case QCASAP_GET_DFS_NOL:
3122 {
3123 wlansap_get_dfs_nol(
3124#ifdef WLAN_FEATURE_MBSSID
3125 WLAN_HDD_GET_SAP_CTX_PTR
3126 (pHostapdAdapter)
3127#else
3128 pHddCtx->pcds_context
3129#endif
3130 );
3131 }
3132 break;
3133
3134 case QCSAP_GET_ACL:
3135 {
3136 hddLog(LOG1, FL("QCSAP_GET_ACL"));
3137 if (hdd_print_acl(pHostapdAdapter) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303138 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003139 hddLog(LOGE,
3140 FL
3141 ("QCSAP_GET_ACL returned Error: not completed"));
3142 }
3143 *value = 0;
3144 break;
3145 }
3146
3147 case QCASAP_TX_CHAINMASK_CMD:
3148 {
3149 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD");
3150 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3151 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3152 PDEV_CMD);
3153 break;
3154 }
3155
3156 case QCASAP_RX_CHAINMASK_CMD:
3157 {
3158 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD");
3159 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3160 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3161 PDEV_CMD);
3162 break;
3163 }
3164
3165 case QCASAP_NSS_CMD:
3166 {
3167 hddLog(LOG1, "QCASAP_NSS_CMD");
3168 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3169 WMI_VDEV_PARAM_NSS,
3170 VDEV_CMD);
3171 break;
3172 }
3173 case QCASAP_GET_TEMP_CMD:
3174 {
3175 hddLog(LOG1, "QCASAP_GET_TEMP_CMD");
3176 ret = wlan_hdd_get_temperature(pHostapdAdapter, value);
3177 break;
3178 }
Govind Singha471e5e2015-10-12 17:11:14 +05303179 case QCSAP_GET_FW_PROFILE_DATA:
3180 hddLog(LOG1, "QCSAP_GET_FW_PROFILE_DATA");
3181 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3182 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
3183 0, DBG_CMD);
3184 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003185 default:
3186 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
3187 ret = -EINVAL;
3188 break;
3189
3190 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303191 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003192 return ret;
3193}
3194
3195int
3196static iw_softap_getparam(struct net_device *dev,
3197 struct iw_request_info *info,
3198 union iwreq_data *wrqu, char *extra)
3199{
3200 int ret;
3201
3202 cds_ssr_protect(__func__);
3203 ret = __iw_softap_getparam(dev, info, wrqu, extra);
3204 cds_ssr_unprotect(__func__);
3205
3206 return ret;
3207}
3208
3209/* Usage:
3210 BLACK_LIST = 0
3211 WHITE_LIST = 1
3212 ADD MAC = 0
3213 REMOVE MAC = 1
3214
3215 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3216 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3217 while using this ioctl
3218
3219 Syntax:
3220 iwpriv softap.0 modify_acl
3221 <6 octet mac addr> <list type> <cmd type>
3222
3223 Examples:
3224 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
3225 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
3226 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
3227 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
3228 */
3229static
3230int __iw_softap_modify_acl(struct net_device *dev,
3231 struct iw_request_info *info,
3232 union iwreq_data *wrqu, char *extra)
3233{
3234 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3235#ifndef WLAN_FEATURE_MBSSID
3236 v_CONTEXT_t cds_ctx;
3237#endif
3238 uint8_t *value = (uint8_t *) extra;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303239 uint8_t pPeerStaMac[QDF_MAC_ADDR_SIZE];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003240 int listType, cmd, i;
3241 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303242 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003243 hdd_context_t *hdd_ctx;
3244
Jeff Johnson02050312016-02-11 18:40:28 -08003245 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003246
3247 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3248 ret = wlan_hdd_validate_context(hdd_ctx);
3249 if (0 != ret)
3250 return ret;
3251
3252#ifndef WLAN_FEATURE_MBSSID
3253 cds_ctx = hdd_ctx->pcds_context;
3254 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303255 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256 "%s: Vos Context is NULL", __func__);
3257 return -EINVAL;
3258 }
3259#endif
3260
Anurag Chouhan6d760662016-02-20 16:05:43 +05303261 for (i = 0; i < QDF_MAC_ADDR_SIZE; i++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003262 pPeerStaMac[i] = *(value + i);
3263
3264 listType = (int)(*(value + i));
3265 i++;
3266 cmd = (int)(*(value + i));
3267
3268 hddLog(LOG1, FL("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d"),
3269 MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
3270
3271#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303272 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003273 wlansap_modify_acl(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
3274 pPeerStaMac, (eSapACLType) listType,
3275 (eSapACLCmdType) cmd);
3276#else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303277 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 wlansap_modify_acl(p_cds_context, pPeerStaMac,
3279 (eSapACLType) listType, (eSapACLCmdType) cmd);
3280#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303281 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003282 hddLog(LOGE, FL("Modify ACL failed"));
3283 ret = -EIO;
3284 }
3285 EXIT();
3286 return ret;
3287}
3288
3289static
3290int iw_softap_modify_acl(struct net_device *dev,
3291 struct iw_request_info *info,
3292 union iwreq_data *wrqu, char *extra)
3293{
3294 int ret;
3295
3296 cds_ssr_protect(__func__);
3297 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
3298 cds_ssr_unprotect(__func__);
3299
3300 return ret;
3301}
3302
3303int
3304static __iw_softap_getchannel(struct net_device *dev,
3305 struct iw_request_info *info,
3306 union iwreq_data *wrqu, char *extra)
3307{
3308 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3309 hdd_context_t *hdd_ctx;
3310 int *value = (int *)extra;
3311 int ret;
3312
Jeff Johnson02050312016-02-11 18:40:28 -08003313 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303314
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003315 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3316 ret = wlan_hdd_validate_context(hdd_ctx);
3317 if (0 != ret)
3318 return ret;
3319
3320 *value = 0;
3321 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3322 *value = (WLAN_HDD_GET_AP_CTX_PTR(
3323 pHostapdAdapter))->operatingChannel;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303324 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003325 return 0;
3326}
3327
3328int
3329static iw_softap_getchannel(struct net_device *dev,
3330 struct iw_request_info *info,
3331 union iwreq_data *wrqu, char *extra)
3332{
3333 int ret;
3334
3335 cds_ssr_protect(__func__);
3336 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
3337 cds_ssr_unprotect(__func__);
3338
3339 return ret;
3340}
3341
3342int
3343static __iw_softap_set_max_tx_power(struct net_device *dev,
3344 struct iw_request_info *info,
3345 union iwreq_data *wrqu, char *extra)
3346{
3347 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3348 hdd_context_t *hdd_ctx;
3349 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3350 int *value = (int *)extra;
3351 int set_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003352 int ret;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303353 struct qdf_mac_addr bssid = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
3354 struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003355
Jeff Johnson02050312016-02-11 18:40:28 -08003356 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303357
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003358 if (NULL == value)
3359 return -ENOMEM;
3360
3361 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3362 ret = wlan_hdd_validate_context(hdd_ctx);
3363 if (0 != ret)
3364 return ret;
3365
3366 /* Assign correct slef MAC address */
Anurag Chouhanc5548422016-02-24 18:33:27 +05303367 qdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
3368 qdf_copy_macaddr(&selfMac, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003369
3370 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303371 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003372 sme_set_max_tx_power(hHal, bssid, selfMac, set_value)) {
3373 hddLog(LOGE, FL("Setting maximum tx power failed"));
3374 return -EIO;
3375 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303376 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003377 return 0;
3378}
3379
3380int
3381static iw_softap_set_max_tx_power(struct net_device *dev,
3382 struct iw_request_info *info,
3383 union iwreq_data *wrqu, char *extra)
3384{
3385 int ret;
3386
3387 cds_ssr_protect(__func__);
3388 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
3389 cds_ssr_unprotect(__func__);
3390
3391 return ret;
3392}
3393
3394int
3395static __iw_softap_set_tx_power(struct net_device *dev,
3396 struct iw_request_info *info,
3397 union iwreq_data *wrqu, char *extra)
3398{
3399 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3400 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3401 hdd_context_t *hdd_ctx;
3402 int *value = (int *)extra;
3403 int set_value;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303404 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003405 int ret;
3406
Jeff Johnson02050312016-02-11 18:40:28 -08003407 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303408
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003409 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3410 ret = wlan_hdd_validate_context(hdd_ctx);
3411 if (0 != ret)
3412 return ret;
3413
3414 if (NULL == value)
3415 return -ENOMEM;
3416
Anurag Chouhanc5548422016-02-24 18:33:27 +05303417 qdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003418
3419 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303420 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003421 sme_set_tx_power(hHal, pHostapdAdapter->sessionId, bssid,
3422 pHostapdAdapter->device_mode, set_value)) {
3423 hddLog(LOGE, FL("Setting tx power failed"));
3424 return -EIO;
3425 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303426 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003427 return 0;
3428}
3429
3430int
3431static iw_softap_set_tx_power(struct net_device *dev,
3432 struct iw_request_info *info,
3433 union iwreq_data *wrqu, char *extra)
3434{
3435 int ret;
3436
3437 cds_ssr_protect(__func__);
3438 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
3439 cds_ssr_unprotect(__func__);
3440
3441 return ret;
3442}
3443
3444#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
3445
3446int
3447static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
3448 struct iw_request_info *info,
3449 union iwreq_data *wrqu, char *extra)
3450{
3451 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3452 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
3453 hdd_context_t *hdd_ctx;
3454 char *buf;
3455 int cnt = 0;
3456 int left;
3457 int ret;
3458 /* maclist_index must be u32 to match userspace */
3459 u32 maclist_index;
3460
Jeff Johnson02050312016-02-11 18:40:28 -08003461 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303462
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003463 /*
3464 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
3465 * number, and even numbered iocts are supposed to have "set"
3466 * semantics. Hence the wireless extensions support in the kernel
3467 * won't correctly copy the result to userspace, so the ioctl
3468 * handler itself must copy the data. Output format is 32-bit
3469 * record length, followed by 0 or more 6-byte STA MAC addresses.
3470 *
3471 * Further note that due to the incorrect semantics, the "iwpriv"
3472 * userspace application is unable to correctly invoke this API,
3473 * hence it is not registered in the hostapd_private_args. This
3474 * API can only be invoked by directly invoking the ioctl() system
3475 * call.
3476 */
3477
3478 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3479 ret = wlan_hdd_validate_context(hdd_ctx);
3480 if (0 != ret)
3481 return ret;
3482
3483 /* make sure userspace allocated a reasonable buffer size */
3484 if (wrqu->data.length < sizeof(maclist_index)) {
3485 hddLog(LOG1, FL("invalid userspace buffer"));
3486 return -EINVAL;
3487 }
3488
3489 /* allocate local buffer to build the response */
3490 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
3491 if (!buf) {
3492 hddLog(LOG1, FL("failed to allocate response buffer"));
3493 return -ENOMEM;
3494 }
3495
3496 /* start indexing beyond where the record count will be written */
3497 maclist_index = sizeof(maclist_index);
3498 left = wrqu->data.length - maclist_index;
3499
3500 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303501 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003502 if ((pStaInfo[cnt].isUsed) &&
3503 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
3504 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
Anurag Chouhan6d760662016-02-20 16:05:43 +05303505 QDF_MAC_ADDR_SIZE);
3506 maclist_index += QDF_MAC_ADDR_SIZE;
3507 left -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508 }
3509 cnt++;
3510 }
3511 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
3512
3513 *((u32 *) buf) = maclist_index;
3514 wrqu->data.length = maclist_index;
3515 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
3516 hddLog(LOG1, FL("failed to copy response to user buffer"));
3517 ret = -EFAULT;
3518 }
3519 kfree(buf);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303520 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003521 return ret;
3522}
3523
3524int
3525static iw_softap_getassoc_stamacaddr(struct net_device *dev,
3526 struct iw_request_info *info,
3527 union iwreq_data *wrqu, char *extra)
3528{
3529 int ret;
3530
3531 cds_ssr_protect(__func__);
3532 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
3533 cds_ssr_unprotect(__func__);
3534
3535 return ret;
3536}
3537
3538/* Usage:
3539 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3540 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3541 while using this ioctl
3542
3543 Syntax:
3544 iwpriv softap.0 disassoc_sta <6 octet mac address>
3545
3546 e.g.
3547 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
3548 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
3549 */
3550
3551int
3552static __iw_softap_disassoc_sta(struct net_device *dev,
3553 struct iw_request_info *info,
3554 union iwreq_data *wrqu, char *extra)
3555{
3556 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3557 hdd_context_t *hdd_ctx;
3558 uint8_t *peerMacAddr;
3559 int ret;
3560
Jeff Johnson02050312016-02-11 18:40:28 -08003561 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003562
Mukul Sharma744420f2015-11-02 19:49:13 +05303563 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303564 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharma744420f2015-11-02 19:49:13 +05303565 FL("permission check failed"));
3566 return -EPERM;
3567 }
3568
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003569 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3570 ret = wlan_hdd_validate_context(hdd_ctx);
3571 if (0 != ret)
3572 return ret;
3573
3574 /* iwpriv tool or framework calls this ioctl with
3575 * data passed in extra (less than 16 octets);
3576 */
3577 peerMacAddr = (uint8_t *) (extra);
3578
3579 hddLog(LOG1, FL("data " MAC_ADDRESS_STR),
3580 MAC_ADDR_ARRAY(peerMacAddr));
3581 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
3582 EXIT();
3583 return 0;
3584}
3585
3586int
3587static iw_softap_disassoc_sta(struct net_device *dev,
3588 struct iw_request_info *info,
3589 union iwreq_data *wrqu, char *extra)
3590{
3591 int ret;
3592
3593 cds_ssr_protect(__func__);
3594 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
3595 cds_ssr_unprotect(__func__);
3596
3597 return ret;
3598}
3599
Govind Singha471e5e2015-10-12 17:11:14 +05303600/**
3601 * iw_get_char_setnone() - Generic "get char" private ioctl handler
3602 * @dev: device upon which the ioctl was received
3603 * @info: ioctl request information
3604 * @wrqu: ioctl request data
3605 * @extra: ioctl extra data
3606 *
3607 * Return: 0 on success, non-zero on error
3608 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003609static int __iw_get_char_setnone(struct net_device *dev,
3610 struct iw_request_info *info,
3611 union iwreq_data *wrqu, char *extra)
3612{
3613 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Govind Singha471e5e2015-10-12 17:11:14 +05303614 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003615 int sub_cmd = wrqu->data.flags;
3616 hdd_context_t *hdd_ctx;
3617
Jeff Johnson02050312016-02-11 18:40:28 -08003618 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003619
3620 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Govind Singha471e5e2015-10-12 17:11:14 +05303621 ret = wlan_hdd_validate_context(hdd_ctx);
3622 if (ret != 0)
3623 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003624
3625 switch (sub_cmd) {
3626 case QCSAP_GET_STATS:
3627 hdd_wlan_get_stats(adapter, &(wrqu->data.length),
3628 extra, WE_MAX_STR_LEN);
3629 break;
Govind Singha471e5e2015-10-12 17:11:14 +05303630 case QCSAP_LIST_FW_PROFILE:
3631 hdd_wlan_list_fw_profile(&(wrqu->data.length),
3632 extra, WE_MAX_STR_LEN);
3633 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003634 }
3635
3636 EXIT();
Govind Singha471e5e2015-10-12 17:11:14 +05303637 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003638}
3639
3640static int iw_get_char_setnone(struct net_device *dev,
3641 struct iw_request_info *info,
3642 union iwreq_data *wrqu, char *extra)
3643{
3644 int ret;
3645
3646 cds_ssr_protect(__func__);
3647 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
3648 cds_ssr_unprotect(__func__);
3649
3650 return ret;
3651}
3652
3653static int wlan_hdd_set_force_acs_ch_range(struct net_device *dev,
3654 struct iw_request_info *info,
3655 union iwreq_data *wrqu, char *extra)
3656{
3657 hdd_adapter_t *adapter = (netdev_priv(dev));
3658 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3659 int *value = (int *)extra;
3660
Jeff Johnson02050312016-02-11 18:40:28 -08003661 ENTER_DEV(dev);
3662
Hanumantha Reddy Pothula3b8c0a52015-11-05 10:59:21 +05303663 if (!capable(CAP_NET_ADMIN)) {
3664 hddLog(LOGE, FL("permission check failed"));
3665 return -EPERM;
3666 }
3667
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003668 if (wlan_hdd_validate_operation_channel(adapter, value[0]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303669 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003670 wlan_hdd_validate_operation_channel(adapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303671 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003672 return -EINVAL;
3673 } else {
3674 hdd_ctx->config->force_sap_acs_st_ch = value[0];
3675 hdd_ctx->config->force_sap_acs_end_ch = value[1];
3676 }
3677
3678 return 0;
3679}
3680
3681static int iw_softap_set_force_acs_ch_range(struct net_device *dev,
3682 struct iw_request_info *info,
3683 union iwreq_data *wrqu, char *extra)
3684{
3685 int ret;
3686 cds_ssr_protect(__func__);
3687 ret = wlan_hdd_set_force_acs_ch_range(dev, info, wrqu, extra);
3688 cds_ssr_unprotect(__func__);
3689 return ret;
3690}
3691
3692static int __iw_softap_get_channel_list(struct net_device *dev,
3693 struct iw_request_info *info,
3694 union iwreq_data *wrqu, char *extra)
3695{
3696 uint32_t num_channels = 0;
3697 uint8_t i = 0;
3698 uint8_t bandStartChannel = RF_CHAN_1;
3699 uint8_t bandEndChannel = RF_CHAN_184;
3700 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3701 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3702 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
3703 eCsrBand curBand = eCSR_BAND_ALL;
3704 hdd_context_t *hdd_ctx;
3705 int ret;
3706
Jeff Johnson02050312016-02-11 18:40:28 -08003707 ENTER_DEV(dev);
3708
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003709 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3710 ret = wlan_hdd_validate_context(hdd_ctx);
3711 if (0 != ret)
3712 return ret;
3713
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303714 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &curBand)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003715 hddLog(LOGE, FL("not able get the current frequency band"));
3716 return -EIO;
3717 }
3718 wrqu->data.length = sizeof(tChannelListInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003719
3720 if (eCSR_BAND_24 == curBand) {
3721 bandStartChannel = RF_CHAN_1;
3722 bandEndChannel = RF_CHAN_14;
3723 } else if (eCSR_BAND_5G == curBand) {
3724 bandStartChannel = RF_CHAN_36;
3725 bandEndChannel = RF_CHAN_184;
3726 }
3727
3728 hddLog(LOG1, FL("curBand = %d, StartChannel = %hu, EndChannel = %hu "),
3729 curBand, bandStartChannel, bandEndChannel);
3730
3731 for (i = bandStartChannel; i <= bandEndChannel; i++) {
Amar Singhal7a1726a2015-10-14 16:28:11 -07003732 if ((CHANNEL_STATE_ENABLE == CDS_CHANNEL_STATE(i)) ||
3733 (CHANNEL_STATE_DFS == CDS_CHANNEL_STATE(i))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003734 channel_list->channels[num_channels] =
Amar Singhal7a1726a2015-10-14 16:28:11 -07003735 CDS_CHANNEL_NUM(i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736 num_channels++;
3737 }
3738 }
3739
3740 hddLog(LOG1, FL(" number of channels %d"), num_channels);
3741
3742 if (num_channels > IW_MAX_FREQUENCIES) {
3743 num_channels = IW_MAX_FREQUENCIES;
3744 }
3745
3746 channel_list->num_channels = num_channels;
3747 EXIT();
3748
3749 return 0;
3750}
3751
3752int iw_softap_get_channel_list(struct net_device *dev,
3753 struct iw_request_info *info,
3754 union iwreq_data *wrqu, char *extra)
3755{
3756 int ret;
3757
3758 cds_ssr_protect(__func__);
3759 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
3760 cds_ssr_unprotect(__func__);
3761
3762 return ret;
3763}
3764
3765static
3766int __iw_get_genie(struct net_device *dev,
3767 struct iw_request_info *info,
3768 union iwreq_data *wrqu, char *extra)
3769{
3770 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3771 hdd_context_t *hdd_ctx;
3772 int ret;
3773#ifndef WLAN_FEATURE_MBSSID
3774 v_CONTEXT_t cds_ctx;
3775#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303776 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003777 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
3778 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
3779
Jeff Johnson02050312016-02-11 18:40:28 -08003780 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003781
3782 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3783 ret = wlan_hdd_validate_context(hdd_ctx);
3784 if (0 != ret)
3785 return ret;
3786
3787#ifndef WLAN_FEATURE_MBSSID
3788 cds_ctx = hdd_ctx->pcds_context;
3789 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303790 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003791 "%s: vos context is not valid ", __func__);
3792 return -EINVAL;
3793 }
3794#endif
3795
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003796 /*
3797 * Actually retrieve the RSN IE from CSR.
3798 * (We previously sent it down in the CSR Roam Profile.)
3799 */
3800 status = wlan_sap_getstation_ie_information(
3801#ifdef WLAN_FEATURE_MBSSID
3802 WLAN_HDD_GET_SAP_CTX_PTR
3803 (pHostapdAdapter),
3804#else
3805 cds_ctx,
3806#endif
3807 &length, genIeBytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303808 if (status == QDF_STATUS_SUCCESS) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05303809 length = QDF_MIN(length, DOT11F_IE_RSN_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003810 if (wrqu->data.length < length ||
3811 copy_to_user(wrqu->data.pointer, (void *)genIeBytes, length)) {
3812 hddLog(LOG1, FL("failed to copy data to user buffer"));
3813 return -EFAULT;
3814 }
3815 wrqu->data.length = length;
3816 hddLog(LOG1, FL(" RSN IE of %d bytes returned"),
3817 wrqu->data.length);
3818 } else {
3819 wrqu->data.length = 0;
3820 hddLog(LOG1, FL(" RSN IE failed to populate"));
3821 }
3822
3823 EXIT();
3824 return 0;
3825}
3826
3827static
3828int iw_get_genie(struct net_device *dev,
3829 struct iw_request_info *info,
3830 union iwreq_data *wrqu, char *extra)
3831{
3832 int ret;
3833
3834 cds_ssr_protect(__func__);
3835 ret = __iw_get_genie(dev, info, wrqu, extra);
3836 cds_ssr_unprotect(__func__);
3837
3838 return ret;
3839}
3840
3841static
3842int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3843 struct iw_request_info *info,
3844 union iwreq_data *wrqu, char *extra)
3845{
3846 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3847 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
3848 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3849 hdd_context_t *hdd_ctx;
3850 int ret;
3851
Jeff Johnson02050312016-02-11 18:40:28 -08003852 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003853
3854 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3855 ret = wlan_hdd_validate_context(hdd_ctx);
3856 if (0 != ret)
3857 return ret;
3858
3859 hddLog(LOG1, FL("get_WPSPBCProbeReqIEs ioctl"));
3860 memset((void *)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
3861
3862 WPSPBCProbeReqIEs.probeReqIELen =
3863 pHddApCtx->WPSPBCProbeReq.probeReqIELen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303864 qdf_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865 pHddApCtx->WPSPBCProbeReq.probeReqIE,
3866 WPSPBCProbeReqIEs.probeReqIELen);
Anurag Chouhanc5548422016-02-24 18:33:27 +05303867 qdf_copy_macaddr(&WPSPBCProbeReqIEs.macaddr,
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003868 &pHddApCtx->WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003869 if (copy_to_user(wrqu->data.pointer,
3870 (void *)&WPSPBCProbeReqIEs,
3871 sizeof(WPSPBCProbeReqIEs))) {
3872 hddLog(LOG1, FL("failed to copy data to user buffer"));
3873 return -EFAULT;
3874 }
3875 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003876 hdd_info("Macaddress : " MAC_ADDRESS_STR,
3877 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003878 up(&pHddApCtx->semWpsPBCOverlapInd);
3879 EXIT();
3880 return 0;
3881}
3882
3883static
3884int iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3885 struct iw_request_info *info,
3886 union iwreq_data *wrqu, char *extra)
3887{
3888 int ret;
3889
3890 cds_ssr_protect(__func__);
3891 ret = __iw_get_wpspbc_probe_req_ies(dev, info, wrqu, extra);
3892 cds_ssr_unprotect(__func__);
3893
3894 return ret;
3895}
3896
3897/**
3898 * __iw_set_auth_hostap() -
3899 * This function sets the auth type received from the wpa_supplicant.
3900 *
3901 * @dev: pointer to the net device.
3902 * @info: pointer to the iw_request_info.
3903 * @wrqu: pointer to the iwreq_data.
3904 * @extra: pointer to the data.
3905 *
3906 * Return: 0 for success, non zero for failure
3907 */
3908static
3909int __iw_set_auth_hostap(struct net_device *dev, struct iw_request_info *info,
3910 union iwreq_data *wrqu, char *extra)
3911{
3912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3913 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3914 hdd_context_t *hdd_ctx;
3915 int ret;
3916
Jeff Johnson651f9f22016-02-11 18:16:11 -08003917 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003918
3919 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3920 ret = wlan_hdd_validate_context(hdd_ctx);
3921 if (0 != ret)
3922 return ret;
3923
3924 switch (wrqu->param.flags & IW_AUTH_INDEX) {
3925 case IW_AUTH_TKIP_COUNTERMEASURES:
3926 {
3927 if (wrqu->param.value) {
3928 hddLog(LOG2,
3929 "Counter Measure started %d", wrqu->param.value);
3930 pWextState->mTKIPCounterMeasures =
3931 TKIP_COUNTER_MEASURE_STARTED;
3932 } else {
3933 hddLog(LOG2,
3934 "Counter Measure stopped=%d", wrqu->param.value);
3935 pWextState->mTKIPCounterMeasures =
3936 TKIP_COUNTER_MEASURE_STOPED;
3937 }
3938
3939 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
3940 wrqu->param.
3941 value);
3942 }
3943 break;
3944
3945 default:
3946
3947 hddLog(LOGW, FL("called with unsupported auth type %d"),
3948 wrqu->param.flags & IW_AUTH_INDEX);
3949 break;
3950 }
3951
3952 EXIT();
3953 return 0;
3954}
3955
3956/**
3957 * iw_set_auth_hostap() - Wrapper function to protect __iw_set_auth_hostap
3958 * from the SSR.
3959 *
3960 * @dev - Pointer to the net device.
3961 * @info - Pointer to the iw_request_info.
3962 * @wrqu - Pointer to the iwreq_data.
3963 * @extra - Pointer to the data.
3964 *
3965 * Return: 0 for success, non zero for failure.
3966 */
3967static int
3968iw_set_auth_hostap(struct net_device *dev,
3969 struct iw_request_info *info,
3970 union iwreq_data *wrqu, char *extra)
3971{
3972 int ret;
3973
3974 cds_ssr_protect(__func__);
3975 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
3976 cds_ssr_unprotect(__func__);
3977
3978 return ret;
3979}
3980
3981/**
3982 * __iw_set_ap_encodeext() - set ap encode
3983 *
3984 * @dev - Pointer to the net device.
3985 * @info - Pointer to the iw_request_info.
3986 * @wrqu - Pointer to the iwreq_data.
3987 * @extra - Pointer to the data.
3988 *
3989 * Return: 0 for success, non zero for failure.
3990 */
3991static int __iw_set_ap_encodeext(struct net_device *dev,
3992 struct iw_request_info *info,
3993 union iwreq_data *wrqu, char *extra)
3994{
3995 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3996#ifndef WLAN_FEATURE_MBSSID
3997 v_CONTEXT_t cds_ctx;
3998#endif
3999 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4000 hdd_context_t *hdd_ctx;
4001 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304002 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004003 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4004 int key_index;
4005 struct iw_point *encoding = &wrqu->encoding;
4006 tCsrRoamSetKey setKey;
4007 int i;
4008
Jeff Johnson651f9f22016-02-11 18:16:11 -08004009 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004010
4011 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4012 ret = wlan_hdd_validate_context(hdd_ctx);
4013 if (0 != ret)
4014 return ret;
4015
4016#ifndef WLAN_FEATURE_MBSSID
4017 cds_ctx = hdd_ctx->pcds_context;
4018 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304019 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004020 "%s: pVosContext is NULL", __func__);
4021 return -EINVAL;
4022 }
4023#endif
4024
4025 key_index = encoding->flags & IW_ENCODE_INDEX;
4026
4027 if (key_index > 0) {
4028 /*Convert from 1-based to 0-based keying */
4029 key_index--;
4030 }
4031 if (!ext->key_len)
4032 return ret;
4033
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304034 qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004035
4036 setKey.keyId = key_index;
4037 setKey.keyLength = ext->key_len;
4038
4039 if (ext->key_len <= CSR_MAX_KEY_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304040 qdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004041 }
4042
4043 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4044 /*Key direction for group is RX only */
4045 setKey.keyDirection = eSIR_RX_ONLY;
Anurag Chouhanc5548422016-02-24 18:33:27 +05304046 qdf_set_macaddr_broadcast(&setKey.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004047 } else {
4048
4049 setKey.keyDirection = eSIR_TX_RX;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304050 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304051 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004052 }
4053 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
4054 setKey.keyDirection = eSIR_TX_DEFAULT;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304055 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304056 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004057 }
4058
4059 /*For supplicant pae role is zero */
4060 setKey.paeRole = 0;
4061
4062 switch (ext->alg) {
4063 case IW_ENCODE_ALG_NONE:
4064 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4065 break;
4066
4067 case IW_ENCODE_ALG_WEP:
4068 setKey.encType =
4069 (ext->key_len ==
4070 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4071 pHddApCtx->uPrivacy = 1;
4072 hddLog(LOG1, FL("uPrivacy=%d"), pHddApCtx->uPrivacy);
4073 break;
4074
4075 case IW_ENCODE_ALG_TKIP:
4076 {
4077 uint8_t *pKey = &setKey.Key[0];
4078
4079 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4080
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304081 qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082
4083 /*Supplicant sends the 32bytes key in this order
4084
4085 |--------------|----------|----------|
4086 | Tk1 |TX-MIC | RX Mic |
4087 |||--------------|----------|----------|
4088 <---16bytes---><--8bytes--><--8bytes-->
4089
4090 */
4091 /*Sme expects the 32 bytes key to be in the below order
4092
4093 |--------------|----------|----------|
4094 | Tk1 |RX-MIC | TX Mic |
4095 |||--------------|----------|----------|
4096 <---16bytes---><--8bytes--><--8bytes-->
4097 */
4098 /* Copy the Temporal Key 1 (TK1) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304099 qdf_mem_copy(pKey, ext->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004100
4101 /*Copy the rx mic first */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304102 qdf_mem_copy(&pKey[16], &ext->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004103
4104 /*Copy the tx mic */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304105 qdf_mem_copy(&pKey[24], &ext->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004106
4107 }
4108 break;
4109
4110 case IW_ENCODE_ALG_CCMP:
4111 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4112 break;
4113
4114 default:
4115 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4116 break;
4117 }
4118
4119 hddLog(LOG1, FL(":EncryptionType:%d key_len:%d, KeyId:%d"),
4120 setKey.encType, setKey.keyLength, setKey.keyId);
4121 for (i = 0; i < ext->key_len; i++)
4122 hddLog(LOG1, "%02x", setKey.Key[i]);
4123
4124#ifdef WLAN_FEATURE_MBSSID
4125 vstatus =
4126 wlansap_set_key_sta(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
4127 &setKey);
4128#else
4129 vstatus = wlansap_set_key_sta(cds_ctx, &setKey);
4130#endif
4131
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304132 if (vstatus != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004133 hddLog(LOGE, FL("wlansap_set_key_sta failed, status= %d"),
4134 vstatus);
4135 ret = -EINVAL;
4136 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304137 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138 return ret;
4139}
4140
4141/**
4142 * iw_set_ap_encodeext() - Wrapper function to protect __iw_set_ap_encodeext
4143 * from the SSR.
4144 *
4145 * @dev - Pointer to the net device.
4146 * @info - Pointer to the iw_request_info.
4147 * @wrqu - Pointer to the iwreq_data.
4148 * @extra - Pointer to the data.
4149 *
4150 * Return: 0 for success, non zero for failure.
4151 */
4152static int iw_set_ap_encodeext(struct net_device *dev,
4153 struct iw_request_info *info,
4154 union iwreq_data *wrqu, char *extra)
4155{
4156 int ret;
4157
4158 cds_ssr_protect(__func__);
4159 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
4160 cds_ssr_unprotect(__func__);
4161
4162 return ret;
4163}
4164
4165/**
4166 * __iw_set_ap_mlme() - set ap mlme
4167 * @dev: pointer to net_device
4168 * @info: pointer to iw_request_info
4169 * @wrqu; pointer to iwreq_data
4170 * @extra: extra
4171 *
4172 * Return; 0 on success, error number otherwise
4173 */
4174static int __iw_set_ap_mlme(struct net_device *dev,
4175 struct iw_request_info *info,
4176 union iwreq_data *wrqu, char *extra)
4177{
Jeff Johnson651f9f22016-02-11 18:16:11 -08004178 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004179 return 0;
4180}
4181
4182/**
4183 * iw_set_ap_mlme() - SSR wrapper for __iw_set_ap_mlme
4184 * @dev: pointer to net_device
4185 * @info: pointer to iw_request_info
4186 * @wrqu; pointer to iwreq_data
4187 * @extra: extra
4188 *
4189 * Return; 0 on success, error number otherwise
4190 */
4191static int iw_set_ap_mlme(struct net_device *dev,
4192 struct iw_request_info *info,
4193 union iwreq_data *wrqu,
4194 char *extra)
4195{
4196 int ret;
4197
4198 cds_ssr_protect(__func__);
4199 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
4200 cds_ssr_unprotect(__func__);
4201
4202 return ret;
4203}
4204
4205/**
4206 * __iw_get_ap_rts_threshold() - get ap rts threshold
4207 * @dev - Pointer to the net device.
4208 * @info - Pointer to the iw_request_info.
4209 * @wrqu - Pointer to the iwreq_data.
4210 * @extra - Pointer to the data.
4211 *
4212 * Return: 0 for success, non zero for failure.
4213 */
4214static int __iw_get_ap_rts_threshold(struct net_device *dev,
4215 struct iw_request_info *info,
4216 union iwreq_data *wrqu, char *extra) {
4217
4218 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4219 int ret;
4220 hdd_context_t *hdd_ctx;
4221
Jeff Johnson651f9f22016-02-11 18:16:11 -08004222 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004223
4224 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4225 ret = wlan_hdd_validate_context(hdd_ctx);
4226 if (0 != ret)
4227 return ret;
4228 ret = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
4229
4230 return ret;
4231}
4232
4233/**
4234 * iw_get_ap_rts_threshold() - Wrapper function to protect
4235 * __iw_get_ap_rts_threshold from the SSR.
4236 * @dev - Pointer to the net device.
4237 * @info - Pointer to the iw_request_info.
4238 * @wrqu - Pointer to the iwreq_data.
4239 * @extra - Pointer to the data.
4240 *
4241 * Return: 0 for success, non zero for failure.
4242 */
4243static int iw_get_ap_rts_threshold(struct net_device *dev,
4244 struct iw_request_info *info,
4245 union iwreq_data *wrqu, char *extra)
4246{
4247 int ret;
4248
4249 cds_ssr_protect(__func__);
4250 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
4251 cds_ssr_unprotect(__func__);
4252
4253 return ret;
4254}
4255
4256/**
4257 * __iw_get_ap_frag_threshold() - get ap fragmentation threshold
4258 * @dev - Pointer to the net device.
4259 * @info - Pointer to the iw_request_info.
4260 * @wrqu - Pointer to the iwreq_data.
4261 * @extra - Pointer to the data.
4262 *
4263 * Return: 0 for success, non zero for failure.
4264 */
4265static int __iw_get_ap_frag_threshold(struct net_device *dev,
4266 struct iw_request_info *info,
4267 union iwreq_data *wrqu, char *extra) {
4268
4269 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4270 hdd_context_t *hdd_ctx;
4271 int ret = 0;
4272
Jeff Johnson651f9f22016-02-11 18:16:11 -08004273 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004274
4275 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4276 ret = wlan_hdd_validate_context(hdd_ctx);
4277 if (0 != ret)
4278 return ret;
4279
4280 ret = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
4281
4282 return ret;
4283}
4284
4285/**
4286 * iw_get_ap_frag_threshold() - Wrapper function to protect
4287 * __iw_get_ap_frag_threshold from the SSR.
4288 * @dev - Pointer to the net device.
4289 * @info - Pointer to the iw_request_info.
4290 * @wrqu - Pointer to the iwreq_data.
4291 * @extra - Pointer to the data.
4292 *
4293 * Return: 0 for success, non zero for failure.
4294 */
4295static int iw_get_ap_frag_threshold(struct net_device *dev,
4296 struct iw_request_info *info,
4297 union iwreq_data *wrqu, char *extra)
4298{
4299 int ret;
4300
4301 cds_ssr_protect(__func__);
4302 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
4303 cds_ssr_unprotect(__func__);
4304
4305 return ret;
4306}
4307
4308/**
4309 * __iw_get_ap_freq() - get ap frequency
4310 * @dev - Pointer to the net device.
4311 * @info - Pointer to the iw_request_info.
4312 * @wrqu - Pointer to the iwreq_data.
4313 * @extra - Pointer to the data.
4314 *
4315 * Return: 0 for success, non zero for failure.
4316 */
4317static int __iw_get_ap_freq(struct net_device *dev,
4318 struct iw_request_info *info, struct iw_freq *fwrq,
4319 char *extra) {
4320 uint32_t status = false, channel = 0, freq = 0;
4321 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4322 hdd_context_t *hdd_ctx;
4323 tHalHandle hHal;
4324 hdd_hostapd_state_t *pHostapdState;
4325 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4326 int ret;
4327
Jeff Johnson651f9f22016-02-11 18:16:11 -08004328 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004329
4330 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4331 ret = wlan_hdd_validate_context(hdd_ctx);
4332 if (0 != ret)
4333 return ret;
4334
4335 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4336 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
4337
4338 if (pHostapdState->bssState == BSS_STOP) {
4339 if (sme_cfg_get_int(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304340 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004341 return -EIO;
4342 } else {
4343 status = hdd_wlan_get_freq(channel, &freq);
4344 if (true == status) {
4345 /* Set Exponent parameter as 6 (MHZ) in struct
4346 * iw_freq * iwlist & iwconfig command
4347 * shows frequency into proper
4348 * format (2.412 GHz instead of 246.2 MHz)
4349 */
4350 fwrq->m = freq;
4351 fwrq->e = MHZ;
4352 }
4353 }
4354 } else {
4355 channel = pHddApCtx->operatingChannel;
4356 status = hdd_wlan_get_freq(channel, &freq);
4357 if (true == status) {
4358 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
4359 * iwlist & iwconfig command shows frequency into proper
4360 * format (2.412 GHz instead of 246.2 MHz)*/
4361 fwrq->m = freq;
4362 fwrq->e = MHZ;
4363 }
4364 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304365 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004366 return 0;
4367}
4368
4369/**
4370 * iw_get_ap_freq() - Wrapper function to protect
4371 * __iw_get_ap_freq from the SSR.
4372 * @dev - Pointer to the net device.
4373 * @info - Pointer to the iw_request_info.
4374 * @wrqu - Pointer to the iwreq_data.
4375 * @extra - Pointer to the data.
4376 *
4377 * Return: 0 for success, non zero for failure.
4378 */
4379static int iw_get_ap_freq(struct net_device *dev,
4380 struct iw_request_info *info,
4381 struct iw_freq *wrqu, char *extra)
4382{
4383 int ret;
4384
4385 cds_ssr_protect(__func__);
4386 ret = __iw_get_ap_freq(dev, info, wrqu, extra);
4387 cds_ssr_unprotect(__func__);
4388
4389 return ret;
4390}
4391
4392/**
4393 * __iw_get_mode() - get mode
4394 * @dev - Pointer to the net device.
4395 * @info - Pointer to the iw_request_info.
4396 * @wrqu - Pointer to the iwreq_data.
4397 * @extra - Pointer to the data.
4398 *
4399 * Return: 0 for success, non zero for failure.
4400 */
4401static int __iw_get_mode(struct net_device *dev,
4402 struct iw_request_info *info,
4403 union iwreq_data *wrqu, char *extra) {
4404
4405 hdd_adapter_t *adapter;
4406 hdd_context_t *hdd_ctx;
4407 int ret;
4408
Jeff Johnson651f9f22016-02-11 18:16:11 -08004409 ENTER_DEV(dev);
4410
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004411 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4412 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4413 ret = wlan_hdd_validate_context(hdd_ctx);
4414 if (0 != ret)
4415 return ret;
4416
4417 wrqu->mode = IW_MODE_MASTER;
4418
4419 return ret;
4420}
4421
4422/**
4423 * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR.
4424 * @dev - Pointer to the net device.
4425 * @info - Pointer to the iw_request_info.
4426 * @wrqu - Pointer to the iwreq_data.
4427 * @extra - Pointer to the data.
4428 *
4429 * Return: 0 for success, non zero for failure.
4430 */
4431static int iw_get_mode(struct net_device *dev,
4432 struct iw_request_info *info,
4433 union iwreq_data *wrqu, char *extra)
4434{
4435 int ret;
4436
4437 cds_ssr_protect(__func__);
4438 ret = __iw_get_mode(dev, info, wrqu, extra);
4439 cds_ssr_unprotect(__func__);
4440
4441 return ret;
4442}
4443
4444static int
4445__iw_softap_setwpsie(struct net_device *dev,
4446 struct iw_request_info *info,
4447 union iwreq_data *wrqu, char *extra)
4448{
4449 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4450#ifndef WLAN_FEATURE_MBSSID
4451 v_CONTEXT_t cds_ctx;
4452#endif
4453 hdd_hostapd_state_t *pHostapdState;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304454 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004455 uint8_t *wps_genie;
4456 uint8_t *fwps_genie;
4457 uint8_t *pos;
4458 tpSap_WPSIE pSap_WPSIe;
4459 uint8_t WPSIeType;
4460 uint16_t length;
4461 struct iw_point s_priv_data;
4462 hdd_context_t *hdd_ctx;
4463 int ret;
4464
Jeff Johnson02050312016-02-11 18:40:28 -08004465 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004466
Mukul Sharmaa42b0622015-11-02 19:57:31 +05304467 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304468 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharmaa42b0622015-11-02 19:57:31 +05304469 FL("permission check failed"));
4470 return -EPERM;
4471 }
4472
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004473 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4474 ret = wlan_hdd_validate_context(hdd_ctx);
4475 if (0 != ret)
4476 return ret;
4477
4478#ifndef WLAN_FEATURE_MBSSID
4479 cds_ctx = hdd_ctx->pcds_context;
4480 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304481 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004482 "%s: HDD context is not valid ", __func__);
4483 return -EINVAL;
4484 }
4485#endif
4486
4487 /* helper function to get iwreq_data with compat handling. */
4488 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
4489 return -EINVAL;
4490 }
4491
4492 if ((NULL == s_priv_data.pointer) ||
4493 (s_priv_data.length < QCSAP_MAX_WSC_IE)) {
4494 return -EINVAL;
4495 }
4496
4497 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
4498 s_priv_data.length);
4499
4500 if (NULL == wps_genie) {
4501 hddLog(LOG1, FL("failed to alloc mem and copy data"));
4502 return -EFAULT;
4503 }
4504
4505 fwps_genie = wps_genie;
4506
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304507 pSap_WPSIe = qdf_mem_malloc(sizeof(tSap_WPSIE));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004508 if (NULL == pSap_WPSIe) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304509 hddLog(LOGE, "QDF unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004510 kfree(fwps_genie);
4511 return -ENOMEM;
4512 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304513 qdf_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004514
4515 hddLog(LOG1, FL("WPS IE type[0x%X] IE[0x%X], LEN[%d]"),
4516 wps_genie[0], wps_genie[1], wps_genie[2]);
4517 WPSIeType = wps_genie[0];
4518 if (wps_genie[0] == eQC_WPS_BEACON_IE) {
4519 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
4520 wps_genie = wps_genie + 1;
4521 switch (wps_genie[0]) {
4522 case DOT11F_EID_WPA:
4523 if (wps_genie[1] < 2 + 4) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304524 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004525 kfree(fwps_genie);
4526 return -EINVAL;
4527 } else if (memcmp(&wps_genie[2],
4528 "\x00\x50\xf2\x04", 4) == 0) {
4529 hddLog(LOG1, FL("Set WPS BEACON IE(len %d)"),
4530 wps_genie[1] + 2);
4531 pos = &wps_genie[6];
4532 while (((size_t) pos -
4533 (size_t) &wps_genie[6]) <
4534 (wps_genie[1] - 4)) {
4535 switch ((uint16_t) (*pos << 8) |
4536 *(pos + 1)) {
4537 case HDD_WPS_ELEM_VERSION:
4538 pos += 4;
4539 pSap_WPSIe->sapwpsie.
4540 sapWPSBeaconIE.Version =
4541 *pos;
4542 hddLog(LOG1, "WPS version %d",
4543 pSap_WPSIe->sapwpsie.
4544 sapWPSBeaconIE.Version);
4545 pSap_WPSIe->sapwpsie.
4546 sapWPSBeaconIE.
4547 FieldPresent |=
4548 WPS_BEACON_VER_PRESENT;
4549 pos += 1;
4550 break;
4551
4552 case HDD_WPS_ELEM_WPS_STATE:
4553 pos += 4;
4554 pSap_WPSIe->sapwpsie.
4555 sapWPSBeaconIE.wpsState =
4556 *pos;
4557 hddLog(LOG1, "WPS State %d",
4558 pSap_WPSIe->sapwpsie.
4559 sapWPSBeaconIE.wpsState);
4560 pSap_WPSIe->sapwpsie.
4561 sapWPSBeaconIE.
4562 FieldPresent |=
4563 WPS_BEACON_STATE_PRESENT;
4564 pos += 1;
4565 break;
4566 case HDD_WPS_ELEM_APSETUPLOCK:
4567 pos += 4;
4568 pSap_WPSIe->sapwpsie.
4569 sapWPSBeaconIE.
4570 APSetupLocked = *pos;
4571 hddLog(LOG1, "AP setup lock %d",
4572 pSap_WPSIe->sapwpsie.
4573 sapWPSBeaconIE.
4574 APSetupLocked);
4575 pSap_WPSIe->sapwpsie.
4576 sapWPSBeaconIE.
4577 FieldPresent |=
4578 WPS_BEACON_APSETUPLOCK_PRESENT;
4579 pos += 1;
4580 break;
4581 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4582 pos += 4;
4583 pSap_WPSIe->sapwpsie.
4584 sapWPSBeaconIE.
4585 SelectedRegistra = *pos;
4586 hddLog(LOG1,
4587 "Selected Registra %d",
4588 pSap_WPSIe->sapwpsie.
4589 sapWPSBeaconIE.
4590 SelectedRegistra);
4591 pSap_WPSIe->sapwpsie.
4592 sapWPSBeaconIE.
4593 FieldPresent |=
4594 WPS_BEACON_SELECTEDREGISTRA_PRESENT;
4595 pos += 1;
4596 break;
4597 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4598 pos += 4;
4599 pSap_WPSIe->sapwpsie.
4600 sapWPSBeaconIE.
4601 DevicePasswordID =
4602 (*pos << 8) | *(pos + 1);
4603 hddLog(LOG1, "Password ID: %x",
4604 pSap_WPSIe->sapwpsie.
4605 sapWPSBeaconIE.
4606 DevicePasswordID);
4607 pSap_WPSIe->sapwpsie.
4608 sapWPSBeaconIE.
4609 FieldPresent |=
4610 WPS_BEACON_DEVICEPASSWORDID_PRESENT;
4611 pos += 2;
4612 break;
4613 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4614 pos +=
4615 4;
4616 pSap_WPSIe->sapwpsie.
4617 sapWPSBeaconIE.
4618 SelectedRegistraCfgMethod =
4619 (*pos << 8) | *(pos + 1);
4620 hddLog(LOG1,
4621 "Select Registra Config Methods: %x",
4622 pSap_WPSIe->sapwpsie.
4623 sapWPSBeaconIE.
4624 SelectedRegistraCfgMethod);
4625 pSap_WPSIe->sapwpsie.
4626 sapWPSBeaconIE.
4627 FieldPresent |=
4628 WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
4629 pos += 2;
4630 break;
4631
4632 case HDD_WPS_ELEM_UUID_E:
4633 pos += 2;
4634 length = *pos << 8 | *(pos + 1);
4635 pos += 2;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304636 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004637 sapwpsie.
4638 sapWPSBeaconIE.
4639 UUID_E, pos,
4640 length);
4641 pSap_WPSIe->sapwpsie.
4642 sapWPSBeaconIE.
4643 FieldPresent |=
4644 WPS_BEACON_UUIDE_PRESENT;
4645 pos += length;
4646 break;
4647 case HDD_WPS_ELEM_RF_BANDS:
4648 pos += 4;
4649 pSap_WPSIe->sapwpsie.
4650 sapWPSBeaconIE.RFBand =
4651 *pos;
4652 hddLog(LOG1, "RF band: %d",
4653 pSap_WPSIe->sapwpsie.
4654 sapWPSBeaconIE.RFBand);
4655 pSap_WPSIe->sapwpsie.
4656 sapWPSBeaconIE.
4657 FieldPresent |=
4658 WPS_BEACON_RF_BANDS_PRESENT;
4659 pos += 1;
4660 break;
4661
4662 default:
4663 hddLog(LOGW,
4664 "UNKNOWN TLV in WPS IE(%x)",
4665 (*pos << 8 |
4666 *(pos + 1)));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304667 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004668 kfree(fwps_genie);
4669 return -EINVAL;
4670 }
4671 }
4672 } else {
4673 hddLog(LOGE, FL("WPS IE Mismatch %X"),
4674 wps_genie[0]);
4675 }
4676 break;
4677
4678 default:
4679 hddLog(LOGE, FL("Set UNKNOWN IE %X"), wps_genie[0]);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304680 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004681 kfree(fwps_genie);
4682 return 0;
4683 }
4684 } else if (wps_genie[0] == eQC_WPS_PROBE_RSP_IE) {
4685 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
4686 wps_genie = wps_genie + 1;
4687 switch (wps_genie[0]) {
4688 case DOT11F_EID_WPA:
4689 if (wps_genie[1] < 2 + 4) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304690 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004691 kfree(fwps_genie);
4692 return -EINVAL;
4693 } else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4)
4694 == 0) {
4695 hddLog(LOG1, FL("Set WPS PROBE RSP IE(len %d)"),
4696 wps_genie[1] + 2);
4697 pos = &wps_genie[6];
4698 while (((size_t) pos -
4699 (size_t) &wps_genie[6]) <
4700 (wps_genie[1] - 4)) {
4701 switch ((uint16_t) (*pos << 8) |
4702 *(pos + 1)) {
4703 case HDD_WPS_ELEM_VERSION:
4704 pos += 4;
4705 pSap_WPSIe->sapwpsie.
4706 sapWPSProbeRspIE.Version =
4707 *pos;
4708 hddLog(LOG1, "WPS version %d",
4709 pSap_WPSIe->sapwpsie.
4710 sapWPSProbeRspIE.
4711 Version);
4712 pSap_WPSIe->sapwpsie.
4713 sapWPSProbeRspIE.
4714 FieldPresent |=
4715 WPS_PROBRSP_VER_PRESENT;
4716 pos += 1;
4717 break;
4718
4719 case HDD_WPS_ELEM_WPS_STATE:
4720 pos += 4;
4721 pSap_WPSIe->sapwpsie.
4722 sapWPSProbeRspIE.wpsState =
4723 *pos;
4724 hddLog(LOG1, "WPS State %d",
4725 pSap_WPSIe->sapwpsie.
4726 sapWPSProbeRspIE.
4727 wpsState);
4728 pSap_WPSIe->sapwpsie.
4729 sapWPSProbeRspIE.
4730 FieldPresent |=
4731 WPS_PROBRSP_STATE_PRESENT;
4732 pos += 1;
4733 break;
4734 case HDD_WPS_ELEM_APSETUPLOCK:
4735 pos += 4;
4736 pSap_WPSIe->sapwpsie.
4737 sapWPSProbeRspIE.
4738 APSetupLocked = *pos;
4739 hddLog(LOG1, "AP setup lock %d",
4740 pSap_WPSIe->sapwpsie.
4741 sapWPSProbeRspIE.
4742 APSetupLocked);
4743 pSap_WPSIe->sapwpsie.
4744 sapWPSProbeRspIE.
4745 FieldPresent |=
4746 WPS_PROBRSP_APSETUPLOCK_PRESENT;
4747 pos += 1;
4748 break;
4749 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4750 pos += 4;
4751 pSap_WPSIe->sapwpsie.
4752 sapWPSProbeRspIE.
4753 SelectedRegistra = *pos;
4754 hddLog(LOG1,
4755 "Selected Registra %d",
4756 pSap_WPSIe->sapwpsie.
4757 sapWPSProbeRspIE.
4758 SelectedRegistra);
4759 pSap_WPSIe->sapwpsie.
4760 sapWPSProbeRspIE.
4761 FieldPresent |=
4762 WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
4763 pos += 1;
4764 break;
4765 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4766 pos += 4;
4767 pSap_WPSIe->sapwpsie.
4768 sapWPSProbeRspIE.
4769 DevicePasswordID =
4770 (*pos << 8) | *(pos + 1);
4771 hddLog(LOG1, "Password ID: %d",
4772 pSap_WPSIe->sapwpsie.
4773 sapWPSProbeRspIE.
4774 DevicePasswordID);
4775 pSap_WPSIe->sapwpsie.
4776 sapWPSProbeRspIE.
4777 FieldPresent |=
4778 WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
4779 pos += 2;
4780 break;
4781 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4782 pos +=
4783 4;
4784 pSap_WPSIe->sapwpsie.
4785 sapWPSProbeRspIE.
4786 SelectedRegistraCfgMethod =
4787 (*pos << 8) | *(pos + 1);
4788 hddLog(LOG1,
4789 "Select Registra Config Methods: %x",
4790 pSap_WPSIe->sapwpsie.
4791 sapWPSProbeRspIE.
4792 SelectedRegistraCfgMethod);
4793 pSap_WPSIe->sapwpsie.
4794 sapWPSProbeRspIE.
4795 FieldPresent |=
4796 WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
4797 pos += 2;
4798 break;
4799 case HDD_WPS_ELEM_RSP_TYPE:
4800 pos += 4;
4801 pSap_WPSIe->sapwpsie.
4802 sapWPSProbeRspIE.
4803 ResponseType = *pos;
4804 hddLog(LOG1,
4805 "Config Methods: %d",
4806 pSap_WPSIe->sapwpsie.
4807 sapWPSProbeRspIE.
4808 ResponseType);
4809 pSap_WPSIe->sapwpsie.
4810 sapWPSProbeRspIE.
4811 FieldPresent |=
4812 WPS_PROBRSP_RESPONSETYPE_PRESENT;
4813 pos += 1;
4814 break;
4815 case HDD_WPS_ELEM_UUID_E:
4816 pos += 2;
4817 length = *pos << 8 | *(pos + 1);
4818 pos += 2;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304819 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004820 sapwpsie.
4821 sapWPSProbeRspIE.
4822 UUID_E, pos,
4823 length);
4824 pSap_WPSIe->sapwpsie.
4825 sapWPSProbeRspIE.
4826 FieldPresent |=
4827 WPS_PROBRSP_UUIDE_PRESENT;
4828 pos += length;
4829 break;
4830
4831 case HDD_WPS_ELEM_MANUFACTURER:
4832 pos += 2;
4833 length = *pos << 8 | *(pos + 1);
4834 pos += 2;
4835 pSap_WPSIe->sapwpsie.
4836 sapWPSProbeRspIE.
4837 Manufacture.num_name =
4838 length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304839 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004840 sapwpsie.
4841 sapWPSProbeRspIE.
4842 Manufacture.name,
4843 pos, length);
4844 pSap_WPSIe->sapwpsie.
4845 sapWPSProbeRspIE.
4846 FieldPresent |=
4847 WPS_PROBRSP_MANUFACTURE_PRESENT;
4848 pos += length;
4849 break;
4850
4851 case HDD_WPS_ELEM_MODEL_NAME:
4852 pos += 2;
4853 length = *pos << 8 | *(pos + 1);
4854 pos += 2;
4855 pSap_WPSIe->sapwpsie.
4856 sapWPSProbeRspIE.ModelName.
4857 num_text = length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304858 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004859 sapwpsie.
4860 sapWPSProbeRspIE.
4861 ModelName.text,
4862 pos, length);
4863 pSap_WPSIe->sapwpsie.
4864 sapWPSProbeRspIE.
4865 FieldPresent |=
4866 WPS_PROBRSP_MODELNAME_PRESENT;
4867 pos += length;
4868 break;
4869 case HDD_WPS_ELEM_MODEL_NUM:
4870 pos += 2;
4871 length = *pos << 8 | *(pos + 1);
4872 pos += 2;
4873 pSap_WPSIe->sapwpsie.
4874 sapWPSProbeRspIE.
4875 ModelNumber.num_text =
4876 length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304877 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878 sapwpsie.
4879 sapWPSProbeRspIE.
4880 ModelNumber.text,
4881 pos, length);
4882 pSap_WPSIe->sapwpsie.
4883 sapWPSProbeRspIE.
4884 FieldPresent |=
4885 WPS_PROBRSP_MODELNUMBER_PRESENT;
4886 pos += length;
4887 break;
4888 case HDD_WPS_ELEM_SERIAL_NUM:
4889 pos += 2;
4890 length = *pos << 8 | *(pos + 1);
4891 pos += 2;
4892 pSap_WPSIe->sapwpsie.
4893 sapWPSProbeRspIE.
4894 SerialNumber.num_text =
4895 length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304896 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004897 sapwpsie.
4898 sapWPSProbeRspIE.
4899 SerialNumber.text,
4900 pos, length);
4901 pSap_WPSIe->sapwpsie.
4902 sapWPSProbeRspIE.
4903 FieldPresent |=
4904 WPS_PROBRSP_SERIALNUMBER_PRESENT;
4905 pos += length;
4906 break;
4907 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
4908 pos += 4;
4909 pSap_WPSIe->sapwpsie.
4910 sapWPSProbeRspIE.
4911 PrimaryDeviceCategory =
4912 (*pos << 8 | *(pos + 1));
4913 hddLog(LOG1,
4914 "primary dev category: %d",
4915 pSap_WPSIe->sapwpsie.
4916 sapWPSProbeRspIE.
4917 PrimaryDeviceCategory);
4918 pos += 2;
4919
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304920 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004921 sapwpsie.
4922 sapWPSProbeRspIE.
4923 PrimaryDeviceOUI,
4924 pos,
4925 HDD_WPS_DEVICE_OUI_LEN);
4926 hddLog(LOG1,
4927 "primary dev oui: %02x, %02x, %02x, %02x",
4928 pos[0], pos[1], pos[2],
4929 pos[3]);
4930 pos += 4;
4931 pSap_WPSIe->sapwpsie.
4932 sapWPSProbeRspIE.
4933 DeviceSubCategory =
4934 (*pos << 8 | *(pos + 1));
4935 hddLog(LOG1,
4936 "primary dev sub category: %d",
4937 pSap_WPSIe->sapwpsie.
4938 sapWPSProbeRspIE.
4939 DeviceSubCategory);
4940 pos += 2;
4941 pSap_WPSIe->sapwpsie.
4942 sapWPSProbeRspIE.
4943 FieldPresent |=
4944 WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
4945 break;
4946 case HDD_WPS_ELEM_DEVICE_NAME:
4947 pos += 2;
4948 length = *pos << 8 | *(pos + 1);
4949 pos += 2;
4950 pSap_WPSIe->sapwpsie.
4951 sapWPSProbeRspIE.DeviceName.
4952 num_text = length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304953 qdf_mem_copy(pSap_WPSIe->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004954 sapwpsie.
4955 sapWPSProbeRspIE.
4956 DeviceName.text,
4957 pos, length);
4958 pos += length;
4959 pSap_WPSIe->sapwpsie.
4960 sapWPSProbeRspIE.
4961 FieldPresent |=
4962 WPS_PROBRSP_DEVICENAME_PRESENT;
4963 break;
4964 case HDD_WPS_ELEM_CONFIG_METHODS:
4965 pos += 4;
4966 pSap_WPSIe->sapwpsie.
4967 sapWPSProbeRspIE.
4968 ConfigMethod =
4969 (*pos << 8) | *(pos + 1);
4970 hddLog(LOG1,
4971 "Config Methods: %d",
4972 pSap_WPSIe->sapwpsie.
4973 sapWPSProbeRspIE.
4974 SelectedRegistraCfgMethod);
4975 pos += 2;
4976 pSap_WPSIe->sapwpsie.
4977 sapWPSProbeRspIE.
4978 FieldPresent |=
4979 WPS_PROBRSP_CONFIGMETHODS_PRESENT;
4980 break;
4981
4982 case HDD_WPS_ELEM_RF_BANDS:
4983 pos += 4;
4984 pSap_WPSIe->sapwpsie.
4985 sapWPSProbeRspIE.RFBand =
4986 *pos;
4987 hddLog(LOG1, "RF band: %d",
4988 pSap_WPSIe->sapwpsie.
4989 sapWPSProbeRspIE.RFBand);
4990 pos += 1;
4991 pSap_WPSIe->sapwpsie.
4992 sapWPSProbeRspIE.
4993 FieldPresent |=
4994 WPS_PROBRSP_RF_BANDS_PRESENT;
4995 break;
4996 } /* switch */
4997 }
4998 } else {
4999 hddLog(LOGE,
5000 FL("WPS IE Mismatch %X"), wps_genie[0]);
5001 }
5002
5003 } /* switch */
5004 }
5005#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305006 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005007 wlansap_set_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
5008 pSap_WPSIe);
5009#else
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305010 qdf_ret_status = wlansap_set_wps_ie(p_cds_context, pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005011#endif
5012 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5013 if (pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE) {
5014#ifdef WLAN_FEATURE_MBSSID
5015 wlansap_update_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
5016#else
5017 wlansap_update_wps_ie(p_cds_context);
5018#endif
5019 }
5020
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305021 qdf_mem_free(pSap_WPSIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005022 kfree(fwps_genie);
5023 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305024 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005025}
5026
5027static int iw_softap_setwpsie(struct net_device *dev,
5028 struct iw_request_info *info,
5029 union iwreq_data *wrqu,
5030 char *extra)
5031{
5032 int ret;
5033
5034 cds_ssr_protect(__func__);
5035 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
5036 cds_ssr_unprotect(__func__);
5037
5038 return ret;
5039}
5040
5041static int
5042__iw_softap_stopbss(struct net_device *dev,
5043 struct iw_request_info *info,
5044 union iwreq_data *wrqu, char *extra)
5045{
5046 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305047 QDF_STATUS status = QDF_STATUS_SUCCESS;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305048 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005049 hdd_context_t *hdd_ctx;
5050
Jeff Johnson02050312016-02-11 18:40:28 -08005051 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005052
5053 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5054 status = wlan_hdd_validate_context(hdd_ctx);
5055 if (0 != status)
5056 return status;
5057
5058 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
5059 hdd_hostapd_state_t *pHostapdState =
5060 WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5061
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305062 qdf_event_reset(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005063#ifdef WLAN_FEATURE_MBSSID
5064 status =
5065 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
5066#else
5067 status =
5068 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
5069 pcds_context);
5070#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305071 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05305072 qdf_status =
5073 qdf_wait_single_event(&pHostapdState->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305074 qdf_stop_bss_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005075 10000);
5076
Anurag Chouhance0dc992016-02-16 18:18:03 +05305077 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005078 hddLog(LOGE,
5079 FL("wait for single_event failed!!"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305080 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005081 }
5082 }
5083 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08005084 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005085 pHostapdAdapter->sessionId);
5086 }
5087 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305088 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005089}
5090
5091static int iw_softap_stopbss(struct net_device *dev,
5092 struct iw_request_info *info,
5093 union iwreq_data *wrqu,
5094 char *extra)
5095{
5096 int ret;
5097
5098 cds_ssr_protect(__func__);
5099 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
5100 cds_ssr_unprotect(__func__);
5101
5102 return ret;
5103}
5104
5105static int
5106__iw_softap_version(struct net_device *dev,
5107 struct iw_request_info *info,
5108 union iwreq_data *wrqu, char *extra)
5109{
5110 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5111 hdd_context_t *hdd_ctx;
5112 int ret;
5113
Jeff Johnson02050312016-02-11 18:40:28 -08005114 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005115
5116 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5117 ret = wlan_hdd_validate_context(hdd_ctx);
5118 if (0 != ret)
5119 return ret;
5120
5121 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
5122 EXIT();
5123 return 0;
5124}
5125
5126static int iw_softap_version(struct net_device *dev,
5127 struct iw_request_info *info,
5128 union iwreq_data *wrqu,
5129 char *extra)
5130{
5131 int ret;
5132
5133 cds_ssr_protect(__func__);
5134 ret = __iw_softap_version(dev, info, wrqu, extra);
5135 cds_ssr_unprotect(__func__);
5136
5137 return ret;
5138}
5139
5140static
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305141QDF_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, uint8_t *pBuf,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005142 int buf_len) {
5143 uint8_t i;
5144 uint8_t maxSta = 0;
5145 int len = 0;
5146 const char sta_info_header[] = "staId staAddress";
5147 hdd_context_t *hdd_ctx;
5148
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305149 ENTER();
5150
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005151 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305152 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005153 "%s: Adapter is NULL", __func__);
5154 return -EINVAL;
5155 }
5156
5157 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5158 if (0 != wlan_hdd_validate_context(hdd_ctx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305159 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005160
5161 len = scnprintf(pBuf, buf_len, sta_info_header);
5162 pBuf += len;
5163 buf_len -= len;
5164
5165 maxSta = hdd_ctx->config->maxNumberOfPeers;
5166
5167 for (i = 0; i <= maxSta; i++) {
5168 if (pAdapter->aStaInfo[i].isUsed) {
5169 len =
5170 scnprintf(pBuf, buf_len,
5171 "%5d .%02x:%02x:%02x:%02x:%02x:%02x",
5172 pAdapter->aStaInfo[i].ucSTAId,
5173 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
5174 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
5175 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
5176 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
5177 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
5178 pAdapter->aStaInfo[i].macAddrSTA.
5179 bytes[5]);
5180 pBuf += len;
5181 buf_len -= len;
5182 }
5183 if (WE_GET_STA_INFO_SIZE > buf_len) {
5184 break;
5185 }
5186 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305187 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305188 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005189}
5190
5191static int __iw_softap_get_sta_info(struct net_device *dev,
5192 struct iw_request_info *info,
5193 union iwreq_data *wrqu, char *extra)
5194{
5195 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305196 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005197 hdd_context_t *hdd_ctx;
5198 int ret;
5199
Jeff Johnson02050312016-02-11 18:40:28 -08005200 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005201
5202 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5203 ret = wlan_hdd_validate_context(hdd_ctx);
5204 if (0 != ret)
5205 return ret;
5206
5207 status =
5208 hdd_softap_get_sta_info(pHostapdAdapter, extra,
5209 WE_SAP_MAX_STA_INFO);
5210
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305211 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212 hddLog(LOGE, FL("Failed to get sta info: %d"), status);
5213 return -EINVAL;
5214 }
5215 wrqu->data.length = strlen(extra);
5216 EXIT();
5217 return 0;
5218}
5219
5220static int iw_softap_get_sta_info(struct net_device *dev,
5221 struct iw_request_info *info,
5222 union iwreq_data *wrqu,
5223 char *extra)
5224{
5225 int ret;
5226
5227 cds_ssr_protect(__func__);
5228 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
5229 cds_ssr_unprotect(__func__);
5230
5231 return ret;
5232}
5233
5234/**
5235 * __iw_set_ap_genie() - set ap wpa/rsn ie
5236 *
5237 * @dev - Pointer to the net device.
5238 * @info - Pointer to the iw_request_info.
5239 * @wrqu - Pointer to the iwreq_data.
5240 * @extra - Pointer to the data.
5241 *
5242 * Return: 0 for success, non zero for failure.
5243 */
5244static int __iw_set_ap_genie(struct net_device *dev,
5245 struct iw_request_info *info,
5246 union iwreq_data *wrqu, char *extra) {
5247
5248 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5249#ifndef WLAN_FEATURE_MBSSID
5250 v_CONTEXT_t cds_ctx;
5251#endif
5252 hdd_context_t *hdd_ctx;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305253 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005254 uint8_t *genie = (uint8_t *)extra;
5255 int ret;
5256
Jeff Johnson651f9f22016-02-11 18:16:11 -08005257 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005258
5259 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5260 ret = wlan_hdd_validate_context(hdd_ctx);
5261 if (0 != ret)
5262 return ret;
5263
5264#ifndef WLAN_FEATURE_MBSSID
5265 cds_ctx = hdd_ctx->pcds_context;
5266 if (NULL == cds_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305267 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305268 "%s: QDF Context is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005269 return -EINVAL;
5270 }
5271#endif
5272
5273 if (!wrqu->data.length) {
5274 EXIT();
5275 return 0;
5276 }
5277
5278 switch (genie[0]) {
5279 case DOT11F_EID_WPA:
5280 case DOT11F_EID_RSN:
5281 if ((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) {
5282 hdd_softap_deregister_bc_sta(pHostapdAdapter);
5283 hdd_softap_register_bc_sta(pHostapdAdapter, 1);
5284 }
5285 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
5286#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305287 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005288 wlansap_set_wparsn_ies(WLAN_HDD_GET_SAP_CTX_PTR
5289 (pHostapdAdapter), genie,
5290 wrqu->data.length);
5291#else
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305292 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005293 wlansap_set_wparsn_ies(cds_ctx, genie,
5294 wrqu->data.length);
5295#endif
5296 break;
5297
5298 default:
5299 hddLog(LOGE, FL("Set UNKNOWN IE %X"), genie[0]);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305300 qdf_ret_status = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005301 }
5302
5303 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305304 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005305}
5306
5307/**
5308 * iw_set_ap_genie() - Wrapper function to protect __iw_set_ap_genie
5309 * from the SSR.
5310 *
5311 * @dev - Pointer to the net device.
5312 * @info - Pointer to the iw_request_info.
5313 * @wrqu - Pointer to the iwreq_data.
5314 * @extra - Pointer to the data.
5315 *
5316 * Return: 0 for success, non zero for failure.
5317 */
5318static int
5319iw_set_ap_genie(struct net_device *dev,
5320 struct iw_request_info *info,
5321 union iwreq_data *wrqu, char *extra)
5322{
5323 int ret;
5324
5325 cds_ssr_protect(__func__);
5326 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
5327 cds_ssr_unprotect(__func__);
5328
5329 return ret;
5330}
5331
5332static
5333int __iw_get_softap_linkspeed(struct net_device *dev,
5334 struct iw_request_info *info,
5335 union iwreq_data *wrqu, char *extra)
5336{
5337 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
5338 hdd_context_t *hdd_ctx;
5339 char *pLinkSpeed = (char *)extra;
5340 uint32_t link_speed = 0;
5341 int len = sizeof(uint32_t) + 1;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305342 struct qdf_mac_addr macAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005343 char pmacAddress[MAC_ADDRESS_STR_LEN + 1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305344 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005345 int rc, valid, i;
5346
Jeff Johnson02050312016-02-11 18:40:28 -08005347 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305348
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005349 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5350 valid = wlan_hdd_validate_context(hdd_ctx);
5351 if (0 != valid)
5352 return valid;
5353
5354 hddLog(LOG1, FL("wrqu->data.length(%d)"), wrqu->data.length);
5355
5356 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
5357 if (copy_from_user((void *)pmacAddress,
5358 wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
5359 hddLog(LOG1, FL("failed to copy data to user buffer"));
5360 return -EFAULT;
5361 }
5362 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
5363
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005364 if (!mac_pton(pmacAddress, macAddress.bytes)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005365 hddLog(LOGE, FL("String to Hex conversion Failed"));
5366 return -EINVAL;
5367 }
5368 }
5369 /* If no mac address is passed and/or its length is less than 17,
5370 * link speed for first connected client will be returned.
5371 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305372 if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005373 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
5374 if (pHostapdAdapter->aStaInfo[i].isUsed &&
Anurag Chouhanc5548422016-02-24 18:33:27 +05305375 (!qdf_is_macaddr_broadcast
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005376 (&pHostapdAdapter->aStaInfo[i].macAddrSTA))) {
Anurag Chouhanc5548422016-02-24 18:33:27 +05305377 qdf_copy_macaddr(
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005378 &macAddress,
5379 &pHostapdAdapter->aStaInfo[i].
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005380 macAddrSTA);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305381 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005382 break;
5383 }
5384 }
5385 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305386 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005387 hddLog(LOGE, FL("Invalid peer macaddress"));
5388 return -EINVAL;
5389 }
5390 status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter,
5391 macAddress);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305392 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005393 hddLog(LOGE, FL("Unable to retrieve SME linkspeed"));
5394 return -EINVAL;
5395 }
5396
5397 link_speed = pHostapdAdapter->ls_stats.estLinkSpeed;
5398
5399 /* linkspeed in units of 500 kbps */
5400 link_speed = link_speed / 500;
5401 wrqu->data.length = len;
5402 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
5403 if ((rc < 0) || (rc >= len)) {
5404 /* encoding or length error? */
5405 hddLog(LOGE, FL("Unable to encode link speed"));
5406 return -EIO;
5407 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305408 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005409 return 0;
5410}
5411
5412static int
5413iw_get_softap_linkspeed(struct net_device *dev,
5414 struct iw_request_info *info,
5415 union iwreq_data *wrqu,
5416 char *extra)
5417{
5418 int ret;
5419
5420 cds_ssr_protect(__func__);
5421 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
5422 cds_ssr_unprotect(__func__);
5423
5424 return ret;
5425}
5426
5427static const iw_handler hostapd_handler[] = {
5428 (iw_handler) NULL, /* SIOCSIWCOMMIT */
5429 (iw_handler) NULL, /* SIOCGIWNAME */
5430 (iw_handler) NULL, /* SIOCSIWNWID */
5431 (iw_handler) NULL, /* SIOCGIWNWID */
5432 (iw_handler) NULL, /* SIOCSIWFREQ */
5433 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
5434 (iw_handler) NULL, /* SIOCSIWMODE */
5435 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
5436 (iw_handler) NULL, /* SIOCSIWSENS */
5437 (iw_handler) NULL, /* SIOCGIWSENS */
5438 (iw_handler) NULL, /* SIOCSIWRANGE */
5439 (iw_handler) NULL, /* SIOCGIWRANGE */
5440 (iw_handler) NULL, /* SIOCSIWPRIV */
5441 (iw_handler) NULL, /* SIOCGIWPRIV */
5442 (iw_handler) NULL, /* SIOCSIWSTATS */
5443 (iw_handler) NULL, /* SIOCGIWSTATS */
5444 (iw_handler) NULL, /* SIOCSIWSPY */
5445 (iw_handler) NULL, /* SIOCGIWSPY */
5446 (iw_handler) NULL, /* SIOCSIWTHRSPY */
5447 (iw_handler) NULL, /* SIOCGIWTHRSPY */
5448 (iw_handler) NULL, /* SIOCSIWAP */
5449 (iw_handler) NULL, /* SIOCGIWAP */
5450 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
5451 (iw_handler) NULL, /* SIOCGIWAPLIST */
5452 (iw_handler) NULL, /* SIOCSIWSCAN */
5453 (iw_handler) NULL, /* SIOCGIWSCAN */
5454 (iw_handler) NULL, /* SIOCSIWESSID */
5455 (iw_handler) NULL, /* SIOCGIWESSID */
5456 (iw_handler) NULL, /* SIOCSIWNICKN */
5457 (iw_handler) NULL, /* SIOCGIWNICKN */
5458 (iw_handler) NULL, /* -- hole -- */
5459 (iw_handler) NULL, /* -- hole -- */
5460 (iw_handler) NULL, /* SIOCSIWRATE */
5461 (iw_handler) NULL, /* SIOCGIWRATE */
5462 (iw_handler) NULL, /* SIOCSIWRTS */
5463 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
5464 (iw_handler) NULL, /* SIOCSIWFRAG */
5465 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
5466 (iw_handler) NULL, /* SIOCSIWTXPOW */
5467 (iw_handler) NULL, /* SIOCGIWTXPOW */
5468 (iw_handler) NULL, /* SIOCSIWRETRY */
5469 (iw_handler) NULL, /* SIOCGIWRETRY */
5470 (iw_handler) NULL, /* SIOCSIWENCODE */
5471 (iw_handler) NULL, /* SIOCGIWENCODE */
5472 (iw_handler) NULL, /* SIOCSIWPOWER */
5473 (iw_handler) NULL, /* SIOCGIWPOWER */
5474 (iw_handler) NULL, /* -- hole -- */
5475 (iw_handler) NULL, /* -- hole -- */
5476 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
5477 (iw_handler) NULL, /* SIOCGIWGENIE */
5478 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
5479 (iw_handler) NULL, /* SIOCGIWAUTH */
5480 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
5481 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
5482 (iw_handler) NULL, /* SIOCSIWPMKSA */
5483};
5484
5485/*
5486 * Note that the following ioctls were defined with semantics which
5487 * cannot be handled by the "iwpriv" userspace application and hence
5488 * they are not included in the hostapd_private_args array
5489 * QCSAP_IOCTL_ASSOC_STA_MACADDR
5490 */
5491
5492static const struct iw_priv_args hostapd_private_args[] = {
5493 {
5494 QCSAP_IOCTL_SETPARAM,
5495 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
5496 }, {
5497 QCSAP_IOCTL_SETPARAM,
5498 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
5499 }, {
5500 QCSAP_PARAM_MAX_ASSOC,
5501 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5502 "setMaxAssoc"
5503 }, {
5504 QCSAP_PARAM_HIDE_SSID,
5505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
5506 }, {
5507 QCSAP_PARAM_SET_MC_RATE,
5508 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
5509 },
5510 {
5511 QCSAP_PARAM_SET_TXRX_FW_STATS,
5512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5513 "txrx_fw_stats"
5514 }, {
5515 QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
5516 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5517 "setMccLatency"
5518 }, {
5519 QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
5520 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5521 "setMccQuota"
5522 }, {
5523 QCSAP_PARAM_SET_CHANNEL_CHANGE,
5524 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5525 "setChanChange"
5526 }, {
5527 QCSAP_PARAM_AUTO_CHANNEL,
5528 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5529 "setAutoChannel"
5530 },
5531 /* Sub-cmds DBGLOG specific commands */
5532 {
5533 QCSAP_DBGLOG_LOG_LEVEL,
5534 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5535 0, "dl_loglevel"
5536 }, {
5537 QCSAP_DBGLOG_VAP_ENABLE,
5538 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
5539 }, {
5540 QCSAP_DBGLOG_VAP_DISABLE,
5541 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5542 0, "dl_vapoff"
5543 }, {
5544 QCSAP_DBGLOG_MODULE_ENABLE,
5545 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
5546 }, {
5547 QCSAP_DBGLOG_MODULE_DISABLE,
5548 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5549 0, "dl_modoff"
5550 }, {
5551 QCSAP_DBGLOG_MOD_LOG_LEVEL,
5552 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5553 0, "dl_mod_loglevel"
5554 }, {
5555 QCSAP_DBGLOG_TYPE,
5556 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
5557 }, {
5558 QCSAP_DBGLOG_REPORT_ENABLE,
5559 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5560 0, "dl_report"
5561 }, {
5562 QCASAP_TXRX_FWSTATS_RESET,
5563 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5564 0, "txrx_fw_st_rst"
5565 }, {
5566 QCSAP_PARAM_RTSCTS,
5567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5568 0, "enablertscts"
5569 }, {
5570 QCASAP_SET_11N_RATE,
5571 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5572 0, "set11NRates"
5573 }, {
5574 QCASAP_SET_VHT_RATE,
5575 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5576 0, "set11ACRates"
5577 }, {
5578 QCASAP_SHORT_GI,
5579 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5580 0, "enable_short_gi"
5581 }, {
5582 QCSAP_SET_AMPDU,
5583 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
5584 }, {
5585 QCSAP_SET_AMSDU,
5586 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
5587 }, {
5588 QCSAP_GTX_HT_MCS,
5589 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
5590 }, {
5591 QCSAP_GTX_VHT_MCS,
5592 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5593 0, "gtxVHTMcs"
5594 }, {
5595 QCSAP_GTX_USRCFG,
5596 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5597 0, "gtxUsrCfg"
5598 }, {
5599 QCSAP_GTX_THRE,
5600 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
5601 }, {
5602 QCSAP_GTX_MARGIN,
5603 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5604 0, "gtxMargin"
5605 }, {
5606 QCSAP_GTX_STEP,
5607 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
5608 }, {
5609 QCSAP_GTX_MINTPC,
5610 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5611 0, "gtxMinTpc"
5612 }, {
5613 QCSAP_GTX_BWMASK,
5614 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5615 0, "gtxBWMask"
5616 }, {
5617 QCSAP_PARAM_CLR_ACL,
5618 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5619 0, "setClearAcl"
5620 }, {
5621 QCSAP_PARAM_ACL_MODE,
5622 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
5623 },
5624#ifdef QCA_PKT_PROTO_TRACE
5625 {
5626 QCASAP_SET_DEBUG_LOG,
5627 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setDbgLvl"
5628 },
5629#endif /* QCA_PKT_PROTO_TRACE */
5630 {
5631 QCASAP_SET_TM_LEVEL,
5632 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5633 0, "setTmLevel"
5634 }, {
5635 QCASAP_SET_DFS_IGNORE_CAC,
5636 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5637 0, "setDfsIgnoreCAC"
5638 }, {
5639 QCASAP_SET_DFS_NOL,
5640 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5641 0, "setdfsnol"
5642 }, {
5643 QCASAP_SET_DFS_TARGET_CHNL,
5644 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5645 0, "setNextChnl"
5646 }, {
5647 QCASAP_SET_RADAR_CMD,
5648 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
5649 },
5650 {
5651 QCSAP_IPA_UC_STAT,
5652 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
5653 },
5654 {
5655 QCASAP_TX_CHAINMASK_CMD,
5656 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5657 0, "set_txchainmask"
5658 }, {
5659 QCASAP_RX_CHAINMASK_CMD,
5660 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5661 0, "set_rxchainmask"
5662 }, {
5663 QCASAP_NSS_CMD,
5664 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
5665 }, {
5666 QCASAP_SET_PHYMODE,
5667 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5668 0, "setphymode"
5669 }, {
5670 QCASAP_DUMP_STATS,
5671 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5672 0, "dumpStats"
5673 }, {
5674 QCASAP_CLEAR_STATS,
5675 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5676 0, "clearStats"
5677 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305678 QCSAP_START_FW_PROFILING,
5679 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5680 0, "startProfile"
5681 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005682 QCSAP_IOCTL_GETPARAM, 0,
5683 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
5684 }, {
5685 QCSAP_IOCTL_GETPARAM, 0,
5686 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
5687 }, {
5688 QCSAP_PARAM_MAX_ASSOC, 0,
5689 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
5690 }, {
5691 QCSAP_PARAM_GET_WLAN_DBG, 0,
5692 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
5693 }, {
5694 QCSAP_PARAM_AUTO_CHANNEL, 0,
5695 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel"
5696 }, {
5697 QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5698 "get_gtxBWMask"
5699 }, {
5700 QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5701 "get_gtxMinTpc"
5702 }, {
5703 QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5704 "get_gtxStep"
5705 }, {
5706 QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5707 "get_gtxMargin"
5708 }, {
5709 QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5710 "get_gtxThre"
5711 }, {
5712 QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5713 "get_gtxUsrCfg"
5714 }, {
5715 QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5716 "get_gtxVHTMcs"
5717 }, {
5718 QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5719 "get_gtxHTMcs"
5720 }, {
5721 QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5722 "get_short_gi"
5723 }, {
5724 QCSAP_PARAM_RTSCTS, 0,
5725 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
5726 }, {
5727 QCASAP_GET_DFS_NOL, 0,
5728 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
5729 }, {
5730 QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5731 "get_acl_list"
5732 }, {
5733 QCASAP_TX_CHAINMASK_CMD, 0,
5734 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5735 "get_txchainmask"
5736 }, {
5737 QCASAP_RX_CHAINMASK_CMD, 0,
5738 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5739 "get_rxchainmask"
5740 }, {
5741 QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5742 "get_nss"
5743 }, {
5744 QCASAP_GET_TEMP_CMD, 0,
5745 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
5746 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305747 QCSAP_GET_FW_PROFILE_DATA, 0,
5748 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
5749 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005750 QCSAP_IOCTL_GET_STAWPAIE,
5751 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
5752 "get_staWPAIE"
5753 }, {
5754 QCSAP_IOCTL_SETWPAIE,
5755 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE |
5756 IW_PRIV_SIZE_FIXED, 0, "setwpaie"
5757 }, {
5758 QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
5759 "stopbss"
5760 }, {
5761 QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE,
5762 "version"
5763 }, {
5764 QCSAP_IOCTL_GET_STA_INFO, 0,
5765 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
5766 }, {
5767 QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
5768 IW_PRIV_TYPE_BYTE |
5769 sizeof(sQcSapreq_WPSPBCProbeReqIES_t) |
5770 IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs"
5771 }
5772 , {
5773 QCSAP_IOCTL_GET_CHANNEL, 0,
5774 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
5775 }
5776 , {
5777 QCSAP_IOCTL_DISASSOC_STA,
5778 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
5779 "disassoc_sta"
5780 }
5781 /* handler for main ioctl */
5782 , {
5783 QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
5784 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
5785 }
5786 /* handler for sub-ioctl */
5787 , {
5788 QCSAP_GET_STATS, 0,
5789 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
5790 }
5791 , {
Govind Singha471e5e2015-10-12 17:11:14 +05305792 QCSAP_LIST_FW_PROFILE, 0,
5793 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
5794 }
5795 , {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005796 QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
5797 IW_PRIV_TYPE_CHAR | 18,
5798 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
5799 }
5800 , {
5801 QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
5802 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
5803 }
5804 ,
5805 /* handlers for sub-ioctl */
5806 {
5807 WE_SET_WLAN_DBG,
5808 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
5809 }, {
5810 WE_SET_SAP_CHANNELS,
5811 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setsapchannels"
5812 }
5813 ,
5814 /* handlers for sub-ioctl */
5815 {
5816 WE_SET_DP_TRACE,
5817 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
5818 }
5819 ,
5820 /* handlers for main ioctl */
5821 {
5822 QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
5823 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
5824 }
5825 , {
5826 WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
5827 }
5828 , {
5829 WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
5830 "setUnitTestCmd"
5831 }
5832 ,
5833 /* handlers for main ioctl */
5834 {
5835 QCSAP_IOCTL_MODIFY_ACL,
5836 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
5837 }
5838 ,
5839 /* handlers for main ioctl */
5840 {
5841 QCSAP_IOCTL_GET_CHANNEL_LIST,
5842 0,
5843 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
5844 "getChannelList"
5845 }
5846 ,
5847 /* handlers for main ioctl */
5848 {
5849 QCSAP_IOCTL_SET_TX_POWER,
5850 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
5851 }
5852 ,
5853 /* handlers for main ioctl */
5854 {
5855 QCSAP_IOCTL_SET_MAX_TX_POWER,
5856 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5857 0, "setTxMaxPower"
5858 }
5859 ,
5860 /* Set HDD CFG Ini param */
5861 {
5862 QCSAP_IOCTL_SET_INI_CFG,
5863 IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig"
5864 }
5865 ,
5866 /* Get HDD CFG Ini param */
5867 {
5868 QCSAP_IOCTL_GET_INI_CFG,
5869 0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
5870 }
5871 ,
5872 /* handlers for main ioctl */
5873 {
5874 /* handlers for main ioctl */
5875 QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
5876 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
5877 }
5878 ,
5879 /* handlers for sub-ioctl */
5880#ifdef DEBUG
5881 {
5882 QCSAP_IOCTL_SET_FW_CRASH_INJECT,
5883 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5884 0, "crash_inject"
5885 }
5886 ,
5887#endif
5888 {
5889 QCASAP_SET_RADAR_DBG,
5890 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5891 0, "setRadarDbg"
5892 }
5893 ,
5894 /* dump dp trace - descriptor or dp trace records */
5895 {
5896 QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
5897 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5898 0, "dump_dp_trace"
5899 }
5900 ,
Govind Singha471e5e2015-10-12 17:11:14 +05305901 {
5902 QCSAP_ENABLE_FW_PROFILE,
5903 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5904 0, "enableProfile"
5905 }
5906 ,
5907 {
5908 QCSAP_SET_FW_PROFILE_HIST_INTVL,
5909 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5910 0, "set_hist_intvl"
5911 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005912};
5913
5914static const iw_handler hostapd_private[] = {
5915 /* set priv ioctl */
5916 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
5917 /* get priv ioctl */
5918 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
5919 /* get station genIE */
5920 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
5921 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
5922 /* stop bss */
5923 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
5924 /* get driver version */
5925 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
5926 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] =
5927 iw_get_wpspbc_probe_req_ies,
5928 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
5929 iw_softap_getchannel,
5930 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
5931 iw_softap_getassoc_stamacaddr,
5932 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
5933 iw_softap_disassoc_sta,
5934 [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
5935 iw_get_char_setnone,
5936 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
5937 SIOCIWFIRSTPRIV] =
5938 iw_set_three_ints_getnone,
5939 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
5940 SIOCIWFIRSTPRIV] =
5941 iw_set_var_ints_getnone,
5942 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] =
5943 iw_softap_set_force_acs_ch_range,
5944 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
5945 iw_softap_modify_acl,
5946 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
5947 iw_softap_get_channel_list,
5948 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
5949 iw_softap_get_sta_info,
5950 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
5951 SIOCIWFIRSTPRIV] =
5952 iw_get_softap_linkspeed,
5953 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
5954 iw_softap_set_tx_power,
5955 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
5956 iw_softap_set_max_tx_power,
5957 [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
5958 iw_softap_set_ini_cfg,
5959 [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
5960 iw_softap_get_ini_cfg,
5961 [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
5962 iw_softap_set_two_ints_getnone,
5963};
5964const struct iw_handler_def hostapd_handler_def = {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305965 .num_standard = QDF_ARRAY_SIZE(hostapd_handler),
5966 .num_private = QDF_ARRAY_SIZE(hostapd_private),
5967 .num_private_args = QDF_ARRAY_SIZE(hostapd_private_args),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005968 .standard = (iw_handler *) hostapd_handler,
5969 .private = (iw_handler *) hostapd_private,
5970 .private_args = hostapd_private_args,
5971 .get_wireless_stats = NULL,
5972};
5973
5974struct net_device_ops net_ops_struct = {
5975 .ndo_open = hdd_hostapd_open,
5976 .ndo_stop = hdd_hostapd_stop,
5977 .ndo_uninit = hdd_hostapd_uninit,
5978 .ndo_start_xmit = hdd_softap_hard_start_xmit,
5979 .ndo_tx_timeout = hdd_softap_tx_timeout,
5980 .ndo_get_stats = hdd_get_stats,
5981 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
5982 .ndo_do_ioctl = hdd_ioctl,
5983 .ndo_change_mtu = hdd_hostapd_change_mtu,
5984 .ndo_select_queue = hdd_hostapd_select_queue,
5985};
5986
5987static int hdd_set_hostapd(hdd_adapter_t *pAdapter)
5988{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305989 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005990}
5991
5992void hdd_set_ap_ops(struct net_device *pWlanHostapdDev)
5993{
5994 pWlanHostapdDev->netdev_ops = &net_ops_struct;
5995}
5996
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305997QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005998{
5999 hdd_hostapd_state_t *phostapdBuf;
6000 struct net_device *dev = pAdapter->dev;
6001 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306002 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05306003 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006004#ifdef WLAN_FEATURE_MBSSID
6005 v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(pAdapter))->pcds_context;
6006 v_CONTEXT_t sapContext = NULL;
6007#endif
6008 int ret;
6009
6010 ENTER();
6011
6012#ifdef WLAN_FEATURE_MBSSID
6013 sapContext = wlansap_open(p_cds_context);
6014 if (sapContext == NULL) {
6015 hddLog(LOGE, ("ERROR: wlansap_open failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306016 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006017 }
6018
6019 pAdapter->sessionCtx.ap.sapContext = sapContext;
6020
6021 status = wlansap_start(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306022 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006023 hddLog(LOGE, ("ERROR: wlansap_start failed!!"));
6024 wlansap_close(sapContext);
6025 return status;
6026 }
6027#endif
6028
6029 /* Allocate the Wireless Extensions state structure */
6030 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6031
6032 sme_set_curr_device_mode(pHddCtx->hHal, pAdapter->device_mode);
6033
6034 /* Zero the memory. This zeros the profile structure. */
6035 memset(phostapdBuf, 0, sizeof(hdd_hostapd_state_t));
6036
6037 /* Set up the pointer to the Wireless Extensions state structure */
6038 /* NOP */
6039 status = hdd_set_hostapd(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306040 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006041 hddLog(LOGE, ("ERROR: hdd_set_hostapd failed!!"));
6042#ifdef WLAN_FEATURE_MBSSID
6043 wlansap_close(sapContext);
6044#endif
6045 return status;
6046 }
6047
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306048 qdf_status = qdf_event_create(&phostapdBuf->qdf_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05306049 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306050 hddLog(LOGE, ("ERROR: Hostapd HDD qdf event init failed!!"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006051#ifdef WLAN_FEATURE_MBSSID
6052 wlansap_close(sapContext);
6053#endif
Anurag Chouhance0dc992016-02-16 18:18:03 +05306054 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006055 }
6056
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306057 qdf_status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05306058 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306059 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006060 ("ERROR: Hostapd HDD stop bss event init failed!!"));
6061#ifdef WLAN_FEATURE_MBSSID
6062 wlansap_close(sapContext);
6063#endif
Anurag Chouhance0dc992016-02-16 18:18:03 +05306064 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006065 }
6066
6067 init_completion(&pAdapter->session_close_comp_var);
6068 init_completion(&pAdapter->session_open_comp_var);
6069
6070 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
6071
6072 /* Register as a wireless device */
6073 dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
6074
6075 /* Initialize the data path module */
6076 status = hdd_softap_init_tx_rx(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306077 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006078 hddLog(LOGP, FL("hdd_softap_init_tx_rx failed"));
6079 }
6080
6081 status = hdd_wmm_adapter_init(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306082 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006083 hddLog(LOGE,
6084 "hdd_wmm_adapter_init() failed code %08d [x%08x]",
6085 status, status);
6086 goto error_wmm_init;
6087 }
6088
6089 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6090
6091 ret = wma_cli_set_command(pAdapter->sessionId,
6092 WMI_PDEV_PARAM_BURST_ENABLE,
6093 pHddCtx->config->enableSifsBurst,
6094 PDEV_CMD);
6095
6096 if (0 != ret) {
6097 hddLog(LOGE,
6098 FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"), ret);
6099 }
6100 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306101 qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
6102 qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006103 sizeof(struct sap_acs_cfg));
6104 return status;
6105
6106error_wmm_init:
6107 hdd_softap_deinit_tx_rx(pAdapter);
6108#ifdef WLAN_FEATURE_MBSSID
6109 wlansap_close(sapContext);
6110#endif
6111 EXIT();
6112 return status;
6113}
6114
6115/**
6116 * hdd_wlan_create_ap_dev() - create an AP-mode device
6117 * @pHddCtx: Global HDD context
6118 * @macAddr: MAC address to assign to the interface
6119 * @iface_name: User-visible name of the interface
6120 *
6121 * This function will allocate a Linux net_device and configuration it
6122 * for an AP mode of operation. Note that the device is NOT actually
6123 * registered with the kernel at this time.
6124 *
6125 * Return: A pointer to the private data portion of the net_device if
6126 * the allocation and initialization was successful, NULL otherwise.
6127 */
6128hdd_adapter_t *hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx,
6129 tSirMacAddr macAddr,
6130 uint8_t *iface_name) {
6131 struct net_device *pWlanHostapdDev = NULL;
6132 hdd_adapter_t *pHostapdAdapter = NULL;
6133
6134 hddLog(LOG4, FL("iface_name = %s"), iface_name);
6135
6136 pWlanHostapdDev =
6137 alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name,
6138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
6139 NET_NAME_UNKNOWN,
6140#endif
6141 ether_setup,
6142 NUM_TX_QUEUES);
6143
6144 if (pWlanHostapdDev != NULL) {
6145 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
6146
6147 /* Init the net_device structure */
6148 ether_setup(pWlanHostapdDev);
6149
6150 /* Initialize the adapter context to zeros. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306151 qdf_mem_zero(pHostapdAdapter, sizeof(hdd_adapter_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006152 pHostapdAdapter->dev = pWlanHostapdDev;
6153 pHostapdAdapter->pHddCtx = pHddCtx;
6154 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6155
6156 hddLog(LOG4,
6157 FL("pWlanHostapdDev = %p, pHostapdAdapter = %p, concurrency_mode=0x%x"),
6158 pWlanHostapdDev,
6159 pHostapdAdapter,
6160 (int)cds_get_concurrency_mode());
6161
6162 /* Init the net_device structure */
6163 strlcpy(pWlanHostapdDev->name, (const char *)iface_name,
6164 IFNAMSIZ);
6165
6166 hdd_set_ap_ops(pHostapdAdapter->dev);
6167
6168 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
6169 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
Mohit Khannaee9e80f2015-11-10 11:32:49 -08006170 pWlanHostapdDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006171
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306172 qdf_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006173 sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306174 qdf_mem_copy(pHostapdAdapter->macAddressCurrent.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006175 (void *)macAddr, sizeof(tSirMacAddr));
6176
6177 pHostapdAdapter->offloads_configured = false;
6178 pWlanHostapdDev->destructor = free_netdev;
6179 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev;
6180 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
6181 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
Dhanashri Atre83d373d2015-07-28 16:45:59 -07006182 hdd_set_tso_flags(pHddCtx, pWlanHostapdDev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006183 init_completion(&pHostapdAdapter->tx_action_cnf_event);
6184 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
6185 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
6186 init_completion(&pHostapdAdapter->sta_authorized_event);
6187 init_completion(&pHostapdAdapter->offchannel_tx_event);
6188 init_completion(&pHostapdAdapter->scan_info.
6189 abortscan_event_var);
6190
6191 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
6192 spin_lock_init(&pHostapdAdapter->pause_map_lock);
6193 }
6194 return pHostapdAdapter;
6195}
6196
6197/**
6198 * hdd_register_hostapd() - register hostapd
6199 * @pAdapter: Pointer to hostapd adapter
6200 * @rtnl_lock_held: RTNL lock held
6201 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306202 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006203 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306204QDF_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006205 uint8_t rtnl_lock_held) {
6206 struct net_device *dev = pAdapter->dev;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306207 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006208
6209 ENTER();
6210
6211 if (rtnl_lock_held) {
6212 if (strnchr(dev->name, strlen(dev->name), '%')) {
6213 if (dev_alloc_name(dev, dev->name) < 0) {
6214 hddLog(LOGE, FL("Failed:dev_alloc_name"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306215 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006216 }
6217 }
6218 if (register_netdevice(dev)) {
6219 hddLog(LOGE, FL("Failed:register_netdevice"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306220 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006221 }
6222 } else {
6223 if (register_netdev(dev)) {
6224 hddLog(LOGE, FL("Failed:register_netdev"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306225 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006226 }
6227 }
6228 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6229
6230 EXIT();
6231 return status;
6232}
6233
6234/**
6235 * hdd_unregister_hostapd() - unregister hostapd
6236 * @pAdapter: Pointer to hostapd adapter
6237 * @rtnl_held: true if rtnl lock held; false otherwise
6238 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306239 * Return: QDF_STATUS enumaration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006240 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306241QDF_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006242{
6243#ifdef WLAN_FEATURE_MBSSID
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306244 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006245 void *sapContext = WLAN_HDD_GET_SAP_CTX_PTR(pAdapter);
6246#endif
6247
6248 ENTER();
6249
6250 hdd_softap_deinit_tx_rx(pAdapter);
6251
6252 /* if we are being called during driver unload,
6253 * then the dev has already been invalidated.
6254 * if we are being called at other times, then we can
6255 * detach the wireless device handlers
6256 */
6257 if (pAdapter->dev) {
6258 if (rtnl_held)
6259 pAdapter->dev->wireless_handlers = NULL;
6260 else {
6261 rtnl_lock();
6262 pAdapter->dev->wireless_handlers = NULL;
6263 rtnl_unlock();
6264 }
6265 }
6266
6267#ifdef WLAN_FEATURE_MBSSID
6268 status = wlansap_stop(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306269 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006270 hddLog(LOGE, FL("Failed:wlansap_stop"));
6271
6272 status = wlansap_close(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306273 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006274 hddLog(LOGE, FL("Failed:WLANSAP_close"));
6275 pAdapter->sessionCtx.ap.sapContext = NULL;
6276#endif
6277
6278 EXIT();
6279 return 0;
6280}
6281
6282/**
6283 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
6284 * @rate: Rate to be checked
6285 *
6286 * Return: true if rate if 11g else false
6287 */
6288static bool wlan_hdd_rate_is_11g(u8 rate)
6289{
6290 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
6291 96, 108}; /* actual rate * 2 */
6292 u8 i;
6293 for (i = 0; i < 8; i++) {
6294 if (rate == gRateArray[i])
6295 return true;
6296 }
6297 return false;
6298}
6299
6300#ifdef QCA_HT_2040_COEX
6301/**
6302 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
6303 * @pHostapdAdapter: Pointer to hostapd adapter
6304 *
6305 * Return: HT support channel width config value
6306 */
6307static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6308{
6309 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
6310 tDot11fIEHTCaps dot11_ht_cap_ie = {0};
6311 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
6312 beacon_data_t *beacon = pHostapdAdapter->sessionCtx.ap.beacon;
6313 uint8_t *ie = NULL;
6314
6315 ie = wlan_hdd_cfg80211_get_ie_ptr(beacon->tail, beacon->tail_len,
6316 WLAN_EID_HT_CAPABILITY);
6317 if (ie && ie[1]) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306318 qdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006319 dot11f_unpack_ie_ht_caps((tpAniSirGlobal)hdd_ctx->hHal,
6320 ht_cap_ie, ie[1], &dot11_ht_cap_ie);
6321 return dot11_ht_cap_ie.supportedChannelWidthSet;
6322 }
6323
6324 return false;
6325}
6326#else
6327static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6328{
6329 return false;
6330}
6331#endif
6332/**
6333 * wlan_hdd_set_channel() - set channel in sap mode
6334 * @wiphy: Pointer to wiphy structure
6335 * @dev: Pointer to net_device structure
6336 * @chandef: Pointer to channel definition structure
6337 * @channel_type: Channel type
6338 *
6339 * Return: 0 for success non-zero for failure
6340 */
6341static int wlan_hdd_set_channel(struct wiphy *wiphy,
6342 struct net_device *dev,
6343 struct cfg80211_chan_def *chandef,
6344 enum nl80211_channel_type channel_type)
6345{
6346 hdd_adapter_t *pAdapter = NULL;
6347 uint32_t num_ch = 0;
6348 int channel = 0;
6349 int channel_seg2 = 0;
6350 hdd_context_t *pHddCtx;
6351 int status;
6352
6353 tSmeConfigParams smeConfig;
6354 tsap_Config_t *sap_config;
6355
6356 ENTER();
6357
6358
6359 if (NULL == dev) {
6360 hddLog(LOGE, FL("Called with dev = NULL."));
6361 return -ENODEV;
6362 }
6363 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6364
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306365 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006366 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
6367 pAdapter->sessionId, channel_type));
6368
6369 hddLog(LOG1, FL("Device_mode %s(%d) freq = %d"),
6370 hdd_device_mode_to_string(pAdapter->device_mode),
6371 pAdapter->device_mode, chandef->chan->center_freq);
6372
6373 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6374 status = wlan_hdd_validate_context(pHddCtx);
6375
6376 if (0 != status) {
6377 hddLog(LOGE, FL("HDD context is not valid"));
6378 return status;
6379 }
6380
6381 /*
6382 * Do freq to chan conversion
6383 * TODO: for 11a
6384 */
6385
6386 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
6387 if (NL80211_CHAN_WIDTH_80P80 == chandef->width)
6388 channel_seg2 = ieee80211_frequency_to_channel(chandef->center_freq2);
6389 else
6390 channel_seg2 = 0;
6391
6392 /* Check freq range */
6393 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6394 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
6395 hddLog(LOGE,
6396 FL("Channel [%d] is outside valid range from %d to %d"),
6397 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6398 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6399 return -EINVAL;
6400 }
6401
6402 /* Check freq range */
6403
6404 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
6405 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
6406 hddLog(LOGE,
6407 FL("Channel [%d] is outside valid range from %d to %d"),
6408 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6409 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6410 return -EINVAL;
6411 }
6412
6413 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6414
6415 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6416 (WLAN_HDD_P2P_GO != pAdapter->device_mode)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306417 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006418 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
6419 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
6420 return -EINVAL;
6421 }
6422 hddLog(LOG2,
6423 FL("set channel to [%d] for device mode %s(%d)"),
6424 channel,
6425 hdd_device_mode_to_string(pAdapter->device_mode),
6426 pAdapter->device_mode);
6427 }
6428
6429 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6430 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6431 ) {
6432 hdd_wext_state_t *pWextState =
6433 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6434 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
6435 hdd_station_ctx_t *pHddStaCtx =
6436 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6437
6438 if (eConnectionState_IbssConnected ==
6439 pHddStaCtx->conn_info.connState) {
6440 /* Link is up then return cant set channel */
6441 hddLog(LOGE,
6442 FL("IBSS Associated, can't set the channel"));
6443 return -EINVAL;
6444 }
6445
6446 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6447 pHddStaCtx->conn_info.operationChannel = channel;
6448 pRoamProfile->ChannelInfo.ChannelList =
6449 &pHddStaCtx->conn_info.operationChannel;
6450 } else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6451 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
6452 ) {
6453 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig);
6454 if (WLAN_HDD_P2P_GO == pAdapter->device_mode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306455 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006456 wlan_hdd_validate_operation_channel(pAdapter,
6457 channel)) {
6458 hddLog(LOGE,
6459 FL("Invalid Channel [%d]"), channel);
6460 return -EINVAL;
6461 }
6462 sap_config->channel = channel;
6463 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6464 } else {
6465 /* set channel to what hostapd configured */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306466 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006467 wlan_hdd_validate_operation_channel(pAdapter,
6468 channel)) {
6469 hddLog(LOGE,
6470 FL("Invalid Channel [%d]"), channel);
6471 return -EINVAL;
6472 }
6473
6474 sap_config->channel = channel;
6475 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6476
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306477 qdf_mem_zero(&smeConfig, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006478 sme_get_config_param(pHddCtx->hHal, &smeConfig);
6479 switch (channel_type) {
6480 case NL80211_CHAN_HT20:
6481 case NL80211_CHAN_NO_HT:
6482 smeConfig.csrConfig.obssEnabled = false;
6483 if (channel <= 14)
6484 smeConfig.csrConfig.
6485 channelBondingMode24GHz =
6486 eCSR_INI_SINGLE_CHANNEL_CENTERED;
6487 else
6488 smeConfig.csrConfig.
6489 channelBondingMode5GHz =
6490 eCSR_INI_SINGLE_CHANNEL_CENTERED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006491 sap_config->sec_ch = 0;
6492 break;
6493
6494 case NL80211_CHAN_HT40MINUS:
6495 if (channel <= 14)
6496 smeConfig.csrConfig.
6497 channelBondingMode24GHz =
6498 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6499 else
6500 smeConfig.csrConfig.
6501 channelBondingMode5GHz =
6502 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6503 sap_config->sec_ch = sap_config->channel - 4;
6504 break;
6505 case NL80211_CHAN_HT40PLUS:
6506 if (channel <= 14)
6507 smeConfig.csrConfig.
6508 channelBondingMode24GHz =
6509 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6510 else
6511 smeConfig.csrConfig.
6512 channelBondingMode5GHz =
6513 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6514 sap_config->sec_ch = sap_config->channel + 4;
6515 break;
6516 default:
6517 hddLog(LOGE,
6518 FL("Error!!! Invalid HT20/40 mode !"));
6519 return -EINVAL;
6520 }
6521 smeConfig.csrConfig.obssEnabled = wlan_hdd_get_sap_obss(
6522 pAdapter);
6523 sme_update_config(pHddCtx->hHal, &smeConfig);
6524 }
6525 } else {
6526 hddLog(LOGE,
6527 FL("Invalid device mode failed to set valid channel"));
6528 return -EINVAL;
6529 }
6530 EXIT();
6531 return status;
6532}
6533
6534/**
6535 * wlan_hdd_check_11gmode() - check for 11g mode
6536 * @pIe: Pointer to IE
6537 * @require_ht: Pointer to require ht
6538 * @require_vht: Pointer to require vht
6539 * @pCheckRatesfor11g: Pointer to check rates for 11g mode
6540 * @pSapHw_mode: SAP HW mode
6541 *
6542 * Check for 11g rate and set proper 11g only mode
6543 *
6544 * Return: none
6545 */
6546static void wlan_hdd_check_11gmode(u8 *pIe, u8 *require_ht, u8 *require_vht,
6547 u8 *pCheckRatesfor11g,
6548 eCsrPhyMode *pSapHw_mode)
6549{
6550 u8 i, num_rates = pIe[0];
6551
6552 pIe += 1;
6553 for (i = 0; i < num_rates; i++) {
6554 if (*pCheckRatesfor11g
6555 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
6556 /* If rate set have 11g rate than change the mode
6557 * to 11G
6558 */
6559 *pSapHw_mode = eCSR_DOT11_MODE_11g;
6560 if (pIe[i] & BASIC_RATE_MASK) {
6561 /* If we have 11g rate as basic rate, it
6562 * means mode is 11g only mode.
6563 */
6564 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
6565 *pCheckRatesfor11g = false;
6566 }
6567 } else {
6568 if ((BASIC_RATE_MASK |
6569 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6570 *require_ht = true;
6571 else if ((BASIC_RATE_MASK |
6572 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
6573 *require_vht = true;
6574 }
6575 }
6576 return;
6577}
6578
6579/**
6580 * wlan_hdd_add_ie() - add ie
6581 * @pHostapdAdapter: Pointer to hostapd adapter
6582 * @genie: Pointer to ie to be added
6583 * @total_ielen: Pointer to store total ie length
6584 * @oui: Pointer to oui
6585 * @oui_size: Size of oui
6586 *
6587 * Return: 0 for success non-zero for failure
6588 */
6589static int wlan_hdd_add_ie(hdd_adapter_t *pHostapdAdapter, uint8_t *genie,
6590 uint8_t *total_ielen, uint8_t *oui,
6591 uint8_t oui_size)
6592{
6593 uint16_t ielen = 0;
6594 uint8_t *pIe = NULL;
6595 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6596
6597 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6598 pBeacon->tail, pBeacon->tail_len);
6599
6600 if (pIe) {
6601 ielen = pIe[1] + 2;
6602 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306603 qdf_mem_copy(&genie[*total_ielen], pIe, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006604 } else {
6605 hddLog(LOGE,
6606 "**Ie Length is too big***");
6607 return -EINVAL;
6608 }
6609 *total_ielen += ielen;
6610 }
6611 return 0;
6612}
6613
6614/**
6615 * wlan_hdd_add_hostapd_conf_vsie() - configure vsie in sap mode
6616 * @pHostapdAdapter: Pointer to hostapd adapter
6617 * @genie: Pointer to vsie
6618 * @total_ielen: Pointer to store total ie length
6619 *
6620 * Return: none
6621 */
6622static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t *pHostapdAdapter,
6623 uint8_t *genie,
6624 uint8_t *total_ielen)
6625{
6626 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6627 int left = pBeacon->tail_len;
6628 uint8_t *ptr = pBeacon->tail;
6629 uint8_t elem_id, elem_len;
6630 uint16_t ielen = 0;
6631
6632 if (NULL == ptr || 0 == left)
6633 return;
6634
6635 while (left >= 2) {
6636 elem_id = ptr[0];
6637 elem_len = ptr[1];
6638 left -= 2;
6639 if (elem_len > left) {
6640 hddLog(LOGE,
6641 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6642 elem_id, elem_len, left);
6643 return;
6644 }
6645 if (IE_EID_VENDOR == elem_id) {
6646 /* skipping the VSIE's which we don't want to include or
6647 * it will be included by existing code
6648 */
6649 if ((memcmp(&ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) !=
6650 0) &&
6651#ifdef WLAN_FEATURE_WFD
6652 (memcmp(&ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) !=
6653 0) &&
6654#endif
6655 (memcmp
6656 (&ptr[2], WHITELIST_OUI_TYPE,
6657 WPA_OUI_TYPE_SIZE) != 0)
6658 &&
6659 (memcmp
6660 (&ptr[2], BLACKLIST_OUI_TYPE,
6661 WPA_OUI_TYPE_SIZE) != 0)
6662 &&
6663 (memcmp
6664 (&ptr[2], "\x00\x50\xf2\x02",
6665 WPA_OUI_TYPE_SIZE) != 0)
6666 && (memcmp(&ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE)
6667 != 0)
6668 && (memcmp(&ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)
6669 != 0)) {
6670 ielen = ptr[1] + 2;
6671 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306672 qdf_mem_copy(&genie[*total_ielen], ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006673 ielen);
6674 *total_ielen += ielen;
6675 } else {
6676 hddLog(LOGE,
6677 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6678 elem_id, elem_len, *total_ielen);
6679 }
6680 }
6681 }
6682
6683 left -= elem_len;
6684 ptr += (elem_len + 2);
6685 }
6686 return;
6687}
6688
6689/**
6690 * wlan_hdd_add_extra_ie() - add extra ies in beacon
6691 * @pHostapdAdapter: Pointer to hostapd adapter
6692 * @genie: Pointer to extra ie
6693 * @total_ielen: Pointer to store total ie length
6694 * @temp_ie_id: ID of extra ie
6695 *
6696 * Return: none
6697 */
6698static void wlan_hdd_add_extra_ie(hdd_adapter_t *pHostapdAdapter,
6699 uint8_t *genie, uint8_t *total_ielen,
6700 uint8_t temp_ie_id)
6701{
6702 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6703 int left = pBeacon->tail_len;
6704 uint8_t *ptr = pBeacon->tail;
6705 uint8_t elem_id, elem_len;
6706 uint16_t ielen = 0;
6707
6708 if (NULL == ptr || 0 == left)
6709 return;
6710
6711 while (left >= 2) {
6712 elem_id = ptr[0];
6713 elem_len = ptr[1];
6714 left -= 2;
6715 if (elem_len > left) {
6716 hddLog(LOGE,
6717 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6718 elem_id, elem_len, left);
6719 return;
6720 }
6721
6722 if (temp_ie_id == elem_id) {
6723 ielen = ptr[1] + 2;
6724 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306725 qdf_mem_copy(&genie[*total_ielen], ptr, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006726 *total_ielen += ielen;
6727 } else {
6728 hddLog(LOGE,
6729 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6730 elem_id, elem_len, *total_ielen);
6731 }
6732 }
6733
6734 left -= elem_len;
6735 ptr += (elem_len + 2);
6736 }
6737 return;
6738}
6739
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006740/**
6741 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
6742 * @pAdapter: Pointer to hostapd adapter
6743 * @ppBeacon: Pointer to pointer to beacon data
6744 * @params: Pointer to beacon parameters
6745 * @dtim_period: DTIM period
6746 *
6747 * Return: 0 for success non-zero for failure
6748 */
6749int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
6750 beacon_data_t **ppBeacon,
6751 struct cfg80211_beacon_data *params,
6752 int dtim_period)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006753{
6754 int size;
6755 beacon_data_t *beacon = NULL;
6756 beacon_data_t *old = NULL;
6757 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
6758 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
6759
6760 ENTER();
6761 if (params->head && !params->head_len) {
6762 hddLog(LOGE, FL("head_len is NULL"));
6763 return -EINVAL;
6764 }
6765
6766 old = pAdapter->sessionCtx.ap.beacon;
6767
6768 if (!params->head && !old) {
6769 hddLog(LOGE, FL("session(%d) old and new heads points to NULL"),
6770 pAdapter->sessionId);
6771 return -EINVAL;
6772 }
6773
6774 if (params->head) {
6775 head_len = params->head_len;
6776 head = params->head;
6777 } else {
6778 head_len = old->head_len;
6779 head = old->head;
6780 }
6781
6782 if (params->tail || !old) {
6783 tail_len = params->tail_len;
6784 tail = params->tail;
6785 } else {
6786 tail_len = old->tail_len;
6787 tail = old->tail;
6788 }
6789
6790 if (params->proberesp_ies || !old) {
6791 proberesp_ies_len = params->proberesp_ies_len;
6792 proberesp_ies = params->proberesp_ies;
6793 } else {
6794 proberesp_ies_len = old->proberesp_ies_len;
6795 proberesp_ies = old->proberesp_ies;
6796 }
6797
6798 if (params->assocresp_ies || !old) {
6799 assocresp_ies_len = params->assocresp_ies_len;
6800 assocresp_ies = params->assocresp_ies;
6801 } else {
6802 assocresp_ies_len = old->assocresp_ies_len;
6803 assocresp_ies = old->assocresp_ies;
6804 }
6805
6806 size = sizeof(beacon_data_t) + head_len + tail_len +
6807 proberesp_ies_len + assocresp_ies_len;
6808
6809 beacon = kzalloc(size, GFP_KERNEL);
6810
6811 if (beacon == NULL) {
6812 hddLog(LOGE,
6813 FL("Mem allocation for beacon failed"));
6814 return -ENOMEM;
6815 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006816 if (dtim_period)
6817 beacon->dtim_period = dtim_period;
6818 else if (old)
6819 beacon->dtim_period = old->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006820 /* -----------------------------------------------
6821 * | head | tail | proberesp_ies | assocresp_ies |
6822 * -----------------------------------------------
6823 */
6824 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6825 beacon->tail = beacon->head + head_len;
6826 beacon->proberesp_ies = beacon->tail + tail_len;
6827 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
6828
6829 beacon->head_len = head_len;
6830 beacon->tail_len = tail_len;
6831 beacon->proberesp_ies_len = proberesp_ies_len;
6832 beacon->assocresp_ies_len = assocresp_ies_len;
6833
6834 if (head && head_len)
6835 memcpy(beacon->head, head, head_len);
6836 if (tail && tail_len)
6837 memcpy(beacon->tail, tail, tail_len);
6838 if (proberesp_ies && proberesp_ies_len)
6839 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
6840 if (assocresp_ies && assocresp_ies_len)
6841 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
6842
6843 *ppBeacon = beacon;
6844
6845 kfree(old);
6846
6847 return 0;
6848
6849}
6850
6851/**
6852 * wlan_hdd_cfg80211_update_apies() - update ap mode ies
6853 * @adapter: Pointer to hostapd adapter
6854 *
6855 * Return: 0 for success non-zero for failure
6856 */
6857int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *adapter)
6858{
6859 uint8_t *genie;
6860 uint8_t total_ielen = 0;
6861 int ret = 0;
6862 tsap_Config_t *pConfig;
6863 tSirUpdateIE updateIE;
6864 beacon_data_t *beacon = NULL;
6865
6866 pConfig = &adapter->sessionCtx.ap.sapConfig;
6867 beacon = adapter->sessionCtx.ap.beacon;
6868
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306869 genie = qdf_mem_malloc(MAX_GENIE_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006870
6871 if (genie == NULL)
6872 return -ENOMEM;
6873
6874 if (0 != wlan_hdd_add_ie(adapter, genie,
6875 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) {
6876 hddLog(LOGE, FL("Adding WPS IE failed"));
6877 ret = -EINVAL;
6878 goto done;
6879 }
6880#ifdef WLAN_FEATURE_WFD
6881 if (0 != wlan_hdd_add_ie(adapter, genie,
6882 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) {
6883 hddLog(LOGE, FL("Adding WFD IE failed"));
6884 ret = -EINVAL;
6885 goto done;
6886 }
6887#endif
6888
6889#ifdef FEATURE_WLAN_WAPI
6890 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6891 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6892 WLAN_EID_WAPI);
6893 }
6894#endif
6895
6896 if (adapter->device_mode == WLAN_HDD_SOFTAP ||
6897 adapter->device_mode == WLAN_HDD_P2P_GO)
6898 wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
6899 &total_ielen);
6900
6901 if (wlan_hdd_add_ie(adapter, genie,
6902 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0) {
6903 hddLog(LOGE, FL("Adding P2P IE failed"));
6904 ret = -EINVAL;
6905 goto done;
6906 }
6907
6908#ifdef QCA_HT_2040_COEX
6909 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6910 tSmeConfigParams smeConfig;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306911 qdf_mem_zero(&smeConfig, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006912 sme_get_config_param(WLAN_HDD_GET_HAL_CTX(adapter),
6913 &smeConfig);
6914 if (smeConfig.csrConfig.obssEnabled)
6915 wlan_hdd_add_extra_ie(adapter, genie,
6916 &total_ielen,
6917 WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
6918 }
6919#endif
Anurag Chouhanc5548422016-02-24 18:33:27 +05306920 qdf_copy_macaddr(&updateIE.bssid, &adapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006921 updateIE.smeSessionId = adapter->sessionId;
6922
6923 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6924 updateIE.ieBufferlength = total_ielen;
6925 updateIE.pAdditionIEBuffer = genie;
6926 updateIE.append = false;
6927 updateIE.notify = true;
6928 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6929 &updateIE,
6930 eUPDATE_IE_PROBE_BCN) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306931 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006932 hddLog(LOGE,
6933 FL("Could not pass on Add Ie probe beacon data"));
6934 ret = -EINVAL;
6935 goto done;
6936 }
6937 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
6938 } else {
6939 wlansap_update_sap_config_add_ie(pConfig,
6940 genie,
6941 total_ielen,
6942 eUPDATE_IE_PROBE_BCN);
6943 }
6944
6945 /* Added for Probe Response IE */
6946 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6947 updateIE.ieBufferlength = beacon->proberesp_ies_len;
6948 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->proberesp_ies;
6949 updateIE.append = false;
6950 updateIE.notify = false;
6951 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6952 &updateIE,
6953 eUPDATE_IE_PROBE_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306954 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006955 hddLog(LOGE,
6956 FL("Could not pass on PROBE_RESP add Ie data"));
6957 ret = -EINVAL;
6958 goto done;
6959 }
6960 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
6961 } else {
6962 wlansap_update_sap_config_add_ie(pConfig,
6963 beacon->proberesp_ies,
6964 beacon->proberesp_ies_len,
6965 eUPDATE_IE_PROBE_RESP);
6966 }
6967
6968 /* Assoc resp Add ie Data */
6969 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6970 updateIE.ieBufferlength = beacon->assocresp_ies_len;
6971 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
6972 updateIE.append = false;
6973 updateIE.notify = false;
6974 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6975 &updateIE,
6976 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306977 QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006978 hddLog(LOGE,
6979 FL("Could not pass on Add Ie Assoc Response data"));
6980 ret = -EINVAL;
6981 goto done;
6982 }
6983 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
6984 } else {
6985 wlansap_update_sap_config_add_ie(pConfig,
6986 beacon->assocresp_ies,
6987 beacon->assocresp_ies_len,
6988 eUPDATE_IE_ASSOC_RESP);
6989 }
6990
6991done:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306992 qdf_mem_free(genie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006993 return ret;
6994}
6995
6996/**
6997 * wlan_hdd_set_sap_hwmode() - set sap hw mode
6998 * @pHostapdAdapter: Pointer to hostapd adapter
6999 *
7000 * Return: none
7001 */
7002static void wlan_hdd_set_sap_hwmode(hdd_adapter_t *pHostapdAdapter)
7003{
7004 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7005 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7006 struct ieee80211_mgmt *pMgmt_frame =
7007 (struct ieee80211_mgmt *)pBeacon->head;
7008 u8 checkRatesfor11g = true;
7009 u8 require_ht = false, require_vht = false;
7010 u8 *pIe = NULL;
7011
7012 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
7013
7014 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7015 pBeacon->head_len,
7016 WLAN_EID_SUPP_RATES);
7017 if (pIe != NULL) {
7018 pIe += 1;
7019 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
7020 &checkRatesfor11g, &pConfig->SapHw_mode);
7021 }
7022
7023 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7024 WLAN_EID_EXT_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 if (pConfig->channel > 14)
7032 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
7033
7034 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7035 WLAN_EID_HT_CAPABILITY);
7036
7037 if (pIe) {
7038 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
7039 if (require_ht)
7040 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
7041 }
7042
7043 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7044 WLAN_EID_VHT_CAPABILITY);
7045
7046 if (pIe) {
7047 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
7048 if (require_vht)
7049 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
7050 }
7051}
7052
7053/**
7054 * wlan_hdd_config_acs() - config ACS needed parameters
7055 * @hdd_ctx: HDD context
7056 * @adapter: Adapter pointer
7057 *
7058 * This function get ACS related INI paramters and populated
7059 * sap config and smeConfig for ACS needed configurations.
7060 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307061 * Return: The QDF_STATUS code associated with performing the operation.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007062 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307063QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007064{
7065 tsap_Config_t *sap_config;
7066 struct hdd_config *ini_config;
7067 tHalHandle hal;
7068
7069 hal = WLAN_HDD_GET_HAL_CTX(adapter);
7070 sap_config = &adapter->sessionCtx.ap.sapConfig;
7071 ini_config = hdd_ctx->config;
7072
7073 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
7074
7075#if defined(WLAN_FEATURE_MBSSID) && defined(FEATURE_WLAN_AP_AP_ACS_OPTIMIZE)
7076 hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"),
7077 hdd_ctx->skip_acs_scan_status);
7078 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
7079 hdd_adapter_t *con_sap_adapter;
7080 tsap_Config_t *con_sap_config = NULL;
7081
7082 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
7083
7084 if (con_sap_adapter)
7085 con_sap_config =
7086 &con_sap_adapter->sessionCtx.ap.sapConfig;
7087
7088 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
7089
7090 if (con_sap_config &&
7091 con_sap_config->acs_cfg.acs_mode == true &&
7092 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
7093 con_sap_config->acs_cfg.hw_mode ==
7094 sap_config->acs_cfg.hw_mode) {
7095 uint8_t con_sap_st_ch, con_sap_end_ch;
7096 uint8_t cur_sap_st_ch, cur_sap_end_ch;
7097 uint8_t bandStartChannel, bandEndChannel;
7098
7099 con_sap_st_ch =
7100 con_sap_config->acs_cfg.start_ch;
7101 con_sap_end_ch =
7102 con_sap_config->acs_cfg.end_ch;
7103 cur_sap_st_ch = sap_config->acs_cfg.start_ch;
7104 cur_sap_end_ch = sap_config->acs_cfg.end_ch;
7105
7106 wlansap_extend_to_acs_range(
7107 &cur_sap_st_ch, &cur_sap_end_ch,
7108 &bandStartChannel, &bandEndChannel);
7109
7110 wlansap_extend_to_acs_range(
7111 &con_sap_st_ch, &con_sap_end_ch,
7112 &bandStartChannel, &bandEndChannel);
7113
7114 if (con_sap_st_ch <= cur_sap_st_ch &&
7115 con_sap_end_ch >= cur_sap_end_ch) {
7116 sap_config->acs_cfg.skip_scan_status =
7117 eSAP_SKIP_ACS_SCAN;
7118
7119 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7120 con_sap_end_ch >= cur_sap_end_ch) {
7121 sap_config->acs_cfg.skip_scan_status =
7122 eSAP_DO_PAR_ACS_SCAN;
7123
7124 sap_config->acs_cfg.skip_scan_range1_stch =
7125 cur_sap_st_ch;
7126 sap_config->acs_cfg.skip_scan_range1_endch =
7127 con_sap_st_ch - 1;
7128 sap_config->acs_cfg.skip_scan_range2_stch =
7129 0;
7130 sap_config->acs_cfg.skip_scan_range2_endch =
7131 0;
7132
7133 } else if (con_sap_st_ch <= cur_sap_st_ch &&
7134 con_sap_end_ch <= cur_sap_end_ch) {
7135 sap_config->acs_cfg.skip_scan_status =
7136 eSAP_DO_PAR_ACS_SCAN;
7137
7138 sap_config->acs_cfg.skip_scan_range1_stch =
7139 con_sap_end_ch + 1;
7140 sap_config->acs_cfg.skip_scan_range1_endch =
7141 cur_sap_end_ch;
7142 sap_config->acs_cfg.skip_scan_range2_stch =
7143 0;
7144 sap_config->acs_cfg.skip_scan_range2_endch =
7145 0;
7146
7147 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7148 con_sap_end_ch <= cur_sap_end_ch) {
7149 sap_config->acs_cfg.skip_scan_status =
7150 eSAP_DO_PAR_ACS_SCAN;
7151
7152 sap_config->acs_cfg.skip_scan_range1_stch =
7153 cur_sap_st_ch;
7154 sap_config->acs_cfg.skip_scan_range1_endch =
7155 con_sap_st_ch - 1;
7156 sap_config->acs_cfg.skip_scan_range2_stch =
7157 con_sap_end_ch;
7158 sap_config->acs_cfg.skip_scan_range2_endch =
7159 cur_sap_end_ch + 1;
7160
7161 } else
7162 sap_config->acs_cfg.skip_scan_status =
7163 eSAP_DO_NEW_ACS_SCAN;
7164
7165
7166 hddLog(LOG1, FL(
7167 "SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d"),
7168 sap_config->acs_cfg.skip_scan_status,
7169 sap_config->acs_cfg.skip_scan_range1_stch,
7170 sap_config->acs_cfg.skip_scan_range1_endch,
7171 sap_config->acs_cfg.skip_scan_range2_stch,
7172 sap_config->acs_cfg.skip_scan_range2_endch);
7173 }
7174 }
7175#endif
7176
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307177 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007178}
7179
7180/**
7181 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
7182 * @adapter: pointer to adapter struct
7183 *
7184 * This function overrides SAP / P2P Go configuration based on driver INI
7185 * parameters for 11AC override and ACS. This overrides are done to support
7186 * android legacy configuration method.
7187 *
7188 * NOTE: Non android platform supports concurrency and these overrides shall
7189 * not be used. Also future driver based overrides shall be consolidated in this
7190 * function only. Avoid random overrides in other location based on ini.
7191 *
7192 * Return: 0 for Success or Negative error codes.
7193 */
7194int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
7195{
7196 tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
7197 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
7198 tHalHandle h_hal = WLAN_HDD_GET_HAL_CTX(ap_adapter);
7199
7200 if (ap_adapter->device_mode == WLAN_HDD_SOFTAP &&
7201 hdd_ctx->config->force_sap_acs)
7202 goto setup_acs_overrides;
7203
7204 /* Fixed channel 11AC override:
7205 * 11AC override in qcacld is introduced for following reasons:
7206 * 1. P2P GO also follows start_bss and since p2p GO could not be
7207 * configured to setup VHT channel width in wpa_supplicant
7208 * 2. Android UI does not provide advanced configuration options for SAP
7209 *
7210 * Default override enabled (for android). MDM shall disable this in ini
7211 */
7212 if (hdd_ctx->config->sap_p2p_11ac_override &&
7213 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7214 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7215 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)) {
7216 hddLog(LOG1, FL("** Driver force 11AC override for SAP/Go **"));
7217
7218 /* 11n only shall not be overridden since it may be on purpose*/
7219 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
7220 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7221
7222 if (sap_cfg->channel >= 36)
7223 sap_cfg->ch_width_orig =
7224 hdd_ctx->config->vhtChannelWidth;
7225 else
7226 sap_cfg->ch_width_orig =
7227 hdd_ctx->config->nChannelBondingMode24GHz ?
7228 eHT_CHANNEL_WIDTH_40MHZ :
7229 eHT_CHANNEL_WIDTH_20MHZ;
7230 }
7231 sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
7232 sme_set_ch_params(h_hal, sap_cfg->SapHw_mode, sap_cfg->channel,
7233 sap_cfg->sec_ch, &sap_cfg->ch_params);
7234
7235 return 0;
7236
7237setup_acs_overrides:
7238 hddLog(LOGE, FL("** Driver force ACS override **"));
7239
7240 sap_cfg->channel = AUTO_CHANNEL_SELECT;
7241 sap_cfg->acs_cfg.acs_mode = true;
7242 sap_cfg->acs_cfg.start_ch = hdd_ctx->config->force_sap_acs_st_ch;
7243 sap_cfg->acs_cfg.end_ch = hdd_ctx->config->force_sap_acs_end_ch;
7244
7245 if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.end_ch) {
7246 hddLog(LOGE, FL("Driver force ACS start ch (%d) > end ch (%d)"),
7247 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7248 return -EINVAL;
7249 }
7250
7251 /* Derive ACS HW mode */
7252 sap_cfg->SapHw_mode = hdd_cfg_xlate_to_csr_phy_mode(
7253 hdd_ctx->config->dot11Mode);
7254 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_AUTO)
7255 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7256
7257 if ((sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11b ||
7258 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g ||
7259 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
7260 sap_cfg->acs_cfg.start_ch > 14) {
7261 hddLog(LOGE, FL("Invalid ACS HW Mode %d + CH range <%d - %d>"),
7262 sap_cfg->SapHw_mode, sap_cfg->acs_cfg.start_ch,
7263 sap_cfg->acs_cfg.end_ch);
7264 return -EINVAL;
7265 }
7266 sap_cfg->acs_cfg.hw_mode = sap_cfg->SapHw_mode;
7267
7268 /* Derive ACS BW */
7269 sap_cfg->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
7270 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7271 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) {
7272
7273 sap_cfg->ch_width_orig = hdd_ctx->config->vhtChannelWidth;
7274 /* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
7275 if (sap_cfg->acs_cfg.end_ch <= 14)
7276 sap_cfg->ch_width_orig =
7277 hdd_ctx->config->nChannelBondingMode24GHz ?
7278 eHT_CHANNEL_WIDTH_40MHZ :
7279 eHT_CHANNEL_WIDTH_20MHZ;
7280 }
7281
7282 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7283 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY) {
7284 if (sap_cfg->acs_cfg.end_ch <= 14)
7285 sap_cfg->ch_width_orig =
7286 hdd_ctx->config->nChannelBondingMode24GHz ?
7287 eHT_CHANNEL_WIDTH_40MHZ :
7288 eHT_CHANNEL_WIDTH_20MHZ;
7289 else
7290 sap_cfg->ch_width_orig =
7291 hdd_ctx->config->nChannelBondingMode5GHz ?
7292 eHT_CHANNEL_WIDTH_40MHZ :
7293 eHT_CHANNEL_WIDTH_20MHZ;
7294 }
7295 sap_cfg->acs_cfg.ch_width = sap_cfg->ch_width_orig;
7296
7297 hddLog(LOG1, FL("Force ACS Config: HW_MODE: %d ACS_BW: %d"),
7298 sap_cfg->acs_cfg.hw_mode, sap_cfg->acs_cfg.ch_width);
7299 hddLog(LOG1, FL("Force ACS Config: ST_CH: %d END_CH: %d"),
7300 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7301
7302 return 0;
7303}
7304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007305/**
7306 * wlan_hdd_cfg80211_start_bss() - start bss
7307 * @pHostapdAdapter: Pointer to hostapd adapter
7308 * @params: Pointer to start bss beacon parameters
7309 * @ssid: Pointer ssid
7310 * @ssid_len: Length of ssid
7311 * @hidden_ssid: Hidden SSID parameter
7312 *
7313 * Return: 0 for success non-zero for failure
7314 */
7315static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7316 struct cfg80211_beacon_data *params,
7317 const u8 *ssid, size_t ssid_len,
7318 enum nl80211_hidden_ssid hidden_ssid)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007319{
7320 tsap_Config_t *pConfig;
7321 beacon_data_t *pBeacon = NULL;
7322 struct ieee80211_mgmt *pMgmt_frame;
7323 uint8_t *pIe = NULL;
7324 uint16_t capab_info;
7325 eCsrAuthType RSNAuthType;
7326 eCsrEncryptionType RSNEncryptType;
7327 eCsrEncryptionType mcRSNEncryptType;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307328 int status = QDF_STATUS_SUCCESS, ret;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307329 int qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007330 tpWLAN_SAPEventCB pSapEventCallback;
7331 hdd_hostapd_state_t *pHostapdState;
7332#ifndef WLAN_FEATURE_MBSSID
7333 v_CONTEXT_t p_cds_context =
7334 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
7335#endif
7336 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
7337 struct qc_mac_acl_entry *acl_entry = NULL;
7338 int32_t i;
7339 struct hdd_config *iniConfig;
7340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
7341 tSmeConfigParams sme_config;
7342 bool MFPCapable = false;
7343 bool MFPRequired = false;
7344 uint16_t prev_rsn_length = 0;
7345 ENTER();
7346
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007347 if (cds_is_connection_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007348 hdd_err("Can't start BSS: connection is in progress");
7349 return -EINVAL;
7350 }
7351
7352 iniConfig = pHddCtx->config;
7353 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7354
7355 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
7356 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
7357
7358 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7359
7360 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7361
7362 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
7363
7364 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7365
7366 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
7367
7368 /* channel is already set in the set_channel Call back */
7369 /* pConfig->channel = pCommitConfig->channel; */
7370
7371 /* Protection parameter to enable or disable */
7372 pConfig->protEnabled = iniConfig->apProtEnabled;
7373
7374 pConfig->dtim_period = pBeacon->dtim_period;
7375
7376 hddLog(LOG2, FL("****pConfig->dtim_period=%d***"),
7377 pConfig->dtim_period);
7378
7379 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
7380 pIe =
7381 wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail,
7382 pBeacon->tail_len,
7383 WLAN_EID_COUNTRY);
7384 if (pIe) {
7385 pConfig->ieee80211d = 1;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307386 qdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007387 sme_set_reg_info(hHal, pConfig->countryCode);
7388 sme_apply_channel_power_info_to_fw(hHal);
7389 } else {
7390 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7391 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7392 pConfig->ieee80211d = 0;
7393 }
7394
7395 ret = wlan_hdd_sap_cfg_dfs_override(pHostapdAdapter);
7396 if (ret < 0) {
7397 return ret;
7398 } else {
7399 if (ret == 0) {
7400 if (CDS_IS_DFS_CH(pConfig->channel))
7401 pHddCtx->dev_dfs_cac_status =
7402 DFS_CAC_NEVER_DONE;
7403 }
7404 }
7405
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307406 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007407 wlan_hdd_validate_operation_channel(pHostapdAdapter,
7408 pConfig->channel)) {
7409 hddLog(LOGE, FL("Invalid Channel [%d]"),
7410 pConfig->channel);
7411 return -EINVAL;
7412 }
7413
7414 /* reject SAP if DFS channel scan is not allowed */
7415 if (!(pHddCtx->config->enableDFSChnlScan) &&
7416 (CHANNEL_STATE_DFS == cds_get_channel_state(
7417 pConfig->channel))) {
7418 hddLog(LOGE,
7419 FL("not allowed to start SAP on DFS channel"));
7420 return -EOPNOTSUPP;
7421 }
7422 wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC);
7423 wlansap_set_dfs_restrict_japan_w53(hHal,
7424 iniConfig->gDisableDfsJapanW53);
7425 wlansap_set_dfs_preferred_channel_location(hHal,
7426 iniConfig->gSapPreferredChanLocation);
7427#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
7428 wlan_sap_set_channel_avoidance(hHal,
7429 iniConfig->sap_channel_avoidance);
7430#endif
7431 } else if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7432 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7433 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7434 pConfig->ieee80211d = 0;
7435 } else {
7436 pConfig->ieee80211d = 0;
7437 }
7438
7439 capab_info = pMgmt_frame->u.beacon.capab_info;
7440
7441 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
7442 WLAN_CAPABILITY_PRIVACY) ? true : false;
7443
7444 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7445
7446 /*Set wps station to configured */
7447 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7448
7449 if (pIe) {
7450 if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) {
7451 hddLog(LOGE,
7452 FL("**Wps Ie Length is too small***"));
7453 return -EINVAL;
7454 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
7455 0) {
7456 hddLog(LOG1, FL("** WPS IE(len %d) ***"), (pIe[1] + 2));
7457 /* Check 15 bit of WPS IE as it contain information for
7458 * wps state
7459 */
7460 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
7461 pConfig->wps_state =
7462 SAP_WPS_ENABLED_UNCONFIGURED;
7463 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
7464 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7465 }
7466 }
7467 } else {
7468 hdd_info("WPS disabled");
7469 pConfig->wps_state = SAP_WPS_DISABLED;
7470 }
7471 /* Forward WPS PBC probe request frame up */
7472 pConfig->fwdWPSPBCProbeReq = 1;
7473
7474 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7475 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7476 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7477 eCSR_ENCRYPT_TYPE_NONE;
7478
7479 pConfig->RSNWPAReqIELength = 0;
7480 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
7481 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7482 WLAN_EID_RSN);
7483 if (pIe && pIe[1]) {
7484 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7485 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
7486 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7487 pConfig->RSNWPAReqIELength);
7488 else
7489 hddLog(LOGE,
7490 FL("RSNWPA IE MAX Length exceeded; length =%d"),
7491 pConfig->RSNWPAReqIELength);
7492 /* The actual processing may eventually be more extensive than
7493 * this. Right now, just consume any PMKIDs that are sent in
7494 * by the app.
7495 * */
7496 status =
7497 hdd_softap_unpack_ie(cds_get_context
Anurag Chouhan6d760662016-02-20 16:05:43 +05307498 (QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007499 &RSNEncryptType, &mcRSNEncryptType,
7500 &RSNAuthType, &MFPCapable,
7501 &MFPRequired,
7502 pConfig->RSNWPAReqIE[1] + 2,
7503 pConfig->RSNWPAReqIE);
7504
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307505 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007506 /* Now copy over all the security attributes you have
7507 * parsed out. Use the cipher type in the RSN IE
7508 */
7509 pConfig->RSNEncryptType = RSNEncryptType;
7510 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7511 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7512 ucEncryptType = RSNEncryptType;
7513 hddLog(LOG1,
7514 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7515 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7516 }
7517 }
7518
7519 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7520 pBeacon->tail, pBeacon->tail_len);
7521
7522 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
7523 if (pConfig->RSNWPAReqIE[0]) {
7524 /*Mixed mode WPA/WPA2 */
7525 prev_rsn_length = pConfig->RSNWPAReqIELength;
7526 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7527 if (pConfig->RSNWPAReqIELength <
7528 sizeof(pConfig->RSNWPAReqIE))
7529 memcpy(&pConfig->RSNWPAReqIE[0] +
7530 prev_rsn_length, pIe, pIe[1] + 2);
7531 else
7532 hddLog(LOGE,
7533 "RSNWPA IE MAX Length exceeded; length =%d",
7534 pConfig->RSNWPAReqIELength);
7535 } else {
7536 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7537 if (pConfig->RSNWPAReqIELength <
7538 sizeof(pConfig->RSNWPAReqIE))
7539 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7540 pConfig->RSNWPAReqIELength);
7541 else
7542 hddLog(LOGE,
7543 "RSNWPA IE MAX Length exceeded; length =%d",
7544 pConfig->RSNWPAReqIELength);
7545 status = hdd_softap_unpack_ie
Anurag Chouhan6d760662016-02-20 16:05:43 +05307546 (cds_get_context(QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007547 &RSNEncryptType,
7548 &mcRSNEncryptType, &RSNAuthType,
7549 &MFPCapable, &MFPRequired,
7550 pConfig->RSNWPAReqIE[1] + 2,
7551 pConfig->RSNWPAReqIE);
7552
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307553 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007554 /* Now copy over all the security attributes
7555 * you have parsed out. Use the cipher type
7556 * in the RSN IE
7557 */
7558 pConfig->RSNEncryptType = RSNEncryptType;
7559 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7560 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7561 ucEncryptType = RSNEncryptType;
7562 hddLog(LOG1,
7563 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7564 RSNAuthType, RSNEncryptType,
7565 mcRSNEncryptType);
7566 }
7567 }
7568 }
7569
7570 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
7571 hddLog(LOGE,
7572 FL("**RSNWPAReqIELength is too large***"));
7573 return -EINVAL;
7574 }
7575
7576 pConfig->SSIDinfo.ssidHidden = false;
7577
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007578 if (ssid != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307579 qdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007580 pConfig->SSIDinfo.ssid.length = ssid_len;
7581
7582 switch (hidden_ssid) {
7583 case NL80211_HIDDEN_SSID_NOT_IN_USE:
7584 hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
7585 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
7586 break;
7587 case NL80211_HIDDEN_SSID_ZERO_LEN:
7588 hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
7589 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
7590 break;
7591 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
7592 hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
7593 pConfig->SSIDinfo.ssidHidden =
7594 eHIDDEN_SSID_ZERO_CONTENTS;
7595 break;
7596 default:
7597 hddLog(LOGE, "Wrong hidden_ssid param %d", hidden_ssid);
7598 break;
7599 }
7600 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007601
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307602 qdf_mem_copy(pConfig->self_macaddr.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007603 pHostapdAdapter->macAddressCurrent.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05307604 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007605
7606 /* default value */
7607 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7608 pConfig->num_accept_mac = 0;
7609 pConfig->num_deny_mac = 0;
7610#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
7611 /*
7612 * We don't want P2PGO to follow STA's channel
7613 * so lets limit the logic for SAP only.
7614 * Later if we decide to make p2pgo follow STA's
7615 * channel then remove this check.
7616 */
7617 if ((0 == pHddCtx->config->conc_custom_rule1) ||
7618 (pHddCtx->config->conc_custom_rule1 &&
7619 WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode))
7620 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
7621#endif
7622
7623 pIe =
7624 wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE,
7625 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7626 pBeacon->tail_len);
7627
7628 /* pIe for black list is following form:
7629 * type : 1 byte
7630 * length : 1 byte
7631 * OUI : 4 bytes
7632 * acl type : 1 byte
7633 * no of mac addr in black list: 1 byte
7634 * list of mac_acl_entries: variable, 6 bytes per mac
7635 * address + sizeof(int) for vlan id
7636 */
7637 if ((pIe != NULL) && (pIe[1] != 0)) {
7638 pConfig->SapMacaddr_acl = pIe[6];
7639 pConfig->num_deny_mac = pIe[7];
7640 hddLog(LOG1,
7641 FL("acl type = %d no deny mac = %d"), pIe[6], pIe[7]);
7642 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7643 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
7644 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7645 for (i = 0; i < pConfig->num_deny_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307646 qdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007647 sizeof(qcmacaddr));
7648 acl_entry++;
7649 }
7650 }
7651 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE,
7652 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7653 pBeacon->tail_len);
7654
7655 /* pIe for white list is following form:
7656 * type : 1 byte
7657 * length : 1 byte
7658 * OUI : 4 bytes
7659 * acl type : 1 byte
7660 * no of mac addr in white list: 1 byte
7661 * list of mac_acl_entries: variable, 6 bytes per mac
7662 * address + sizeof(int) for vlan id
7663 */
7664 if ((pIe != NULL) && (pIe[1] != 0)) {
7665 pConfig->SapMacaddr_acl = pIe[6];
7666 pConfig->num_accept_mac = pIe[7];
7667 hddLog(LOG1, FL("acl type = %d no accept mac = %d"),
7668 pIe[6], pIe[7]);
7669 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7670 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
7671 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7672 for (i = 0; i < pConfig->num_accept_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307673 qdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007674 sizeof(qcmacaddr));
7675 acl_entry++;
7676 }
7677 }
7678
7679 wlan_hdd_set_sap_hwmode(pHostapdAdapter);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307680 qdf_mem_zero(&sme_config, sizeof(tSmeConfigParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007681 sme_get_config_param(pHddCtx->hHal, &sme_config);
7682 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
7683 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
7684 * may not be good with non QOS 11N AP
7685 * Default: enable QOS for SAP unless WMM IE not present for 11bga
7686 */
7687 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
7688 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
7689 pBeacon->tail, pBeacon->tail_len);
7690 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
7691 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
7692 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
7693 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
7694 sme_update_config(pHddCtx->hHal, &sme_config);
7695
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007696 if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80P80) {
7697 if (pHddCtx->isVHT80Allowed == false)
7698 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7699 else
7700 pConfig->ch_width_orig = CH_WIDTH_80P80MHZ;
7701 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_160) {
7702 if (pHddCtx->isVHT80Allowed == false)
7703 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7704 else
7705 pConfig->ch_width_orig = CH_WIDTH_160MHZ;
7706 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80) {
7707 if (pHddCtx->isVHT80Allowed == false)
7708 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7709 else
7710 pConfig->ch_width_orig = CH_WIDTH_80MHZ;
7711 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40) {
7712 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7713 } else {
7714 pConfig->ch_width_orig = CH_WIDTH_20MHZ;
7715 }
7716
7717 if (wlan_hdd_setup_driver_overrides(pHostapdAdapter))
7718 return -EINVAL;
7719
7720 /* ht_capab is not what the name conveys,this is used for protection
7721 * bitmap */
7722 pConfig->ht_capab = iniConfig->apProtection;
7723
7724 if (0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter)) {
7725 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7726 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7727 return -EINVAL;
7728 }
7729 /* Uapsd Enabled Bit */
7730 pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
7731 /* Enable OBSS protection */
7732 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
7733
7734 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7735 pConfig->sap_dot11mc =
7736 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->sap_dot11mc;
7737 else /* for P2P-Go case */
7738 pConfig->sap_dot11mc = 1;
7739
7740 hddLog(LOG1, FL("11MC Support Enabled : %d\n"),
7741 pConfig->sap_dot11mc);
7742
7743#ifdef WLAN_FEATURE_11W
7744 pConfig->mfpCapable = MFPCapable;
7745 pConfig->mfpRequired = MFPRequired;
7746 hddLog(LOG1, FL("Soft AP MFP capable %d, MFP required %d"),
7747 pConfig->mfpCapable, pConfig->mfpRequired);
7748#endif
7749
7750 hddLog(LOGW, FL("SOftAP macaddress : " MAC_ADDRESS_STR),
7751 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
7752 hddLog(LOGW, FL("ssid =%s, beaconint=%d, channel=%d"),
7753 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7754 (int)pConfig->channel);
7755 hddLog(LOGW, FL("hw_mode=%x, privacy=%d, authType=%d"),
7756 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
7757 hddLog(LOGW, FL("RSN/WPALen=%d, Uapsd = %d"),
7758 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7759 hddLog(LOGW, FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7760 pConfig->protEnabled, pConfig->obssProtEnabled);
7761
7762 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
7763 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7764 /* Bss already started. just return. */
7765 /* TODO Probably it should update some beacon params. */
7766 hddLog(LOGE, "Bss Already started...Ignore the request");
7767 EXIT();
7768 return 0;
7769 }
7770
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007771 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007772 cds_convert_device_mode_to_hdd_type(
7773 pHostapdAdapter->device_mode),
7774 pConfig->channel, HW_MODE_20_MHZ)) {
7775 hddLog(LOGW,
7776 FL("This concurrency combination is not allowed"));
7777 return -EINVAL;
7778 }
7779
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007780 if (!cds_set_connection_in_progress(true)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007781 hdd_err("Can't start BSS: set connnection in progress failed");
7782 return -EINVAL;
7783 }
7784
7785 pConfig->persona = pHostapdAdapter->device_mode;
7786
7787 pSapEventCallback = hdd_hostapd_sap_event_cb;
7788
7789 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = true;
7790
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307791 qdf_event_reset(&pHostapdState->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007792 status = wlansap_start_bss(
7793#ifdef WLAN_FEATURE_MBSSID
7794 WLAN_HDD_GET_SAP_CTX_PTR
7795 (pHostapdAdapter),
7796#else
7797 p_cds_context,
7798#endif
7799 pSapEventCallback, pConfig,
7800 pHostapdAdapter->dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307801 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007802 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007803 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007804 hddLog(LOGE, FL("SAP Start Bss fail"));
7805 return -EINVAL;
7806 }
7807
7808 hddLog(LOG1,
7809 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7810
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307811 qdf_status = qdf_wait_single_event(&pHostapdState->qdf_event, 10000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007812
7813 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7814
Anurag Chouhance0dc992016-02-16 18:18:03 +05307815 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007816 hddLog(LOGE,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307817 FL("ERROR: HDD qdf wait for single_event failed!!"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007818 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007819 sme_get_command_q_status(hHal);
7820#ifdef WLAN_FEATURE_MBSSID
7821 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
7822#else
7823 wlansap_stop_bss(p_cds_context);
7824#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307825 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007826 return -EINVAL;
7827 }
7828 /* Succesfully started Bss update the state bit. */
7829 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
7830 /* Initialize WMM configuation */
7831 hdd_wmm_init(pHostapdAdapter);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007832 cds_incr_active_session(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007833 pHostapdAdapter->sessionId);
7834#ifdef DHCP_SERVER_OFFLOAD
7835 if (iniConfig->enableDHCPServerOffload)
7836 wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
7837#endif /* DHCP_SERVER_OFFLOAD */
7838
7839#ifdef WLAN_FEATURE_P2P_DEBUG
7840 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7841 if (global_p2p_connection_status == P2P_GO_NEG_COMPLETED) {
7842 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7843 hddLog(LOGE,
7844 FL("[P2P State] From Go nego completed to Non-autonomous Group started"));
7845 } else if (global_p2p_connection_status == P2P_NOT_ACTIVE) {
7846 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7847 hddLog(LOGE,
7848 FL("[P2P State] From Inactive to Autonomous Group started"));
7849 }
7850 }
7851#endif
7852
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007853 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007854 pHostapdState->bCommit = true;
7855 EXIT();
7856
7857 return 0;
7858}
7859
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007860/**
7861 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
7862 * @wiphy: Pointer to wiphy structure
7863 * @dev: Pointer to net_device structure
7864 *
7865 * Return: 0 for success non-zero for failure
7866 */
7867static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7868 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007869{
7870 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7871 hdd_context_t *pHddCtx = NULL;
7872 hdd_scaninfo_t *pScanInfo = NULL;
7873 hdd_adapter_t *staAdapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307874 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307875 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007876 tSirUpdateIE updateIE;
7877 beacon_data_t *old;
7878 int ret;
7879 unsigned long rc;
7880 hdd_adapter_list_node_t *pAdapterNode = NULL;
7881 hdd_adapter_list_node_t *pNext = NULL;
7882
7883 ENTER();
7884
Anurag Chouhan6d760662016-02-20 16:05:43 +05307885 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007886 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7887 return -EINVAL;
7888 }
7889
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307890 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007891 TRACE_CODE_HDD_CFG80211_STOP_AP,
7892 pAdapter->sessionId, pAdapter->device_mode));
7893
7894 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7895 ret = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307896 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007897 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007898
7899 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
7900 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
7901 return -EOPNOTSUPP;
7902 }
7903
7904 hddLog(LOG1, FL("Device_mode %s(%d)"),
7905 hdd_device_mode_to_string(pAdapter->device_mode),
7906 pAdapter->device_mode);
7907
7908 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307909 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007910 staAdapter = pAdapterNode->pAdapter;
7911
7912 if (WLAN_HDD_INFRA_STATION == staAdapter->device_mode ||
7913 (WLAN_HDD_P2P_CLIENT == staAdapter->device_mode) ||
7914 (WLAN_HDD_P2P_GO == staAdapter->device_mode)) {
7915 pScanInfo = &staAdapter->scan_info;
7916
7917 if (pScanInfo && pScanInfo->mScanPending) {
7918 hddLog(LOG1, FL("Aborting pending scan for device mode:%d"),
7919 staAdapter->device_mode);
7920 INIT_COMPLETION(pScanInfo->abortscan_event_var);
7921 hdd_abort_mac_scan(staAdapter->pHddCtx,
7922 staAdapter->sessionId,
7923 eCSR_SCAN_ABORT_DEFAULT);
7924 rc = wait_for_completion_timeout(
7925 &pScanInfo->abortscan_event_var,
7926 msecs_to_jiffies(
7927 WLAN_WAIT_TIME_ABORTSCAN));
7928 if (!rc) {
7929 hddLog(LOGE,
7930 FL("Timeout occurred while waiting for abortscan"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307931 QDF_ASSERT(pScanInfo->mScanPending);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007932 }
7933 }
7934 }
7935
7936 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
7937 pAdapterNode = pNext;
7938 }
7939 /*
7940 * When ever stop ap adapter gets called, we need to check
7941 * whether any restart AP work is pending. If any restart is pending
7942 * then lets finish it and go ahead from there.
7943 */
7944 if (pHddCtx->config->conc_custom_rule1 &&
7945 (WLAN_HDD_SOFTAP == pAdapter->device_mode)) {
7946 cds_flush_work(&pHddCtx->sap_start_work);
7947 hddLog(LOGW, FL("Canceled the pending restart work"));
7948 spin_lock(&pHddCtx->sap_update_info_lock);
7949 pHddCtx->is_sap_restart_required = false;
7950 spin_unlock(&pHddCtx->sap_update_info_lock);
7951 }
7952 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
7953 if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307954 qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
7955 qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007956 sizeof(struct sap_acs_cfg));
7957 hdd_hostapd_stop(dev);
7958
7959 old = pAdapter->sessionCtx.ap.beacon;
7960 if (!old) {
7961 hddLog(LOGE,
7962 FL("Session(%d) beacon data points to NULL"),
7963 pAdapter->sessionId);
7964 return -EINVAL;
7965 }
7966
7967 hdd_cleanup_actionframe(pHddCtx, pAdapter);
7968
7969 mutex_lock(&pHddCtx->sap_lock);
7970 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) {
7971 hdd_hostapd_state_t *pHostapdState =
7972 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7973
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307974 qdf_event_reset(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007975#ifdef WLAN_FEATURE_MBSSID
7976 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter));
7977#else
7978 status = wlansap_stop_bss(pHddCtx->pcds_context);
7979#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307980 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05307981 qdf_status =
7982 qdf_wait_single_event(&pHostapdState->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307983 qdf_stop_bss_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007984 10000);
7985
Anurag Chouhance0dc992016-02-16 18:18:03 +05307986 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007987 hddLog(LOGE,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307988 FL("HDD qdf wait for single_event failed!!"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307989 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007990 }
7991 }
7992 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7993 /*BSS stopped, clear the active sessions for this device mode*/
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08007994 cds_decr_session_set_pcl(pAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007995 pAdapter->sessionId);
7996 pAdapter->sessionCtx.ap.beacon = NULL;
7997 kfree(old);
7998 }
7999 mutex_unlock(&pHddCtx->sap_lock);
8000
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308001 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008002 hddLog(LOGE, FL("Stopping the BSS"));
8003 return -EINVAL;
8004 }
8005
Anurag Chouhanc5548422016-02-24 18:33:27 +05308006 qdf_copy_macaddr(&updateIE.bssid, &pAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008007 updateIE.smeSessionId = pAdapter->sessionId;
8008 updateIE.ieBufferlength = 0;
8009 updateIE.pAdditionIEBuffer = NULL;
8010 updateIE.append = true;
8011 updateIE.notify = true;
8012 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
8013 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308014 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008015 hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
8016 }
8017
8018 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
8019 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308020 eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008021 hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE"));
8022 }
8023 /* Reset WNI_CFG_PROBE_RSP Flags */
8024 wlan_hdd_reset_prob_rspies(pAdapter);
8025
8026#ifdef WLAN_FEATURE_P2P_DEBUG
8027 if ((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8028 (global_p2p_connection_status == P2P_GO_COMPLETED_STATE)) {
8029 hddLog(LOGE,
8030 "[P2P State] From GO completed to Inactive state GO got removed");
8031 global_p2p_connection_status = P2P_NOT_ACTIVE;
8032 }
8033#endif
8034 EXIT();
8035 return ret;
8036}
8037
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008038/**
8039 * wlan_hdd_get_channel_bw() - get channel bandwidth
8040 * @width: input channel width in nl80211_chan_width value
8041 *
8042 * Return: channel width value defined by driver
8043 */
8044static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
8045 enum nl80211_chan_width width)
8046{
8047 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
8048
8049 switch (width) {
8050 case NL80211_CHAN_WIDTH_20_NOHT:
8051 case NL80211_CHAN_WIDTH_20:
8052 ch_bw = HW_MODE_20_MHZ;
8053 break;
8054 case NL80211_CHAN_WIDTH_40:
8055 ch_bw = HW_MODE_40_MHZ;
8056 break;
8057 case NL80211_CHAN_WIDTH_80:
8058 ch_bw = HW_MODE_80_MHZ;
8059 break;
8060 case NL80211_CHAN_WIDTH_80P80:
8061 ch_bw = HW_MODE_80_PLUS_80_MHZ;
8062 break;
8063 case NL80211_CHAN_WIDTH_160:
8064 ch_bw = HW_MODE_160_MHZ;
8065 break;
8066 default:
8067 hdd_err("Invalid width: %d, using default 20MHz", width);
8068 break;
8069 }
8070
8071 return ch_bw;
8072}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008073
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008074/**
8075 * wlan_hdd_cfg80211_stop_ap() - stop sap
8076 * @wiphy: Pointer to wiphy
8077 * @dev: Pointer to netdev
8078 *
8079 * Return: zero for success non-zero for failure
8080 */
8081int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8082 struct net_device *dev)
8083{
8084 int ret;
8085
8086 cds_ssr_protect(__func__);
8087 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8088 cds_ssr_unprotect(__func__);
8089
8090 return ret;
8091}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008092
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008093/**
8094 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
8095 * @wiphy: Pointer to wiphy structure
8096 * @dev: Pointer to net_device structure
8097 * @params: Pointer to AP settings parameters
8098 *
8099 * Return: 0 for success non-zero for failure
8100 */
8101static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8102 struct net_device *dev,
8103 struct cfg80211_ap_settings *params)
8104{
8105 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8106 hdd_context_t *pHddCtx;
Chandrasekaran, Manishekar96c90962015-11-20 16:47:45 +05308107 enum hw_mode_bandwidth channel_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008108 int status;
8109 uint8_t channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008110
8111 ENTER();
8112
Anurag Chouhan6d760662016-02-20 16:05:43 +05308113 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008114 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8115 return -EINVAL;
8116 }
8117
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308118 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008119 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8120 params->beacon_interval));
8121 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
8122 hddLog(LOGE, FL("HDD adapter magic is invalid"));
8123 return -ENODEV;
8124 }
8125
8126 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8127 status = wlan_hdd_validate_context(pHddCtx);
8128
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308129 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008130 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008131
8132 hddLog(LOG2, FL("pAdapter = %p, Device mode %s(%d)"), pAdapter,
8133 hdd_device_mode_to_string(pAdapter->device_mode),
8134 pAdapter->device_mode);
8135
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008136 channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
8137 channel = ieee80211_frequency_to_channel(
8138 params->chandef.chan->center_freq);
Amar Singhal01098f72015-10-08 11:55:32 -07008139
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008140 /* check if concurrency is allowed */
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008141 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008142 cds_convert_device_mode_to_hdd_type(
8143 pAdapter->device_mode),
8144 channel,
8145 channel_width)) {
8146 hdd_err("Connection failed due to concurrency check failure");
8147 return -EINVAL;
8148 }
8149 if (pHddCtx->config->policy_manager_enabled) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308150 status = qdf_reset_connection_update();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308151 if (!QDF_IS_STATUS_SUCCESS(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008152 hdd_err("ERR: clear event failed");
8153
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308154 status = cds_current_connections_update(pAdapter->sessionId,
8155 channel,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05308156 SIR_UPDATE_REASON_START_AP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308157 if (QDF_STATUS_E_FAILURE == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008158 hdd_err("ERROR: connections update failed!!");
8159 return -EINVAL;
8160 }
8161
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308162 if (QDF_STATUS_SUCCESS == status) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308163 status = qdf_wait_for_connection_update();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308164 if (!QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308165 hdd_err("ERROR: qdf wait for event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008166 return -EINVAL;
8167 }
8168 }
8169 }
8170
8171 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8172 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
8173 ) {
8174 beacon_data_t *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008175 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008176
8177 old = pAdapter->sessionCtx.ap.beacon;
8178
8179 if (old)
8180 return -EALREADY;
8181
8182 status =
8183 wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new,
8184 &params->beacon,
8185 params->dtim_period);
8186
8187 if (status != 0) {
8188 hddLog(LOGE, FL("Error!!! Allocating the new beacon"));
8189 return -EINVAL;
8190 }
8191 pAdapter->sessionCtx.ap.beacon = new;
8192
8193 if (params->chandef.width < NL80211_CHAN_WIDTH_80)
8194 channel_type = cfg80211_get_chandef_type(
8195 &(params->chandef));
8196 else
8197 channel_type = NL80211_CHAN_HT40PLUS;
8198
8199
8200 wlan_hdd_set_channel(wiphy, dev,
8201 &params->chandef,
8202 channel_type);
8203
8204 /* set authentication type */
8205 switch (params->auth_type) {
8206 case NL80211_AUTHTYPE_OPEN_SYSTEM:
8207 pAdapter->sessionCtx.ap.sapConfig.authType =
8208 eSAP_OPEN_SYSTEM;
8209 break;
8210 case NL80211_AUTHTYPE_SHARED_KEY:
8211 pAdapter->sessionCtx.ap.sapConfig.authType =
8212 eSAP_SHARED_KEY;
8213 break;
8214 default:
8215 pAdapter->sessionCtx.ap.sapConfig.authType =
8216 eSAP_AUTO_SWITCH;
8217 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008218 pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
8219 params->chandef.width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008220 status =
8221 wlan_hdd_cfg80211_start_bss(pAdapter,
8222 &params->beacon,
8223 params->ssid, params->ssid_len,
8224 params->hidden_ssid);
8225 }
8226
8227 EXIT();
8228 return status;
8229}
8230
8231/**
8232 * wlan_hdd_cfg80211_start_ap() - start sap
8233 * @wiphy: Pointer to wiphy
8234 * @dev: Pointer to netdev
8235 * @params: Pointer to start ap configuration parameters
8236 *
8237 * Return: zero for success non-zero for failure
8238 */
8239int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8240 struct net_device *dev,
8241 struct cfg80211_ap_settings *params)
8242{
8243 int ret;
8244
8245 cds_ssr_protect(__func__);
8246 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8247 cds_ssr_unprotect(__func__);
8248
8249 return ret;
8250}
8251
8252/**
8253 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
8254 * @wiphy: Pointer to wiphy structure
8255 * @dev: Pointer to net_device structure
8256 * @params: Pointer to change beacon parameters
8257 *
8258 * Return: 0 for success non-zero for failure
8259 */
8260static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8261 struct net_device *dev,
8262 struct cfg80211_beacon_data *params)
8263{
8264 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8265 hdd_context_t *pHddCtx;
8266 beacon_data_t *old, *new;
8267 int status;
8268
8269 ENTER();
8270
Anurag Chouhan6d760662016-02-20 16:05:43 +05308271 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008272 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8273 return -EINVAL;
8274 }
8275
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308276 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008277 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8278 pAdapter->sessionId, pAdapter->device_mode));
8279 hddLog(LOG1, FL("Device_mode %s(%d)"),
8280 hdd_device_mode_to_string(pAdapter->device_mode),
8281 pAdapter->device_mode);
8282
8283 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8284 status = wlan_hdd_validate_context(pHddCtx);
8285
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308286 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008287 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008288
8289 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
8290 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
8291 return -EOPNOTSUPP;
8292 }
8293
8294 old = pAdapter->sessionCtx.ap.beacon;
8295
8296 if (!old) {
8297 hddLog(LOGE, FL("session(%d) beacon data points to NULL"),
8298 pAdapter->sessionId);
8299 return -EINVAL;
8300 }
8301
8302 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8303
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308304 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008305 hddLog(LOGE, FL("new beacon alloc failed"));
8306 return -EINVAL;
8307 }
8308
8309 pAdapter->sessionCtx.ap.beacon = new;
8310 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
8311
8312 EXIT();
8313 return status;
8314}
8315
8316/**
8317 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
8318 * @wiphy: Pointer to wiphy
8319 * @dev: Pointer to netdev
8320 * @params: Pointer to change beacon parameters
8321 *
8322 * Return: zero for success non-zero for failure
8323 */
8324int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8325 struct net_device *dev,
8326 struct cfg80211_beacon_data *params)
8327{
8328 int ret;
8329
8330 cds_ssr_protect(__func__);
8331 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8332 cds_ssr_unprotect(__func__);
8333
8334 return ret;
8335}