blob: 8919893cb646b0341564d4e63f01b1ac391565a5 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
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 */
Jeff Johnson295189b2012-06-20 16:38:30 -070027
28/**========================================================================
29
30 \file wlan_hdd_hostapd.c
31 \brief WLAN Host Device Driver implementation
32
33 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
34
35 Qualcomm Confidential and Proprietary.
36
37 ========================================================================*/
38/**=========================================================================
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45 $Header:$ $DateTime: $ $Author: $
46
47
48 when who what, where, why
49 -------- --- --------------------------------------------------------
50 04/5/09 Shailender Created module.
51 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
52 ==========================================================================*/
53/*--------------------------------------------------------------------------
54 Include Files
55 ------------------------------------------------------------------------*/
56
57#include <linux/version.h>
58#include <linux/module.h>
59#include <linux/kernel.h>
60#include <linux/init.h>
61#include <linux/wireless.h>
62#include <linux/semaphore.h>
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -070063#include <linux/compat.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
66#include <linux/etherdevice.h>
67#include <wlan_hdd_includes.h>
68#include <qc_sap_ioctl.h>
69#include <wlan_hdd_hostapd.h>
70#include <sapApi.h>
71#include <sapInternal.h>
72#include <wlan_qct_tl.h>
73#include <wlan_hdd_softap_tx_rx.h>
74#include <wlan_hdd_main.h>
75#include <linux/netdevice.h>
76#include <linux/mmc/sdio_func.h>
77#include "wlan_nlink_common.h"
78#include "wlan_btc_svc.h"
79#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070080#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070081#include "cfgApi.h"
82#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070083
Leo Chang0b0e45a2013-12-15 15:18:55 -080084#ifdef FEATURE_WLAN_CH_AVOID
85#include "wcnss_wlan.h"
86#endif /* FEATURE_WLAN_CH_AVOID */
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Leo Chang0b0e45a2013-12-15 15:18:55 -080090
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define IS_UP(_dev) \
92 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
93#define IS_UP_AUTO(_ic) \
94 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
95#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -070096#define WE_GET_STA_INFO_SIZE 30
97/* WEXT limition: MAX allowed buf len for any *
98 * IW_PRIV_TYPE_CHAR is 2Kbytes *
99 */
100#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530102#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700103
Leo Chang0b0e45a2013-12-15 15:18:55 -0800104#ifdef FEATURE_WLAN_CH_AVOID
105/* Channle/Freqency table */
106extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
107safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
108{
109 /*CH , SAFE, default safe */
110 {1 , VOS_TRUE}, //RF_CHAN_1,
111 {2 , VOS_TRUE}, //RF_CHAN_2,
112 {3 , VOS_TRUE}, //RF_CHAN_3,
113 {4 , VOS_TRUE}, //RF_CHAN_4,
114 {5 , VOS_TRUE}, //RF_CHAN_5,
115 {6 , VOS_TRUE}, //RF_CHAN_6,
116 {7 , VOS_TRUE}, //RF_CHAN_7,
117 {8 , VOS_TRUE}, //RF_CHAN_8,
118 {9 , VOS_TRUE}, //RF_CHAN_9,
119 {10 , VOS_TRUE}, //RF_CHAN_10,
120 {11 , VOS_TRUE}, //RF_CHAN_11,
121 {12 , VOS_TRUE}, //RF_CHAN_12,
122 {13 , VOS_TRUE}, //RF_CHAN_13,
123 {14 , VOS_TRUE}, //RF_CHAN_14,
124 {240, VOS_TRUE}, //RF_CHAN_240,
125 {244, VOS_TRUE}, //RF_CHAN_244,
126 {248, VOS_TRUE}, //RF_CHAN_248,
127 {252, VOS_TRUE}, //RF_CHAN_252,
128 {208, VOS_TRUE}, //RF_CHAN_208,
129 {212, VOS_TRUE}, //RF_CHAN_212,
130 {216, VOS_TRUE}, //RF_CHAN_216,
131 {36 , VOS_TRUE}, //RF_CHAN_36,
132 {40 , VOS_TRUE}, //RF_CHAN_40,
133 {44 , VOS_TRUE}, //RF_CHAN_44,
134 {48 , VOS_TRUE}, //RF_CHAN_48,
135 {52 , VOS_TRUE}, //RF_CHAN_52,
136 {56 , VOS_TRUE}, //RF_CHAN_56,
137 {60 , VOS_TRUE}, //RF_CHAN_60,
138 {64 , VOS_TRUE}, //RF_CHAN_64,
139 {100, VOS_TRUE}, //RF_CHAN_100,
140 {104, VOS_TRUE}, //RF_CHAN_104,
141 {108, VOS_TRUE}, //RF_CHAN_108,
142 {112, VOS_TRUE}, //RF_CHAN_112,
143 {116, VOS_TRUE}, //RF_CHAN_116,
144 {120, VOS_TRUE}, //RF_CHAN_120,
145 {124, VOS_TRUE}, //RF_CHAN_124,
146 {128, VOS_TRUE}, //RF_CHAN_128,
147 {132, VOS_TRUE}, //RF_CHAN_132,
148 {136, VOS_TRUE}, //RF_CHAN_136,
149 {140, VOS_TRUE}, //RF_CHAN_140,
150 {149, VOS_TRUE}, //RF_CHAN_149,
151 {153, VOS_TRUE}, //RF_CHAN_153,
152 {157, VOS_TRUE}, //RF_CHAN_157,
153 {161, VOS_TRUE}, //RF_CHAN_161,
154 {165, VOS_TRUE}, //RF_CHAN_165,
155};
156#endif /* FEATURE_WLAN_CH_AVOID */
157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530158/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 * Function definitions
160 *-------------------------------------------------------------------------*/
161/**---------------------------------------------------------------------------
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530162
Jeff Johnson295189b2012-06-20 16:38:30 -0700163 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530164
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 This is called in response to ifconfig up
166
167 \param - dev Pointer to net_device structure
168
169 \return - 0 for success non-zero for failure
170
171 --------------------------------------------------------------------------*/
172int hdd_hostapd_open (struct net_device *dev)
173{
174 ENTER();
175
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530176 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
177 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 //Turn ON carrier state
179 netif_carrier_on(dev);
180 //Enable all Tx queues
181 netif_tx_start_all_queues(dev);
182
183 EXIT();
184 return 0;
185}
186/**---------------------------------------------------------------------------
187
188 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
189
190 This is called in response to ifconfig down
191
192 \param - dev Pointer to net_device structure
193
194 \return - 0 for success non-zero for failure
195
196 --------------------------------------------------------------------------*/
197int hdd_hostapd_stop (struct net_device *dev)
198{
199 ENTER();
200
201 //Stop all tx queues
202 netif_tx_disable(dev);
203
204 //Turn OFF carrier state
205 netif_carrier_off(dev);
206
207 EXIT();
208 return 0;
209}
210/**---------------------------------------------------------------------------
211
212 \brief hdd_hostapd_uninit() - HDD uninit function
213
214 This is called during the netdev unregister to uninitialize all data
215associated with the device
216
217 \param - dev Pointer to net_device structure
218
219 \return - void
220
221 --------------------------------------------------------------------------*/
222static void hdd_hostapd_uninit (struct net_device *dev)
223{
224 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
225
226 ENTER();
227
228 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
229 {
230 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
231
232 /* after uninit our adapter structure will no longer be valid */
233 pHostapdAdapter->dev = NULL;
234 }
235
236 EXIT();
237}
238
239
240/**============================================================================
241 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
242 transmitting packets. There are 2 versions of this function. One that uses
243 locked queue and other that uses lockless queues. Both have been retained to
244 do some performance testing
245 @param skb : [in] pointer to OS packet (sk_buff)
246 @param dev : [in] pointer to Libra network device
247
248 @return : NET_XMIT_DROP if packets are dropped
249 : NET_XMIT_SUCCESS if packet is enqueued succesfully
250 ===========================================================================*/
251int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
252{
253 return 0;
254}
255int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
256{
257 return 0;
258}
259
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700260static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
261 hdd_priv_data_t *priv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -0700262{
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700263 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530264 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
265 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700266 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530267 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700268 /*
269 * Note that valid pointers are provided by caller
270 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700271
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700272 if (priv_data->total_len <= 0 ||
273 priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
274 {
275 /* below we allocate one more byte for command buffer.
276 * To avoid addition overflow total_len should be
277 * smaller than INT_MAX. */
278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
279 __func__, priv_data->total_len);
280 ret = -EFAULT;
281 goto exit;
282 }
Kaushik, Sushant96122442014-10-21 16:40:18 +0530283 status = wlan_hdd_validate_context(pHddCtx);
284
285 if (0 != status)
286 {
287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
288 "%s: HDD context is not valid", __func__);
289 return status;
290 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700291
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700292 /* Allocate +1 for '\0' */
293 command = kmalloc((priv_data->total_len + 1), GFP_KERNEL);
294 if (!command)
295 {
296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__);
297 ret = -ENOMEM;
298 goto exit;
299 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700301 if (copy_from_user(command, priv_data->buf, priv_data->total_len))
302 {
303 ret = -EFAULT;
304 goto exit;
305 }
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800306
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700307 /* Make sure the command is NUL-terminated */
308 command[priv_data->total_len] = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -0700309
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700310 hddLog(VOS_TRACE_LEVEL_INFO,
311 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700313 if (strncmp(command, "P2P_SET_NOA", 11) == 0)
314 {
315 hdd_setP2pNoa(pAdapter->dev, command);
316 }
317 else if (strncmp(command, "P2P_SET_PS", 10) == 0)
318 {
319 hdd_setP2pOpps(pAdapter->dev, command);
320 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800321#ifdef FEATURE_WLAN_BATCH_SCAN
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700322 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
323 {
324 ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command);
325 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800326#endif
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700327 else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
328 {
329 /*
330 * command should be a string having format
331 * SET_SAP_CHANNEL_LIST <num channels> <channels seperated by spaces>
332 */
333 hddLog(VOS_TRACE_LEVEL_INFO,
334 "%s: Received Command to Set Preferred Channels for SAP",
335 __func__);
Rajeev Kumar8b373292014-01-08 20:36:55 -0800336
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700337 ret = sapSetPreferredChannel(command);
338 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530339 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
340 {
341 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
342 tANI_U8 filterType = 0;
343 tANI_U8 *value;
344 value = command + 9;
345
346 /* Convert the value from ascii to integer */
347 ret = kstrtou8(value, 10, &filterType);
348 if (ret < 0)
349 {
350 /* If the input value is greater than max value of datatype,
351 * then also kstrtou8 fails
352 */
353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
354 "%s: kstrtou8 failed range ", __func__);
355 ret = -EINVAL;
356 goto exit;
357 }
358 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
359 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
360 {
361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
362 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
363 " 2-Sink ", __func__);
364 ret = -EINVAL;
365 goto exit;
366 }
367 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
368 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530369 pScanInfo = &pHddCtx->scan_info;
370 if (filterType && pScanInfo != NULL &&
371 pHddCtx->scan_info.mScanPending)
372 {
373 /*Miracast Session started. Abort Scan */
374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
375 "%s, Aborting Scan For Miracast",__func__);
376 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
377 eCSR_SCAN_ABORT_DEFAULT);
378 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530379 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
380 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
381 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700382
Jeff Johnson295189b2012-06-20 16:38:30 -0700383exit:
384 if (command)
385 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700386 kfree(command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 }
388 return ret;
389}
390
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700391#ifdef CONFIG_COMPAT
392static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
393 struct ifreq *ifr)
394{
395 struct {
396 compat_uptr_t buf;
397 int used_len;
398 int total_len;
399 } compat_priv_data;
400 hdd_priv_data_t priv_data;
401 int ret = 0;
402
403 /*
404 * Note that pAdapter and ifr have already been verified by caller,
405 * and HDD context has also been validated
406 */
407 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
408 sizeof(compat_priv_data))) {
409 ret = -EFAULT;
410 goto exit;
411 }
412 priv_data.buf = compat_ptr(compat_priv_data.buf);
413 priv_data.used_len = compat_priv_data.used_len;
414 priv_data.total_len = compat_priv_data.total_len;
415 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
416 exit:
417 return ret;
418}
419#else /* CONFIG_COMPAT */
420static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
421 struct ifreq *ifr)
422{
423 /* will never be invoked */
424 return 0;
425}
426#endif /* CONFIG_COMPAT */
427
428static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
429{
430 hdd_priv_data_t priv_data;
431 int ret = 0;
432
433 /*
434 * Note that pAdapter and ifr have already been verified by caller,
435 * and HDD context has also been validated
436 */
437 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
438 ret = -EFAULT;
439 } else {
440 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
441 }
442 return ret;
443}
444
445static int hdd_hostapd_ioctl(struct net_device *dev,
446 struct ifreq *ifr, int cmd)
447{
448 hdd_adapter_t *pAdapter;
449 hdd_context_t *pHddCtx;
450 int ret;
451
452 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
453 if (NULL == pAdapter) {
454 hddLog(VOS_TRACE_LEVEL_ERROR,
455 "%s: HDD adapter context is Null", __func__);
456 ret = -ENODEV;
457 goto exit;
458 }
459 if (dev != pAdapter->dev) {
460 hddLog(VOS_TRACE_LEVEL_ERROR,
461 "%s: HDD adapter/dev inconsistency", __func__);
462 ret = -ENODEV;
463 goto exit;
464 }
465
466 if ((!ifr) || (!ifr->ifr_data)) {
467 ret = -EINVAL;
468 goto exit;
469 }
470
471 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
472 ret = wlan_hdd_validate_context(pHddCtx);
473 if (ret) {
474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__);
475 ret = -EBUSY;
476 goto exit;
477 }
478
479 switch (cmd) {
480 case (SIOCDEVPRIVATE + 1):
481 if (is_compat_task())
482 ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
483 else
484 ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
485 break;
486 default:
487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
488 __func__, cmd);
489 ret = -EINVAL;
490 break;
491 }
492 exit:
493 return ret;
494}
495
Jeff Johnson295189b2012-06-20 16:38:30 -0700496/**---------------------------------------------------------------------------
497
498 \brief hdd_hostapd_set_mac_address() -
499 This function sets the user specified mac address using
500 the command ifconfig wlanX hw ether <mac adress>.
501
502 \param - dev - Pointer to the net device.
503 - addr - Pointer to the sockaddr.
504 \return - 0 for success, non zero for failure
505
506 --------------------------------------------------------------------------*/
507
508static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
509{
510 struct sockaddr *psta_mac_addr = addr;
511 ENTER();
512 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
513 EXIT();
514 return 0;
515}
516void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
517{
518 struct net_device *dev = (struct net_device *)usrDataForCallback;
519 v_BYTE_t we_custom_event[64];
520 union iwreq_data wrqu;
521#ifdef DISABLE_CONCURRENCY_AUTOSAVE
522 VOS_STATUS vos_status;
523 hdd_adapter_t *pHostapdAdapter;
524 hdd_ap_ctx_t *pHddApCtx;
525#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
526
527 /* event_name space-delimiter driver_module_name */
528 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
529 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
530 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
531
532 ENTER();
533
Agarwal Ashish51325b52014-06-16 16:50:49 +0530534#ifdef DISABLE_CONCURRENCY_AUTOSAVE
535 if (vos_concurrent_open_sessions_running())
Jeff Johnson295189b2012-06-20 16:38:30 -0700536 {
537 /*
538 This timer routine is going to be called only when AP
539 persona is up.
540 If there are concurrent sessions running we do not want
541 to shut down the Bss.Instead we run the timer again so
542 that if Autosave is enabled next time and other session
543 was down only then we bring down AP
544 */
545 pHostapdAdapter = netdev_priv(dev);
546 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
547 vos_status = vos_timer_start(
548 &pHddApCtx->hdd_ap_inactivity_timer,
549 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
550 * 1000);
551 if (!VOS_IS_STATUS_SUCCESS(vos_status))
552 {
553 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
554 }
555 EXIT();
556 return;
557 }
558#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
559 memset(&we_custom_event, '\0', sizeof(we_custom_event));
560 memcpy(&we_custom_event, autoShutEvent, event_len);
561
562 memset(&wrqu, 0, sizeof(wrqu));
563 wrqu.data.length = event_len;
564
565 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
566 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
567
568 EXIT();
569}
570
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800571VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
572{
573 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
574 ptSapContext pSapCtx = NULL;
575 eHalStatus halStatus = eHAL_STATUS_FAILURE;
576 v_PVOID_t hHal = NULL;
577
578 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
579 "%s: UPDATE Beacon Params", __func__);
580
581 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
582 pSapCtx = VOS_GET_SAP_CB(pVosContext);
583 if ( NULL == pSapCtx )
584 {
585 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
586 "%s: Invalid SAP pointer from pvosGCtx", __func__);
587 return VOS_STATUS_E_FAULT;
588 }
589
590 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
591 if ( NULL == hHal ){
592 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
593 "%s: Invalid HAL pointer from pvosGCtx", __func__);
594 return VOS_STATUS_E_FAULT;
595 }
596 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
597 if(halStatus == eHAL_STATUS_FAILURE ){
598 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
599 "%s: Failed to update Beacon Params", __func__);
600 return VOS_STATUS_E_FAILURE;
601 }
602 }
603 return VOS_STATUS_SUCCESS;
604}
605
606void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
607{
608 v_U8_t staId = 0;
609 struct net_device *dev;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530610 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
611 ptSapContext pSapCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800612
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530613 dev = (struct net_device *)usrDataForCallback;
614 pSapCtx = VOS_GET_SAP_CB(pVosContext);
615 if(pSapCtx == NULL){
616 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
617 FL("psapCtx is NULL"));
618 return;
619 }
Arif Hussain6d2a3322013-11-17 19:50:10 -0800620 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800621 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
622 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530623 if ( pSapCtx->aStaInfo[staId].isUsed &&
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800624 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
625 {
626 //Disconnect all the stations
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530627 hdd_softap_sta_disassoc(pHostapdAdapter, &pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800628 }
629 }
630}
631
632static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
633{
634 struct net_device *dev;
Agarwal Ashish51325b52014-06-16 16:50:49 +0530635 hdd_context_t *pHddCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800636 VOS_STATUS status = VOS_STATUS_SUCCESS;
637 dev = (struct net_device *)usrDataForCallback;
638 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +0530639
640 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
641 status = wlan_hdd_validate_context(pHddCtx);
642
643 if (0 != status) {
644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
645 return status;
646 }
647
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800648 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
649 {
650 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
653 }
654 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +0530655 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800656 }
657 EXIT();
658 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
659}
Jeff Johnson295189b2012-06-20 16:38:30 -0700660
661VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
662{
663 hdd_adapter_t *pHostapdAdapter;
664 hdd_ap_ctx_t *pHddApCtx;
665 hdd_hostapd_state_t *pHostapdState;
666 struct net_device *dev;
667 eSapHddEvent sapEvent;
668 union iwreq_data wrqu;
669 v_BYTE_t *we_custom_event_generic = NULL;
670 int we_event = 0;
671 int i = 0;
672 v_U8_t staId;
673 VOS_STATUS vos_status;
674 v_BOOL_t bWPSState;
675 v_BOOL_t bApActive = FALSE;
676 v_BOOL_t bAuthRequired = TRUE;
677 tpSap_AssocMacAddr pAssocStasArray = NULL;
678 char unknownSTAEvent[IW_CUSTOM_MAX+1];
679 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
680 v_BYTE_t we_custom_start_event[64];
681 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800682 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800683 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700684 struct iw_michaelmicfailure msg;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530685 v_CONTEXT_t pVosContext = NULL;
686 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700687
688 dev = (struct net_device *)usrDataForCallback;
689 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530690
691 if ((NULL == pHostapdAdapter) ||
692 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
693 {
694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
695 "invalid adapter or adapter has invalid magic");
696 return eHAL_STATUS_FAILURE;
697 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530698 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
699 pSapCtx = VOS_GET_SAP_CB(pVosContext);
700 if(pSapCtx == NULL){
701 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
702 FL("psapCtx is NULL"));
703 return eHAL_STATUS_FAILURE;
704 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700705 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
706 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
707 sapEvent = pSapEvent->sapHddEventCode;
708 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800709 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700710
711 switch(sapEvent)
712 {
713 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800714 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700715 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
716 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
717 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
718
719 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
720 vos_status = vos_event_set(&pHostapdState->vosEvent);
721
722 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
723 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 goto stopbss;
726 }
727 else
728 {
729 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
730 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530731 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
732 if (!VOS_IS_STATUS_SUCCESS(vos_status))
733 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700734 }
735
736 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
737 {
738 // AP Inactivity timer init and start
739 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
740 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
741 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800742 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700743
744 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
745 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800746 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700747
748 }
749 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
750 pHostapdState->bssState = BSS_START;
751
752 // Send current operating channel of SoftAP to BTC-ES
753 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
754
Jeff Johnson295189b2012-06-20 16:38:30 -0700755 //Check if there is any group key pending to set.
756 if( pHddApCtx->groupKey.keyLength )
757 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700758 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700759 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
760 &pHddApCtx->groupKey ) )
761 {
762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
763 "%s: WLANSAP_SetKeySta failed", __func__);
764 }
765 pHddApCtx->groupKey.keyLength = 0;
766 }
767 else if ( pHddApCtx->wepKey[0].keyLength )
768 {
769 int i=0;
770 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
771 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700772 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700773 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
774 &pHddApCtx->wepKey[i] ) )
775 {
776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
777 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
778 }
779 pHddApCtx->wepKey[i].keyLength = 0;
780 }
781 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
783 startBssEvent = "SOFTAP.enabled";
784 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
785 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
786 memset(&wrqu, 0, sizeof(wrqu));
787 wrqu.data.length = strlen(startBssEvent);
788 we_event = IWEVCUSTOM;
789 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700790 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 break; //Event will be sent after Switch-Case stmt
792
793 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800794 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
796
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700797 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700798 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700799
Jeff Johnson295189b2012-06-20 16:38:30 -0700800 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700801 goto stopbss;
802 case eSAP_STA_SET_KEY_EVENT:
803 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800804 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
806 return VOS_STATUS_SUCCESS;
807 case eSAP_STA_DEL_KEY_EVENT:
808 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800809 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700810 return VOS_STATUS_SUCCESS;
811 case eSAP_STA_MIC_FAILURE_EVENT:
812 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 memset(&msg, '\0', sizeof(msg));
814 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800815 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800816 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700817 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 msg.flags = IW_MICFAILURE_GROUP;
819 else
820 msg.flags = IW_MICFAILURE_PAIRWISE;
821 memset(&wrqu, 0, sizeof(wrqu));
822 wrqu.data.length = sizeof(msg);
823 we_event = IWEVMICHAELMICFAILURE;
824 we_custom_event_generic = (v_BYTE_t *)&msg;
825 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 /* inform mic failure to nl80211 */
827 cfg80211_michael_mic_failure(dev,
828 pSapEvent->sapevt.
829 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700830 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700831 NL80211_KEYTYPE_GROUP :
832 NL80211_KEYTYPE_PAIRWISE),
833 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
834 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
835 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 break;
837
838 case eSAP_STA_ASSOC_EVENT:
839 case eSAP_STA_REASSOC_EVENT:
840 wrqu.addr.sa_family = ARPHRD_ETHER;
841 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800842 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800843 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 we_event = IWEVREGISTERED;
845
846 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
847
848 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
849 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
850 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
851 {
852 bAuthRequired = FALSE;
853 }
854
855 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
856 {
c_hpothuffdb5272013-10-02 16:42:35 +0530857 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700858 TRUE,
859 pHddApCtx->uPrivacy,
860 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
861 0,
862 0,
863 (v_MACADDR_t *)wrqu.addr.sa_data,
864 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530865
866 if (!VOS_IS_STATUS_SUCCESS(vos_status))
867 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
868 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700869 }
870 else
871 {
c_hpothuffdb5272013-10-02 16:42:35 +0530872 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 FALSE,
874 pHddApCtx->uPrivacy,
875 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
876 0,
877 0,
878 (v_MACADDR_t *)wrqu.addr.sa_data,
879 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530880 if (!VOS_IS_STATUS_SUCCESS(vos_status))
881 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
882 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Amar Singhal6144c002013-05-03 16:11:42 -0700883 }
884
Jeff Johnson295189b2012-06-20 16:38:30 -0700885 // Stop AP inactivity timer
886 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
887 {
888 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
889 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800890 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800892#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800893 if (wake_lock_active(&pHddCtx->sap_wake_lock))
894 {
895 wake_unlock(&pHddCtx->sap_wake_lock);
896 }
Amar Singhal6144c002013-05-03 16:11:42 -0700897 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
900 {
901 struct station_info staInfo;
902 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
903
904 memset(&staInfo, 0, sizeof(staInfo));
905 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
906 {
907 staInfo.assoc_req_ies =
908 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
909 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700911 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
912#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700913 cfg80211_new_sta(dev,
914 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
915 &staInfo, GFP_KERNEL);
916 }
917 else
918 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800919 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 }
921 }
922#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800923 pScanInfo = &pHddCtx->scan_info;
924 // Lets do abort scan to ensure smooth authentication for client
925 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
926 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +0530927 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530928 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800929 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700930
931 break;
932 case eSAP_STA_DISASSOC_EVENT:
933 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800934 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800935 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
937 hddLog(LOG1," User initiated disassociation");
938 else
939 hddLog(LOG1," MAC initiated disassociation");
940 we_event = IWEVEXPIRED;
941 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
942 if (!VOS_IS_STATUS_SUCCESS(vos_status))
943 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 return VOS_STATUS_E_FAILURE;
946 }
947 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
948
949 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
950 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530951 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 // Start AP inactivity timer if no stations associated with it
953 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
954 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530955 if (pSapCtx->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700956 {
957 bApActive = TRUE;
958 break;
959 }
960 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530961 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700962
963 if (bApActive == FALSE)
964 {
965 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
966 {
967 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
968 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800969 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 }
971 else
972 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
973 }
974 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
976 cfg80211_del_sta(dev,
977 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
978 GFP_KERNEL);
979#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800980 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +0530981 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
982 if (VOS_STATUS_SUCCESS != vos_status)
983 {
984 hddLog(LOGE, "%s: failed to update Beacon interval %d",
985 __func__, vos_status);
986 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 break;
988 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
989 {
990 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
991 union iwreq_data wreq;
992
993 down(&pHddApCtx->semWpsPBCOverlapInd);
994 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
995
996 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
997 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
998
999 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -08001000 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001001 memset(&wreq, 0, sizeof(wreq));
1002 wreq.data.length = strlen(message); // This is length of message
1003 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
1004
1005 return VOS_STATUS_SUCCESS;
1006 }
1007 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1008 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1009 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
1010 { // List of associated stations
1011 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
1012 {
1013 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
1014 i+1,
1015 pAssocStasArray->assocId,
1016 pAssocStasArray->staId,
1017 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
1018 pAssocStasArray++;
1019 }
1020 }
1021 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001022 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001024 case eSAP_INDICATE_MGMT_FRAME:
1025 hdd_indicateMgmtFrame( pHostapdAdapter,
1026 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
1027 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
1028 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05301029 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 return VOS_STATUS_SUCCESS;
1031 case eSAP_REMAIN_CHAN_READY:
1032 hdd_remainChanReadyHandler( pHostapdAdapter );
1033 return VOS_STATUS_SUCCESS;
1034 case eSAP_SEND_ACTION_CNF:
1035 hdd_sendActionCnf( pHostapdAdapter,
1036 ( eSAP_STATUS_SUCCESS ==
1037 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
1038 TRUE : FALSE );
1039 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001040 case eSAP_UNKNOWN_STA_JOIN:
1041 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1042 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1043 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1044 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1045 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1046 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1047 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1048 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1049 wrqu.data.pointer = unknownSTAEvent;
1050 wrqu.data.length = strlen(unknownSTAEvent);
1051 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +05301052 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001053 break;
1054
1055 case eSAP_MAX_ASSOC_EXCEEDED:
1056 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1057 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1058 " one or more devices to enable the new device connection",
1059 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1060 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1061 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1062 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1063 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1064 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
1065 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1066 wrqu.data.pointer = maxAssocExceededEvent;
1067 wrqu.data.length = strlen(maxAssocExceededEvent);
1068 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001069 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001070 break;
1071 case eSAP_STA_ASSOC_IND:
1072 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001073
1074 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001075 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001076 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
1077 return VOS_STATUS_SUCCESS;
1078
1079 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
c_hpothuffdb5272013-10-02 16:42:35 +05301080 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1081 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1082 {
1083 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1084 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001085 return VOS_STATUS_SUCCESS;
1086
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001088 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 goto stopbss;
1090 return VOS_STATUS_SUCCESS;
1091 }
1092 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1093 return VOS_STATUS_SUCCESS;
1094
1095stopbss :
1096 {
1097 v_BYTE_t we_custom_event[64];
1098 char *stopBssEvent = "STOP-BSS.response";//17
1099 int event_len = strlen(stopBssEvent);
1100
1101 hddLog(LOG1, FL("BSS stop status = %s"),
1102 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1103 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1104
1105 /* Change the BSS state now since, as we are shutting things down,
1106 * we don't want interfaces to become re-enabled */
1107 pHostapdState->bssState = BSS_STOP;
1108
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301109 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1110 {
1111 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1112 {
1113 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1114 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1115 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1116 }
1117
1118 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1119 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1120 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1121 }
1122
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 /* Stop the pkts from n/w stack as we are going to free all of
1124 * the TX WMM queues for all STAID's */
1125 hdd_hostapd_stop(dev);
1126
1127 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301128 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1129 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1130 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001131
Amar Singhal37e6f052013-03-05 16:16:54 -08001132 /* once the event is set, structure dev/pHostapdAdapter should
1133 * not be touched since they are now subject to being deleted
1134 * by another thread */
1135 if (eSAP_STOP_BSS_EVENT == sapEvent)
1136 vos_event_set(&pHostapdState->vosEvent);
1137
Jeff Johnson295189b2012-06-20 16:38:30 -07001138 /* notify userspace that the BSS has stopped */
1139 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1140 memcpy(&we_custom_event, stopBssEvent, event_len);
1141 memset(&wrqu, 0, sizeof(wrqu));
1142 wrqu.data.length = event_len;
1143 we_event = IWEVCUSTOM;
1144 we_custom_event_generic = we_custom_event;
1145 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001146 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001147 }
1148 return VOS_STATUS_SUCCESS;
1149}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001150
1151int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001153 eCsrEncryptionType *pEncryptType,
1154 eCsrEncryptionType *mcEncryptType,
1155 eCsrAuthType *pAuthType,
1156 v_BOOL_t *pMFPCapable,
1157 v_BOOL_t *pMFPRequired,
1158 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001159 u_int8_t *gen_ie )
1160{
1161 tDot11fIERSN dot11RSNIE;
1162 tDot11fIEWPA dot11WPAIE;
1163
1164 tANI_U8 *pRsnIe;
1165 tANI_U16 RSNIeLen;
1166
1167 if (NULL == halHandle)
1168 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001169 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 return -EINVAL;
1171 }
1172
1173 // Validity checks
1174 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1175 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1176 return -EINVAL;
1177 // Type check
1178 if ( gen_ie[0] == DOT11F_EID_RSN)
1179 {
1180 // Validity checks
1181 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1182 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1183 {
1184 return VOS_STATUS_E_FAILURE;
1185 }
1186 // Skip past the EID byte and length byte
1187 pRsnIe = gen_ie + 2;
1188 RSNIeLen = gen_ie_len - 2;
1189 // Unpack the RSN IE
1190 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1191 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1192 pRsnIe,
1193 RSNIeLen,
1194 &dot11RSNIE);
1195 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001196 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001197 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001198 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001199 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 /*Here we have followed the apple base code,
1201 but probably I suspect we can do something different*/
1202 //dot11RSNIE.akm_suite_count
1203 // Just translate the FIRST one
1204 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1205 //dot11RSNIE.pwise_cipher_suite_count
1206 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1207 //dot11RSNIE.gp_cipher_suite_count
1208 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1209 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001210 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1211 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001212
1213 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1214 } else
1215 if (gen_ie[0] == DOT11F_EID_WPA)
1216 {
1217 // Validity checks
1218 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1219 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1220 {
1221 return VOS_STATUS_E_FAILURE;
1222 }
1223 // Skip past the EID byte and length byte - and four byte WiFi OUI
1224 pRsnIe = gen_ie + 2 + 4;
1225 RSNIeLen = gen_ie_len - (2 + 4);
1226 // Unpack the WPA IE
1227 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1228 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1229 pRsnIe,
1230 RSNIeLen,
1231 &dot11WPAIE);
1232 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001233 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001234 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001235 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001236 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001237 //dot11WPAIE.auth_suite_count
1238 // Just translate the FIRST one
1239 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1240 //dot11WPAIE.unicast_cipher_count
1241 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1242 //dot11WPAIE.unicast_cipher_count
1243 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001244 *pMFPCapable = VOS_FALSE;
1245 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001246 }
1247 else
1248 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001249 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001250 return VOS_STATUS_E_FAILURE;
1251 }
1252 return VOS_STATUS_SUCCESS;
1253}
Leo Chang614d2072013-08-22 14:59:44 -07001254
Leo Chang0b0e45a2013-12-15 15:18:55 -08001255#ifdef FEATURE_WLAN_CH_AVOID
1256/**---------------------------------------------------------------------------
1257
1258 \brief hdd_hostapd_freq_to_chn() -
1259
1260 Input frequency translated into channel number
1261
1262 \param - freq input frequency with order of kHz
1263
1264 \return - corresponding channel number.
1265 incannot find correct channel number, return 0
1266
1267 --------------------------------------------------------------------------*/
1268v_U16_t hdd_hostapd_freq_to_chn
1269(
1270 v_U16_t freq
1271)
1272{
1273 int loop;
1274
1275 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1276 {
1277 if (rfChannels[loop].targetFreq == freq)
1278 {
1279 return rfChannels[loop].channelNum;
1280 }
1281 }
1282
1283 return (0);
1284}
1285
1286/*==========================================================================
1287 FUNCTION sapUpdateUnsafeChannelList
1288
1289 DESCRIPTION
1290 Function Undate unsafe channel list table
1291
1292 DEPENDENCIES
1293 NA.
1294
1295 PARAMETERS
1296
1297 IN
1298 pSapCtx : SAP context pointer, include unsafe channel list
1299
1300 RETURN VALUE
1301 NONE
1302============================================================================*/
1303void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1304 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1305{
1306 v_U16_t i, j;
1307
1308 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1309 sizeof(pHddCtx->unsafeChannelList));
1310 if (0 == unsafeChannelCount)
1311 {
1312 pHddCtx->unsafeChannelCount = 0;
1313 }
1314 else
1315 {
c_hpothu8de53e42014-08-22 15:00:37 +05301316 if (unsafeChannelCount > NUM_20MHZ_RF_CHANNELS)
1317 {
1318 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1319 FL("unsafeChannelCount%hd greater than %d"),
1320 unsafeChannelCount, NUM_20MHZ_RF_CHANNELS);
1321 unsafeChannelCount = NUM_20MHZ_RF_CHANNELS;
1322 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001323 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1324 unsafeChannelList,
1325 unsafeChannelCount * sizeof(tANI_U16));
1326 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1327 }
1328
1329 /* Flush, default set all channel safe */
1330 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1331 {
1332 safeChannels[i].isSafe = VOS_TRUE;
1333 }
1334
1335 /* Try to find unsafe channel */
1336 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1337 {
1338 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1339 {
1340 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1341 {
1342 /* Found unsafe channel, update it */
1343 safeChannels[j].isSafe = VOS_FALSE;
1344 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1345 "%s : CH %d is not safe",
1346 __func__, pHddCtx->unsafeChannelList[i]);
1347 break;
1348 }
1349 }
1350 }
1351
1352 return;
1353}
1354
1355/**---------------------------------------------------------------------------
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301356 \brief hdd_restart_softap() -
1357 Restart SAP on STA channel to support
1358 STA + SAP concurrency.
1359
1360 --------------------------------------------------------------------------*/
1361void hdd_restart_softap
1362(
1363 hdd_context_t *pHddCtx,
1364 hdd_adapter_t *pHostapdAdapter
1365)
1366{
1367 tSirChAvoidIndType *chAvoidInd;
1368
1369 chAvoidInd =
1370 (tSirChAvoidIndType *)vos_mem_malloc(sizeof(tSirChAvoidIndType));
1371 if (NULL == chAvoidInd)
1372 {
1373 hddLog(VOS_TRACE_LEVEL_INFO, FL("CH_AVOID IND buffer alloc Fail"));
1374 return ;
1375 }
1376 chAvoidInd->avoidRangeCount = 1;
1377 chAvoidInd->avoidFreqRange[0].startFreq =
1378 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1379 chAvoidInd->avoidFreqRange[0].endFreq =
1380 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1381 hdd_hostapd_ch_avoid_cb((void *)pHddCtx, (void *)chAvoidInd);
Girish Gowlic1725582014-07-31 20:37:35 +05301382 vos_mem_free(chAvoidInd);
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301383}
1384/**---------------------------------------------------------------------------
Leo Chang0b0e45a2013-12-15 15:18:55 -08001385
1386 \brief hdd_hostapd_ch_avoid_cb() -
1387
1388 Avoid channel notification from FW handler.
1389 FW will send un-safe channle list to avoid overwrapping.
1390 hostapd should not use notified channel
1391
1392 \param - pAdapter HDD adapter pointer
1393 indParam channel avoid notification parameter
1394
1395 \return - None
1396
1397 --------------------------------------------------------------------------*/
1398void hdd_hostapd_ch_avoid_cb
1399(
1400 void *pAdapter,
1401 void *indParam
1402)
1403{
1404 hdd_adapter_t *pHostapdAdapter = NULL;
1405 hdd_context_t *hddCtxt;
1406 tSirChAvoidIndType *chAvoidInd;
1407 v_U8_t rangeLoop;
1408 v_U16_t channelLoop;
1409 v_U16_t dupCheck;
1410 v_U16_t startChannel;
1411 v_U16_t endChannel;
1412 v_U16_t unsafeChannelCount = 0;
1413 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1414 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001415 tHddAvoidFreqList hddAvoidFreqList;
1416 tANI_U32 i;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001417
1418 /* Basic sanity */
1419 if ((NULL == pAdapter) || (NULL == indParam))
1420 {
1421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1422 "%s : Invalid arguments", __func__);
1423 return;
1424 }
1425
1426 hddCtxt = (hdd_context_t *)pAdapter;
1427 chAvoidInd = (tSirChAvoidIndType *)indParam;
1428 pVosContext = hddCtxt->pvosContext;
1429
1430 /* Make unsafe channel list */
1431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1432 "%s : band count %d",
1433 __func__, chAvoidInd->avoidRangeCount);
1434 vos_mem_zero((void *)unsafeChannelList,
1435 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1436 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1437 {
1438 startChannel = hdd_hostapd_freq_to_chn(
1439 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1440 endChannel = hdd_hostapd_freq_to_chn(
1441 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1443 "%s : start %d : %d, end %d : %d",
1444 __func__,
1445 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1446 startChannel,
1447 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1448 endChannel);
1449 for (channelLoop = startChannel;
1450 channelLoop < (endChannel + 1);
1451 channelLoop++)
1452 {
1453 /* Channel duplicate check routine */
1454 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1455 {
1456 if (unsafeChannelList[dupCheck] == channelLoop)
1457 {
1458 /* This channel is duplicated */
1459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1460 "%s : found duplicated channel %d",
1461 __func__, channelLoop);
1462 break;
1463 }
1464 }
1465 if (dupCheck == unsafeChannelCount)
1466 {
c_hpothu8de53e42014-08-22 15:00:37 +05301467 int ii;
1468 for(ii=0; ii<NUM_20MHZ_RF_CHANNELS; ii++)
1469 {
1470 if (channelLoop == safeChannels[ii].channelNumber)
1471 {
1472 unsafeChannelList[unsafeChannelCount] = channelLoop;
1473 unsafeChannelCount++;
1474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1475 "%s : unsafe channel %d, count %d",
1476 __func__,
1477 channelLoop, unsafeChannelCount);
1478 }
1479 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001480 }
1481 else
1482 {
1483 /* DUP, do nothing */
1484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1485 "%s : duplicated channel %d",
1486 __func__, channelLoop);
1487 }
1488 }
1489 }
1490 /* Update unsafe channel cache
1491 * WCN Platform Driver cache */
1492 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1493 unsafeChannelCount);
1494
1495 /* Store into local cache
1496 * Start with STA and later start SAP
1497 * in this scenario, local cache will be used */
1498 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1499 unsafeChannelList,
1500 unsafeChannelCount);
1501
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001502 /* generate vendor specific event */
1503 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1504 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1505 {
1506 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1507 chAvoidInd->avoidFreqRange[i].startFreq;
1508 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1509 chAvoidInd->avoidFreqRange[i].endFreq;
1510 }
1511 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1512
1513 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1514
Leo Chang0b0e45a2013-12-15 15:18:55 -08001515 /* Get SAP context first
1516 * SAP and P2PGO would not concurrent */
1517 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
1518 if ((pHostapdAdapter) && (unsafeChannelCount))
1519 {
1520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1521 "%s : Current operation channel %d",
1522 __func__,
1523 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1524 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1525 {
1526 if (((unsafeChannelList[channelLoop] ==
1527 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1528 (AUTO_CHANNEL_SELECT ==
1529 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1530 {
1531 /* current operating channel is un-safe channel
1532 * restart driver */
1533 hdd_hostapd_stop(pHostapdAdapter->dev);
Neelansh Mittaledafed22014-09-04 18:54:39 +05301534 /* On LE, this event is handled by wlan-services to restart SAP.
1535 On android, this event would be ignored. */
1536 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND, NULL, 0);
Leo Chang0b0e45a2013-12-15 15:18:55 -08001537 break;
1538 }
1539 }
1540 }
1541
1542 return;
1543}
1544
1545#endif /* FEATURE_WLAN_CH_AVOID */
1546
Jeff Johnson295189b2012-06-20 16:38:30 -07001547int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301548static __iw_softap_setparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001549 struct iw_request_info *info,
1550 union iwreq_data *wrqu, char *extra)
1551{
1552 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001553 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 int *value = (int *)extra;
1555 int sub_cmd = value[0];
1556 int set_value = value[1];
1557 eHalStatus status;
1558 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001559 v_CONTEXT_t pVosContext;
1560
1561 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1562 {
1563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1564 "%s: either hostapd Adapter is null or HDD ctx is null",
1565 __func__);
1566 return -1;
1567 }
1568
1569 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1570 if (!hHal)
1571 {
1572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1573 "%s: Hal ctx is null", __func__);
1574 return -1;
1575 }
1576
1577 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1578 if (!pVosContext)
1579 {
1580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1581 "%s: Vos ctx is null", __func__);
1582 return -1;
1583 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001584
1585 switch(sub_cmd)
1586 {
1587
1588 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001589 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001590 {
1591 ret = -EIO;
1592 }
1593 break;
1594
1595 case QCSAP_PARAM_ACL_MODE:
1596 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1597 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1598 {
1599 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1600 ret = -EINVAL;
1601 }
1602 else
1603 {
1604 WLANSAP_SetMode(pVosContext, set_value);
1605 }
1606 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301607
1608 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1609 if ((0 != set_value) && (1 != set_value))
1610 {
1611 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1612 ret = -EINVAL;
1613 }
1614 else
1615 {
1616 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1617 }
1618 break;
1619
Jeff Johnson295189b2012-06-20 16:38:30 -07001620 case QCSAP_PARAM_MAX_ASSOC:
1621 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1622 {
1623 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1624 ret = -EINVAL;
1625 }
1626 else
1627 {
1628 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1629 {
1630 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1631 "Setting it to max allowed and continuing"),
1632 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1633 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1634 }
1635 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1636 set_value, NULL, eANI_BOOLEAN_FALSE);
1637 if ( status != eHAL_STATUS_SUCCESS )
1638 {
1639 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1640 status);
1641 ret = -EIO;
1642 }
1643 }
1644 break;
1645
1646 case QCSAP_PARAM_HIDE_SSID:
1647 {
1648 eHalStatus status = eHAL_STATUS_SUCCESS;
1649 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1650 if(eHAL_STATUS_SUCCESS != status)
1651 {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001654 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001655 return status;
1656 }
1657 break;
1658 }
1659
Leo Chang614d2072013-08-22 14:59:44 -07001660 case QCSAP_PARAM_SET_MC_RATE:
1661 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001662 tSirRateUpdateInd *rateUpdate;
1663
1664 rateUpdate = (tSirRateUpdateInd *)
1665 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1666 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001667 {
1668 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001669 "%s: SET_MC_RATE indication alloc fail", __func__);
1670 ret = -1;
1671 break;
1672 }
1673 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1674
1675 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1676 /* Ignore unicast */
1677 rateUpdate->ucastDataRate = -1;
1678 rateUpdate->mcastDataRate24GHz = set_value;
1679 rateUpdate->mcastDataRate5GHz = set_value;
1680 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1681 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1682 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1683 if (eHAL_STATUS_SUCCESS != status)
1684 {
1685 hddLog(VOS_TRACE_LEVEL_ERROR,
1686 "%s: SET_MC_RATE failed", __func__);
1687 vos_mem_free(rateUpdate);
1688 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001689 }
1690 break;
1691 }
1692
Jeff Johnson295189b2012-06-20 16:38:30 -07001693 default:
1694 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1695 sub_cmd, set_value);
1696 ret = -EINVAL;
1697 break;
1698 }
1699
1700 return ret;
1701}
1702
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301703int
1704static iw_softap_setparam(struct net_device *dev,
1705 struct iw_request_info *info,
1706 union iwreq_data *wrqu, char *extra)
1707{
1708 int ret;
1709
1710 vos_ssr_protect(__func__);
1711 ret = __iw_softap_setparam(dev, info, wrqu, extra);
1712 vos_ssr_unprotect(__func__);
1713
1714 return ret;
1715}
Jeff Johnson295189b2012-06-20 16:38:30 -07001716
1717int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301718static __iw_softap_getparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001719 struct iw_request_info *info,
1720 union iwreq_data *wrqu, char *extra)
1721{
1722 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1723 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Girish Gowli385be612014-09-18 11:17:20 +05301724 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 int *value = (int *)extra;
1726 int sub_cmd = value[0];
1727 eHalStatus status;
1728 int ret = 0; /* success */
1729 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1730
1731 switch (sub_cmd)
1732 {
1733 case QCSAP_PARAM_MAX_ASSOC:
1734 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1735 if (eHAL_STATUS_SUCCESS != status)
1736 {
c_hpothuffdb5272013-10-02 16:42:35 +05301737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1738 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 ret = -EIO;
1740 }
Girish Gowli385be612014-09-18 11:17:20 +05301741
1742#ifdef WLAN_SOFTAP_VSTA_FEATURE
1743 if (pHddCtx->cfg_ini->fEnableVSTASupport)
1744 {
1745 if (*value > VSTA_NUM_ASSOC_STA)
1746 {
1747 *value = VSTA_NUM_ASSOC_STA;
1748 }
1749 if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) &&
1750 (*value > (VSTA_NUM_ASSOC_STA -
1751 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA))))
1752 {
1753 *value = (VSTA_NUM_ASSOC_STA -
1754 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA));
1755 }
1756 }
1757 else
1758#endif
1759 {
1760 if (*value > NUM_ASSOC_STA)
1761 {
1762 *value = NUM_ASSOC_STA;
1763 }
1764 if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) &&
1765 (*value > (NUM_ASSOC_STA -
1766 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA))))
1767 {
1768 *value = (NUM_ASSOC_STA -
1769 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA));
1770 }
1771 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 break;
1773
1774 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001775 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001776 {
c_hpothuffdb5272013-10-02 16:42:35 +05301777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1778 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 ret = -EIO;
1780 }
1781 *value = 0;
1782 break;
1783
Jeff Johnson43971f52012-07-17 12:26:56 -07001784 case QCSAP_PARAM_GET_WLAN_DBG:
1785 {
1786 vos_trace_display();
1787 *value = 0;
1788 break;
1789 }
1790
1791 case QCSAP_PARAM_AUTO_CHANNEL:
1792 {
1793 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1794 break;
1795 }
1796
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 default:
1798 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1799 ret = -EINVAL;
1800 break;
1801
1802 }
1803
1804 return ret;
1805}
1806
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301807int
1808static iw_softap_getparam(struct net_device *dev,
1809 struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1811{
1812 int ret;
1813
1814 vos_ssr_protect(__func__);
1815 ret = __iw_softap_getparam(dev, info, wrqu, extra);
1816 vos_ssr_unprotect(__func__);
1817
1818 return ret;
1819}
Jeff Johnson295189b2012-06-20 16:38:30 -07001820/* Usage:
1821 BLACK_LIST = 0
1822 WHITE_LIST = 1
1823 ADD MAC = 0
1824 REMOVE MAC = 1
1825
1826 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1827 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1828 while using this ioctl
1829
1830 Syntax:
1831 iwpriv softap.0 modify_acl
1832 <6 octet mac addr> <list type> <cmd type>
1833
1834 Examples:
1835 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1836 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1837 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1838 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1839*/
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301840int __iw_softap_modify_acl(struct net_device *dev,
1841 struct iw_request_info *info,
1842 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001843{
1844 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1845 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1846 v_BYTE_t *value = (v_BYTE_t*)extra;
1847 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1848 int listType, cmd, i;
1849 int ret = 0; /* success */
1850
1851 ENTER();
1852 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1853 {
1854 pPeerStaMac[i] = *(value+i);
1855 }
1856 listType = (int)(*(value+i));
1857 i++;
1858 cmd = (int)(*(value+i));
1859
Arif Hussain24bafea2013-11-15 15:10:03 -08001860 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1861 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001862
1863 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1864 != VOS_STATUS_SUCCESS)
1865 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001866 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001867 ret = -EIO;
1868 }
1869 EXIT();
1870 return ret;
1871}
1872
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301873int iw_softap_modify_acl(struct net_device *dev,
1874 struct iw_request_info *info,
1875 union iwreq_data *wrqu, char *extra)
1876{
1877 int ret;
1878
1879 vos_ssr_protect(__func__);
1880 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
1881 vos_ssr_unprotect(__func__);
1882
1883 return ret;
1884}
1885
Jeff Johnson295189b2012-06-20 16:38:30 -07001886int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301887static __iw_softap_getchannel(struct net_device *dev,
1888 struct iw_request_info *info,
1889 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001890{
1891 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1892
Jeff Johnson43971f52012-07-17 12:26:56 -07001893 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001894
Jeff Johnson43971f52012-07-17 12:26:56 -07001895 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 return 0;
1897}
1898
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301899
Jeff Johnsone7245742012-09-05 17:12:55 -07001900int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301901static iw_softap_getchannel(struct net_device *dev,
1902 struct iw_request_info *info,
1903 union iwreq_data *wrqu, char *extra)
1904{
1905 int ret;
1906
1907 vos_ssr_protect(__func__);
1908 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
1909 vos_ssr_unprotect(__func__);
1910
1911 return ret;
1912}
1913
1914int
1915static __iw_softap_set_max_tx_power(struct net_device *dev,
1916 struct iw_request_info *info,
1917 union iwreq_data *wrqu, char *extra)
Jeff Johnsone7245742012-09-05 17:12:55 -07001918{
1919 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1920 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001921 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001922 int set_value;
1923 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1924 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1925
schang86c22c42013-03-13 18:41:24 -07001926 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001927 return -ENOMEM;
1928
Leo Changd37675a2013-08-01 13:19:45 -07001929 /* Assign correct slef MAC address */
1930 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1931 VOS_MAC_ADDR_SIZE);
1932 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1933 VOS_MAC_ADDR_SIZE);
1934
schang86c22c42013-03-13 18:41:24 -07001935 set_value = value[0];
1936 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001939 __func__);
schang86c22c42013-03-13 18:41:24 -07001940 return -EIO;
1941 }
1942
1943 return 0;
1944}
1945
1946int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301947static iw_softap_set_max_tx_power(struct net_device *dev,
1948 struct iw_request_info *info,
1949 union iwreq_data *wrqu, char *extra)
1950{
1951 int ret;
1952
1953 vos_ssr_protect(__func__);
1954 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
1955 vos_ssr_unprotect(__func__);
1956
1957 return ret;
1958}
1959
1960
1961int
1962static __iw_display_data_path_snapshot(struct net_device *dev,
1963 struct iw_request_info *info,
1964 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301965{
1966
1967 /* Function intitiating dumping states of
1968 * HDD(WMM Tx Queues)
1969 * TL State (with Per Client infor)
1970 * DXE Snapshot (Called at the end of TL Snapshot)
1971 */
1972 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1973 hddLog(LOGE, "%s: called for SAP",__func__);
1974 hdd_wmm_tx_snapshot(pHostapdAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +05301975 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301976 return 0;
1977}
1978
1979int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301980static iw_display_data_path_snapshot(struct net_device *dev,
1981 struct iw_request_info *info,
1982 union iwreq_data *wrqu, char *extra)
1983{
1984 int ret;
1985
1986 vos_ssr_protect(__func__);
1987 ret = __iw_display_data_path_snapshot(dev, info, wrqu, extra);
1988 vos_ssr_unprotect(__func__);
1989
1990 return ret;
1991}
1992
1993int
1994static __iw_softap_set_tx_power(struct net_device *dev,
1995 struct iw_request_info *info,
1996 union iwreq_data *wrqu, char *extra)
schang86c22c42013-03-13 18:41:24 -07001997{
1998 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1999 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2000 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2001 int *value = (int *)extra;
2002 int set_value;
2003 ptSapContext pSapCtx = NULL;
2004
2005 if (NULL == value)
2006 return -ENOMEM;
2007
2008 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2009 if (NULL == pSapCtx)
2010 {
2011 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2012 "%s: Invalid SAP pointer from pvosGCtx", __func__);
2013 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07002014 }
2015
2016 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07002017 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07002018 {
schang86c22c42013-03-13 18:41:24 -07002019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07002020 __func__);
2021 return -EIO;
2022 }
2023
2024 return 0;
2025}
2026
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302027int
2028static iw_softap_set_tx_power(struct net_device *dev,
2029 struct iw_request_info *info,
2030 union iwreq_data *wrqu, char *extra)
2031{
2032 int ret;
2033
2034 vos_ssr_protect(__func__);
2035 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
2036 vos_ssr_unprotect(__func__);
2037
2038 return ret;
2039}
2040
Kiet Lambcf38522013-10-26 18:28:27 +05302041/**---------------------------------------------------------------------------
2042
2043 \brief iw_softap_set_trafficmonitor() -
2044 This function dynamically enable/disable traffic monitor functonality
2045 the command iwpriv wlanX setTrafficMon <value>.
2046
2047 \param - dev - Pointer to the net device.
2048 - addr - Pointer to the sockaddr.
2049 \return - 0 for success, non zero for failure
2050
2051 --------------------------------------------------------------------------*/
2052
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302053static int __iw_softap_set_trafficmonitor(struct net_device *dev,
2054 struct iw_request_info *info,
2055 union iwreq_data *wrqu, char *extra)
Kiet Lambcf38522013-10-26 18:28:27 +05302056{
2057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik128a0bb2014-08-07 20:24:54 +05302058 int *isSetTrafficMon = (int *)extra;
Kiet Lambcf38522013-10-26 18:28:27 +05302059 hdd_context_t *pHddCtx;
2060 int status;
2061
2062 if (NULL == pAdapter)
2063 {
2064 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2065 "%s: HDD adapter is Null", __func__);
2066 return -ENODEV;
2067 }
2068
2069 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2070
2071 status = wlan_hdd_validate_context(pHddCtx);
2072
2073 if (0 != status)
2074 {
2075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2076 "%s: HDD context is not valid", __func__);
2077 return status;
2078 }
2079
2080 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
2081
2082 if (NULL == isSetTrafficMon)
2083 {
2084 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2085 "%s: Invalid SAP pointer from extra", __func__);
2086 return -ENOMEM;
2087 }
2088
2089 if (TRUE == *isSetTrafficMon)
2090 {
2091 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
2092 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
2093 {
2094 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2095 "%s: failed to Start Traffic Monitor timer ", __func__ );
2096 return -EIO;
2097 }
2098 }
2099 else if (FALSE == *isSetTrafficMon)
2100 {
2101 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
2102 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
2103 {
2104 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2105 "%s: failed to Stop Traffic Monitor timer ", __func__ );
2106 return -EIO;
2107 }
2108
2109 }
2110 return 0;
2111}
2112
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302113static int iw_softap_set_trafficmonitor(struct net_device *dev,
2114 struct iw_request_info *info,
2115 union iwreq_data *wrqu, char *extra)
2116{
2117 int ret;
2118
2119 vos_ssr_protect(__func__);
2120 ret = __iw_softap_set_trafficmonitor(dev, info, wrqu, extra);
2121 vos_ssr_unprotect(__func__);
2122
2123 return ret;
2124}
2125
Jeff Johnson295189b2012-06-20 16:38:30 -07002126#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
2127
2128int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302129static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
2130 struct iw_request_info *info,
2131 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002132{
2133 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302134 hdd_station_info_t *pStaInfo = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002135 char *buf;
2136 int cnt = 0;
2137 int left;
2138 int ret = 0;
2139 /* maclist_index must be u32 to match userspace */
2140 u32 maclist_index;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302141 v_CONTEXT_t pVosContext = NULL;
2142 ptSapContext pSapCtx = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002143 /*
2144 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
2145 * number, and even numbered iocts are supposed to have "set"
2146 * semantics. Hence the wireless extensions support in the kernel
2147 * won't correctly copy the result to userspace, so the ioctl
2148 * handler itself must copy the data. Output format is 32-bit
2149 * record length, followed by 0 or more 6-byte STA MAC addresses.
2150 *
2151 * Further note that due to the incorrect semantics, the "iwpriv"
2152 * userspace application is unable to correctly invoke this API,
2153 * hence it is not registered in the hostapd_private_args. This
2154 * API can only be invoked by directly invoking the ioctl() system
2155 * call.
2156 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
Jeff Johnson224f3702014-03-26 11:09:47 -07002158 /* make sure userspace allocated a reasonable buffer size */
2159 if (wrqu->data.length < sizeof(maclist_index)) {
2160 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
2161 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07002162 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002163
Jeff Johnson224f3702014-03-26 11:09:47 -07002164 /* allocate local buffer to build the response */
2165 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
2166 if (!buf) {
2167 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
2168 return -ENOMEM;
2169 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302170 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2171 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2172 if(pSapCtx == NULL){
2173 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2174 FL("psapCtx is NULL"));
2175 return -EFAULT;
2176 }
2177 pStaInfo = pSapCtx->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07002178 /* start indexing beyond where the record count will be written */
2179 maclist_index = sizeof(maclist_index);
2180 left = wrqu->data.length - maclist_index;
2181
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302182 spin_lock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002183 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
2184 if ((pStaInfo[cnt].isUsed) &&
2185 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
2186 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
2187 VOS_MAC_ADDR_SIZE);
2188 maclist_index += VOS_MAC_ADDR_SIZE;
2189 left -= VOS_MAC_ADDR_SIZE;
2190 }
2191 cnt++;
2192 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302193 spin_unlock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002194
2195 *((u32 *)buf) = maclist_index;
2196 wrqu->data.length = maclist_index;
2197 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
2198 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
2199 ret = -EFAULT;
2200 }
2201 kfree(buf);
2202 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002203}
2204
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302205int
2206static iw_softap_getassoc_stamacaddr(struct net_device *dev,
2207 struct iw_request_info *info,
2208 union iwreq_data *wrqu, char *extra)
2209{
2210 int ret;
2211
2212 vos_ssr_protect(__func__);
2213 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
2214 vos_ssr_unprotect(__func__);
2215
2216 return ret;
2217}
2218
Jeff Johnson295189b2012-06-20 16:38:30 -07002219/* Usage:
2220 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
2221 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
2222 while using this ioctl
2223
2224 Syntax:
2225 iwpriv softap.0 disassoc_sta <6 octet mac address>
2226
2227 e.g.
2228 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
2229 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
2230*/
2231
2232int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302233static __iw_softap_disassoc_sta(struct net_device *dev,
2234 struct iw_request_info *info,
2235 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002236{
2237 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2238 v_U8_t *peerMacAddr;
2239
2240 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302241 /* iwpriv tool or framework calls this ioctl with
2242 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302244 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002245
Arif Hussain24bafea2013-11-15 15:10:03 -08002246 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
2247 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
2249 EXIT();
2250 return 0;
2251}
2252
2253int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302254static iw_softap_disassoc_sta(struct net_device *dev,
2255 struct iw_request_info *info,
2256 union iwreq_data *wrqu, char *extra)
2257{
2258 int ret;
2259
2260 vos_ssr_protect(__func__);
2261 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
2262 vos_ssr_unprotect(__func__);
2263
2264 return ret;
2265}
2266
2267int
2268static __iw_softap_ap_stats(struct net_device *dev,
2269 struct iw_request_info *info,
2270 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002271{
2272 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2273 WLANTL_TRANSFER_STA_TYPE statBuffer;
2274 char *pstatbuf;
Girish Gowlif3769802014-06-16 21:17:16 +05302275 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07002276
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002277 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07002278 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
2279 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002280
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302281 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07002282 if(NULL == pstatbuf) {
2283 hddLog(LOG1, "unable to allocate memory");
2284 return -ENOMEM;
2285 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302286
2287 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07002288 "RUF=%d RMF=%d RBF=%d "
2289 "RUB=%d RMB=%d RBB=%d "
2290 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302291 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002292 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2293 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2294 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2295 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2296 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2297 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302299 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002300 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2301 kfree(pstatbuf);
2302 return -EFAULT;
2303 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302304
2305 strlcpy(extra, pstatbuf, len);
2306 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002307 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 return 0;
2309}
2310
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302311int
2312static iw_softap_ap_stats(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002313 struct iw_request_info *info,
2314 union iwreq_data *wrqu, char *extra)
2315{
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302316 int ret;
2317
2318 vos_ssr_protect(__func__);
2319 ret = __iw_softap_ap_stats(dev, info, wrqu, extra);
2320 vos_ssr_unprotect(__func__);
2321
2322 return ret;
2323}
2324
2325static int __iw_softap_set_channel_range(struct net_device *dev,
2326 struct iw_request_info *info,
2327 union iwreq_data *wrqu, char *extra)
2328{
Jeff Johnson295189b2012-06-20 16:38:30 -07002329 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2330 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002331 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002332
2333 int *value = (int *)extra;
2334 int startChannel = value[0];
2335 int endChannel = value[1];
2336 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002337 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 int ret = 0; /* success */
2339
2340 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2341 if(status != VOS_STATUS_SUCCESS)
2342 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002343 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 startChannel,endChannel, band);
2345 ret = -EINVAL;
2346 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002347
2348 pHddCtx->is_dynamic_channel_range_set = 1;
2349
Jeff Johnson295189b2012-06-20 16:38:30 -07002350 return ret;
2351}
2352
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302353static int iw_softap_set_channel_range(struct net_device *dev,
2354 struct iw_request_info *info,
2355 union iwreq_data *wrqu, char *extra)
2356{
2357 int ret;
2358
2359 vos_ssr_protect(__func__);
2360 ret = __iw_softap_set_channel_range(dev, info, wrqu, extra);
2361 vos_ssr_unprotect(__func__);
2362
2363 return ret;
2364}
2365
2366
2367int __iw_softap_get_channel_list(struct net_device *dev,
2368 struct iw_request_info *info,
2369 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002370{
2371 v_U32_t num_channels = 0;
2372 v_U8_t i = 0;
2373 v_U8_t bandStartChannel = RF_CHAN_1;
2374 v_U8_t bandEndChannel = RF_CHAN_165;
2375 v_U32_t temp_num_channels = 0;
2376 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2377 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2378 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002380 eCsrBand curBand = eCSR_BAND_ALL;
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302381 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002382
2383 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2384 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002385 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002386 return -EIO;
2387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002388 wrqu->data.length = sizeof(tChannelListInfo);
2389 ENTER();
2390
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002391 if (eCSR_BAND_24 == curBand)
2392 {
2393 bandStartChannel = RF_CHAN_1;
2394 bandEndChannel = RF_CHAN_14;
2395 }
2396 else if (eCSR_BAND_5G == curBand)
2397 {
2398 bandStartChannel = RF_CHAN_36;
2399 bandEndChannel = RF_CHAN_165;
2400 }
2401
Arif Hussain6d2a3322013-11-17 19:50:10 -08002402 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302403 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002404 bandStartChannel, bandEndChannel );
2405
Jeff Johnson295189b2012-06-20 16:38:30 -07002406 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2407 {
2408 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2409 {
2410 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2411 num_channels++;
2412 }
2413 }
2414
2415 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2416
2417 temp_num_channels = num_channels;
2418
2419 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2420 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302421 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002422 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 }
2424
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302425 if(REGDOMAIN_FCC == domainIdCurrentSoftap &&
2426 pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC )
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 {
2428 for(i = 0; i < temp_num_channels; i++)
2429 {
2430
2431 if((channel_list->channels[i] > 35) &&
2432 (channel_list->channels[i] < 49))
2433 {
2434 vos_mem_move(&channel_list->channels[i],
2435 &channel_list->channels[i+1],
2436 temp_num_channels - (i-1));
2437 num_channels--;
2438 temp_num_channels--;
2439 i--;
2440 }
2441 }
2442 }
2443
Arif Hussain6d2a3322013-11-17 19:50:10 -08002444 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002445
2446 if (num_channels > IW_MAX_FREQUENCIES)
2447 {
2448 num_channels = IW_MAX_FREQUENCIES;
2449 }
2450
2451 channel_list->num_channels = num_channels;
2452 EXIT();
2453
2454 return 0;
2455}
2456
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302457int iw_softap_get_channel_list(struct net_device *dev,
2458 struct iw_request_info *info,
2459 union iwreq_data *wrqu, char *extra)
2460{
2461 int ret;
2462
2463 vos_ssr_protect(__func__);
2464 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
2465 vos_ssr_unprotect(__func__);
2466
2467 return ret;
2468}
2469
2470static
2471int __iw_get_genie(struct net_device *dev,
2472 struct iw_request_info *info,
2473 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002474{
2475 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2476 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2477 eHalStatus status;
2478 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2479 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2480 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002481 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2483 status = WLANSap_getstationIE_information(pVosContext,
2484 &length,
2485 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002486 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2487 if (wrqu->data.length < length ||
2488 copy_to_user(wrqu->data.pointer,
2489 (v_VOID_t*)genIeBytes, length))
2490 {
2491 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2492 return -EFAULT;
2493 }
2494 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002495
Arif Hussain6d2a3322013-11-17 19:50:10 -08002496 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002497
2498
2499 EXIT();
2500 return 0;
2501}
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302502
2503static
2504int iw_get_genie(struct net_device *dev,
2505 struct iw_request_info *info,
2506 union iwreq_data *wrqu, char *extra)
2507{
2508 int ret;
2509
2510 vos_ssr_protect(__func__);
2511 ret = __iw_get_genie(dev, info, wrqu, extra);
2512 vos_ssr_unprotect(__func__);
2513
2514 return ret;
2515}
2516
2517static
2518int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2519 struct iw_request_info *info,
2520 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002521{
2522 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002523 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002524 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2525 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002526
Arif Hussain6d2a3322013-11-17 19:50:10 -08002527 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002528 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2529
2530 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2531 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2532 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2533 WPSPBCProbeReqIEs.probeReqIELen);
2534 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2535 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2536 sizeof(v_MACADDR_t));
2537 if (copy_to_user(wrqu->data.pointer,
2538 (void *)&WPSPBCProbeReqIEs,
2539 sizeof(WPSPBCProbeReqIEs)))
2540 {
2541 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2542 return -EFAULT;
2543 }
2544 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002545 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002546 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 up(&pHddApCtx->semWpsPBCOverlapInd);
2548 EXIT();
2549 return 0;
2550}
2551
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302552static
2553int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2554 struct iw_request_info *info,
2555 union iwreq_data *wrqu, char *extra)
2556{
2557 int ret;
2558
2559 vos_ssr_protect(__func__);
2560 ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra);
2561 vos_ssr_unprotect(__func__);
2562
2563 return ret;
2564}
2565
Jeff Johnson295189b2012-06-20 16:38:30 -07002566/**---------------------------------------------------------------------------
2567
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302568 \brief __iw_set_auth_hostap() -
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 This function sets the auth type received from the wpa_supplicant.
2570
2571 \param - dev - Pointer to the net device.
2572 - info - Pointer to the iw_request_info.
2573 - wrqu - Pointer to the iwreq_data.
2574 - extra - Pointer to the data.
2575 \return - 0 for success, non zero for failure
2576
2577 --------------------------------------------------------------------------*/
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302578int __iw_set_auth_hostap(struct net_device *dev,
2579 struct iw_request_info *info,
2580 union iwreq_data *wrqu,char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002581{
2582 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2583 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2584
2585 ENTER();
2586 switch(wrqu->param.flags & IW_AUTH_INDEX)
2587 {
2588 case IW_AUTH_TKIP_COUNTERMEASURES:
2589 {
2590 if(wrqu->param.value) {
2591 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2592 "Counter Measure started %d", wrqu->param.value);
2593 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2594 }
2595 else {
2596 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2597 "Counter Measure stopped=%d", wrqu->param.value);
2598 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2599 }
2600
2601 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2602 wrqu->param.value);
2603 }
2604 break;
2605
2606 default:
2607
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002608 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002609 wrqu->param.flags & IW_AUTH_INDEX);
2610 break;
2611 }
2612
2613 EXIT();
2614 return 0;
2615}
2616
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302617int iw_set_auth_hostap(struct net_device *dev,
2618 struct iw_request_info *info,
2619 union iwreq_data *wrqu,char *extra)
2620{
2621 int ret;
2622
2623 vos_ssr_protect(__func__);
2624 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
2625 vos_ssr_unprotect(__func__);
2626
2627 return ret;
2628}
2629
2630static int __iw_set_ap_encodeext(struct net_device *dev,
2631 struct iw_request_info *info,
2632 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002633{
2634 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2635 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2636 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002637 int retval = 0;
2638 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002639 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2640 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2641 int key_index;
2642 struct iw_point *encoding = &wrqu->encoding;
2643 tCsrRoamSetKey setKey;
2644// tCsrRoamRemoveKey RemoveKey;
2645 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002646
Jeff Johnson295189b2012-06-20 16:38:30 -07002647 ENTER();
2648
2649 key_index = encoding->flags & IW_ENCODE_INDEX;
2650
2651 if(key_index > 0) {
2652
2653 /*Convert from 1-based to 0-based keying*/
2654 key_index--;
2655 }
2656 if(!ext->key_len) {
2657#if 0
2658 /*Set the encrytion type to NONE*/
2659#if 0
2660 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2661#endif
2662
2663 RemoveKey.keyId = key_index;
2664 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2665 /*Key direction for group is RX only*/
2666 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2667 }
2668 else {
2669 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2670 }
2671 switch(ext->alg)
2672 {
2673 case IW_ENCODE_ALG_NONE:
2674 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2675 break;
2676 case IW_ENCODE_ALG_WEP:
2677 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2678 break;
2679 case IW_ENCODE_ALG_TKIP:
2680 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002681 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 case IW_ENCODE_ALG_CCMP:
2683 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2684 break;
2685 default:
2686 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2687 break;
2688 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002690 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002692 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002693 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002694 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2695 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 {
2697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002698 __LINE__, vstatus );
2699 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002700 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002701#endif
2702 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002703
Jeff Johnson43971f52012-07-17 12:26:56 -07002704 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002705
2706 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2707
2708 setKey.keyId = key_index;
2709 setKey.keyLength = ext->key_len;
2710
2711 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2712 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2713 }
2714
2715 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2716 /*Key direction for group is RX only*/
2717 setKey.keyDirection = eSIR_RX_ONLY;
2718 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2719 }
2720 else {
2721
2722 setKey.keyDirection = eSIR_TX_RX;
2723 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2724 }
2725 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2726 {
2727 setKey.keyDirection = eSIR_TX_DEFAULT;
2728 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2729 }
2730
2731 /*For supplicant pae role is zero*/
2732 setKey.paeRole = 0;
2733
2734 switch(ext->alg)
2735 {
2736 case IW_ENCODE_ALG_NONE:
2737 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2738 break;
2739
2740 case IW_ENCODE_ALG_WEP:
2741 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2742 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002743 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002744 break;
2745
2746 case IW_ENCODE_ALG_TKIP:
2747 {
2748 v_U8_t *pKey = &setKey.Key[0];
2749
2750 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2751
2752 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2753
2754 /*Supplicant sends the 32bytes key in this order
2755
2756 |--------------|----------|----------|
2757 | Tk1 |TX-MIC | RX Mic |
2758 |--------------|----------|----------|
2759 <---16bytes---><--8bytes--><--8bytes-->
2760
2761 */
2762 /*Sme expects the 32 bytes key to be in the below order
2763
2764 |--------------|----------|----------|
2765 | Tk1 |RX-MIC | TX Mic |
2766 |--------------|----------|----------|
2767 <---16bytes---><--8bytes--><--8bytes-->
2768 */
2769 /* Copy the Temporal Key 1 (TK1) */
2770 vos_mem_copy(pKey,ext->key,16);
2771
2772 /*Copy the rx mic first*/
2773 vos_mem_copy(&pKey[16],&ext->key[24],8);
2774
2775 /*Copy the tx mic */
2776 vos_mem_copy(&pKey[24],&ext->key[16],8);
2777
2778 }
2779 break;
2780
2781 case IW_ENCODE_ALG_CCMP:
2782 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2783 break;
2784
2785 default:
2786 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2787 break;
2788 }
2789
2790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302791 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002792 setKey.keyId);
2793 for(i=0; i< ext->key_len; i++)
2794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2795 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002796
2797 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2798 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002799 {
2800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002801 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2802 retval = -EINVAL;
2803 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002804
Jeff Johnson43971f52012-07-17 12:26:56 -07002805 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002806}
Jeff Johnson43971f52012-07-17 12:26:56 -07002807
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302808static int iw_set_ap_encodeext(struct net_device *dev,
2809 struct iw_request_info *info,
2810 union iwreq_data *wrqu, char *extra)
2811{
2812 int ret;
2813
2814 vos_ssr_protect(__func__);
2815 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
2816 vos_ssr_unprotect(__func__);
2817
2818 return ret;
2819}
Jeff Johnson43971f52012-07-17 12:26:56 -07002820
Jeff Johnson295189b2012-06-20 16:38:30 -07002821static int iw_set_ap_mlme(struct net_device *dev,
2822 struct iw_request_info *info,
2823 union iwreq_data *wrqu,
2824 char *extra)
2825{
2826#if 0
2827 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2828 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2829
2830 ENTER();
2831
2832 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2833 switch (mlme->cmd) {
2834 case IW_MLME_DISASSOC:
2835 case IW_MLME_DEAUTH:
2836 hddLog(LOG1, "Station disassociate");
2837 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2838 {
2839 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2840
2841 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2842 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2843
2844 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2845
2846 //clear all the reason codes
2847 if (status != 0)
2848 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002849 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002850 }
2851
2852 netif_stop_queue(dev);
2853 netif_carrier_off(dev);
2854 }
2855 else
2856 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002857 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002858 }
2859 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002860 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002861 return -EINVAL;
2862 }//end of switch
2863 EXIT();
2864#endif
2865 return 0;
2866// return status;
2867}
2868
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302869static int __iw_get_ap_rts_threshold(struct net_device *dev,
2870 struct iw_request_info *info,
2871 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002872{
2873 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2874 v_U32_t status = 0;
2875
2876 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2877
2878 return status;
2879}
2880
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302881static int iw_get_ap_rts_threshold(struct net_device *dev,
2882 struct iw_request_info *info,
2883 union iwreq_data *wrqu, char *extra)
2884{
2885 int ret;
2886
2887 vos_ssr_protect(__func__);
2888 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
2889 vos_ssr_unprotect(__func__);
2890
2891 return ret;
2892}
2893
2894static int __iw_get_ap_frag_threshold(struct net_device *dev,
2895 struct iw_request_info *info,
2896 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002897{
2898 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2899 v_U32_t status = 0;
2900
2901 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2902
2903 return status;
2904}
2905
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302906static int iw_get_ap_frag_threshold(struct net_device *dev,
2907 struct iw_request_info *info,
2908 union iwreq_data *wrqu, char *extra)
2909{
2910 int ret;
2911
2912 vos_ssr_protect(__func__);
2913 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
2914 vos_ssr_unprotect(__func__);
2915
2916 return ret;
2917}
2918
2919static int __iw_get_ap_freq(struct net_device *dev,
2920 struct iw_request_info *info,
2921 struct iw_freq *fwrq, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002922{
Jeff Johnsone7245742012-09-05 17:12:55 -07002923 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002924 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2925 tHalHandle hHal;
2926 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002927 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002928
2929 ENTER();
2930
2931 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2933 "%s:LOGP in Progress. Ignore!!!",__func__);
2934 return status;
2935 }
2936
2937 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2938 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2939
2940 if(pHostapdState->bssState == BSS_STOP )
2941 {
2942 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2943 != eHAL_STATUS_SUCCESS)
2944 {
c_hpothuffdb5272013-10-02 16:42:35 +05302945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2946 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002947 return -EIO;
2948 }
2949 else
2950 {
2951 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002952 if( TRUE == status)
2953 {
2954 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2955 * iwlist & iwconfig command shows frequency into proper
2956 * format (2.412 GHz instead of 246.2 MHz)*/
2957 fwrq->m = freq;
2958 fwrq->e = MHZ;
2959 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 }
2961 }
2962 else
2963 {
2964 channel = pHddApCtx->operatingChannel;
2965 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002966 if( TRUE == status)
2967 {
2968 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2969 * iwlist & iwconfig command shows frequency into proper
2970 * format (2.412 GHz instead of 246.2 MHz)*/
2971 fwrq->m = freq;
2972 fwrq->e = MHZ;
2973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002975 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002976}
2977
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302978static int iw_get_ap_freq(struct net_device *dev,
2979 struct iw_request_info *info,
2980 struct iw_freq *fwrq, char *extra)
2981{
2982 int ret;
2983
2984 vos_ssr_protect(__func__);
2985 ret = __iw_get_ap_freq(dev, info, fwrq, extra);
2986 vos_ssr_unprotect(__func__);
2987
2988 return ret;
2989}
2990
2991static int __iw_get_mode(struct net_device *dev,
2992 struct iw_request_info *info,
2993 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302994{
2995 int status = 0;
2996
2997 wrqu->mode = IW_MODE_MASTER;
2998
2999 return status;
3000}
3001
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303002static int iw_get_mode(struct net_device *dev,
3003 struct iw_request_info *info,
3004 union iwreq_data *wrqu, char *extra)
3005{
3006 int ret;
3007
3008 vos_ssr_protect(__func__);
3009 ret = __iw_get_mode(dev, info, wrqu, extra);
3010 vos_ssr_unprotect(__func__);
3011
3012 return ret;
3013}
3014
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303015static int __iw_softap_setwpsie(struct net_device *dev,
3016 struct iw_request_info *info,
3017 union iwreq_data *wrqu,
3018 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003019{
3020 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3021 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3022 hdd_hostapd_state_t *pHostapdState;
3023 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003024 u_int8_t *wps_genie;
3025 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07003026 u_int8_t *pos;
3027 tpSap_WPSIE pSap_WPSIe;
3028 u_int8_t WPSIeType;
3029 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05303030 struct iw_point s_priv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003031 ENTER();
3032
Girish Gowli07c05ec2014-06-17 20:47:03 +05303033 /* helper function to get iwreq_data with compat handling. */
3034 if (hdd_priv_get_data(&s_priv_data, wrqu))
3035 {
3036 return -EINVAL;
3037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003038
Girish Gowli07c05ec2014-06-17 20:47:03 +05303039 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
3040 {
3041 return -EINVAL;
3042 }
3043
3044 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
3045 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07003046
Girish Gowli86c471e2014-06-17 19:28:05 +05303047 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07003048 {
Girish Gowli86c471e2014-06-17 19:28:05 +05303049 hddLog(LOG1, "%s: failed to alloc memory "
3050 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07003051 return -EFAULT;
3052 }
3053
Girish Gowli86c471e2014-06-17 19:28:05 +05303054 fwps_genie = wps_genie;
3055
Jeff Johnson295189b2012-06-20 16:38:30 -07003056 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
3057 if (NULL == pSap_WPSIe)
3058 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003059 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07003060 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003061 return -ENOMEM;
3062 }
3063 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
3064
Arif Hussain6d2a3322013-11-17 19:50:10 -08003065 hddLog(LOG1,"%s WPS IE type[0x%X] IE[0x%X], LEN[%d]", __func__, wps_genie[0], wps_genie[1], wps_genie[2]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003066 WPSIeType = wps_genie[0];
3067 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
3068 {
3069 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
3070 wps_genie = wps_genie + 1;
3071 switch ( wps_genie[0] )
3072 {
3073 case DOT11F_EID_WPA:
3074 if (wps_genie[1] < 2 + 4)
3075 {
3076 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003077 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003078 return -EINVAL;
3079 }
3080 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3081 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003082 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003083 pos = &wps_genie[6];
3084 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3085 {
3086 switch((u_int16_t)(*pos<<8) | *(pos+1))
3087 {
3088 case HDD_WPS_ELEM_VERSION:
3089 pos += 4;
3090 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003091 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003092 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
3093 pos += 1;
3094 break;
3095
3096 case HDD_WPS_ELEM_WPS_STATE:
3097 pos +=4;
3098 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003099 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
3101 pos += 1;
3102 break;
3103 case HDD_WPS_ELEM_APSETUPLOCK:
3104 pos += 4;
3105 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003106 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003107 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
3108 pos += 1;
3109 break;
3110 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3111 pos += 4;
3112 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003113 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003114 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
3115 pos += 1;
3116 break;
3117 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3118 pos += 4;
3119 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003120 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003121 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
3122 pos += 2;
3123 break;
3124 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3125 pos += 4;
3126 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003127 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003128 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
3129 pos += 2;
3130 break;
3131
3132 case HDD_WPS_ELEM_UUID_E:
3133 pos += 2;
3134 length = *pos<<8 | *(pos+1);
3135 pos += 2;
3136 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
3137 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
3138 pos += length;
3139 break;
3140 case HDD_WPS_ELEM_RF_BANDS:
3141 pos += 4;
3142 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003143 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003144 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
3145 pos += 1;
3146 break;
3147
3148 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08003149 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07003150 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003151 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003152 return -EINVAL;
3153 }
3154 }
3155 }
3156 else {
3157 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003158 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 }
3160 break;
3161
3162 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003163 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003164 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003165 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003166 return 0;
3167 }
3168 }
3169 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
3170 {
3171 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
3172 wps_genie = wps_genie + 1;
3173 switch ( wps_genie[0] )
3174 {
3175 case DOT11F_EID_WPA:
3176 if (wps_genie[1] < 2 + 4)
3177 {
3178 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003179 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180 return -EINVAL;
3181 }
3182 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3183 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003184 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003185 pos = &wps_genie[6];
3186 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3187 {
3188 switch((u_int16_t)(*pos<<8) | *(pos+1))
3189 {
3190 case HDD_WPS_ELEM_VERSION:
3191 pos += 4;
3192 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003193 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003194 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
3195 pos += 1;
3196 break;
3197
3198 case HDD_WPS_ELEM_WPS_STATE:
3199 pos +=4;
3200 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003201 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003202 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
3203 pos += 1;
3204 break;
3205 case HDD_WPS_ELEM_APSETUPLOCK:
3206 pos += 4;
3207 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003208 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003209 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
3210 pos += 1;
3211 break;
3212 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3213 pos += 4;
3214 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003215 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003216 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
3217 pos += 1;
3218 break;
3219 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3220 pos += 4;
3221 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003222 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003223 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
3224 pos += 2;
3225 break;
3226 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3227 pos += 4;
3228 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003229 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003230 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
3231 pos += 2;
3232 break;
3233 case HDD_WPS_ELEM_RSP_TYPE:
3234 pos += 4;
3235 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003236 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07003237 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
3238 pos += 1;
3239 break;
3240 case HDD_WPS_ELEM_UUID_E:
3241 pos += 2;
3242 length = *pos<<8 | *(pos+1);
3243 pos += 2;
3244 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
3245 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
3246 pos += length;
3247 break;
3248
3249 case HDD_WPS_ELEM_MANUFACTURER:
3250 pos += 2;
3251 length = *pos<<8 | *(pos+1);
3252 pos += 2;
3253 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
3254 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
3255 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
3256 pos += length;
3257 break;
3258
3259 case HDD_WPS_ELEM_MODEL_NAME:
3260 pos += 2;
3261 length = *pos<<8 | *(pos+1);
3262 pos += 2;
3263 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
3264 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
3265 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
3266 pos += length;
3267 break;
3268 case HDD_WPS_ELEM_MODEL_NUM:
3269 pos += 2;
3270 length = *pos<<8 | *(pos+1);
3271 pos += 2;
3272 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
3273 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
3274 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
3275 pos += length;
3276 break;
3277 case HDD_WPS_ELEM_SERIAL_NUM:
3278 pos += 2;
3279 length = *pos<<8 | *(pos+1);
3280 pos += 2;
3281 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
3282 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
3283 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
3284 pos += length;
3285 break;
3286 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
3287 pos += 4;
3288 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003289 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003290 pos += 2;
3291
3292 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003293 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003294 pos += 4;
3295 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003296 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003297 pos += 2;
3298 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
3299 break;
3300 case HDD_WPS_ELEM_DEVICE_NAME:
3301 pos += 2;
3302 length = *pos<<8 | *(pos+1);
3303 pos += 2;
3304 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
3305 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
3306 pos += length;
3307 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
3308 break;
3309 case HDD_WPS_ELEM_CONFIG_METHODS:
3310 pos += 4;
3311 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003312 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003313 pos += 2;
3314 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
3315 break;
3316
3317 case HDD_WPS_ELEM_RF_BANDS:
3318 pos += 4;
3319 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003320 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003321 pos += 1;
3322 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
3323 break;
3324 } // switch
3325 }
3326 }
3327 else
3328 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003329 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003330 }
3331
3332 } // switch
3333 }
3334 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
3335 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3336 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3337 {
3338 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3339 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3340 WLANSAP_Update_WpsIe ( pVosContext );
3341 }
3342
3343 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003344 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003345 EXIT();
3346 return halStatus;
3347}
3348
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303349static int iw_softap_setwpsie(struct net_device *dev,
3350 struct iw_request_info *info,
3351 union iwreq_data *wrqu,
3352 char *extra)
3353{
3354 int ret;
3355
3356 vos_ssr_protect(__func__);
3357 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
3358 vos_ssr_unprotect(__func__);
3359
3360 return ret;
3361}
3362
3363static int __iw_softap_stopbss(struct net_device *dev,
3364 struct iw_request_info *info,
3365 union iwreq_data *wrqu,
3366 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003367{
3368 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3369 VOS_STATUS status = VOS_STATUS_SUCCESS;
Agarwal Ashish51325b52014-06-16 16:50:49 +05303370 hdd_context_t *pHddCtx = NULL;
3371
Jeff Johnson295189b2012-06-20 16:38:30 -07003372 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +05303373
3374 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3375 status = wlan_hdd_validate_context(pHddCtx);
3376
3377 if (0 != status) {
3378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
3379 return status;
3380 }
3381
Jeff Johnson295189b2012-06-20 16:38:30 -07003382 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3383 {
3384 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
3385 {
3386 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3387
3388 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
3389
3390 if (!VOS_IS_STATUS_SUCCESS(status))
3391 {
3392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003393 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003394 VOS_ASSERT(0);
3395 }
3396 }
3397 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05303398 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003399 }
3400 EXIT();
3401 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
3402}
3403
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303404static int iw_softap_stopbss(struct net_device *dev,
3405 struct iw_request_info *info,
3406 union iwreq_data *wrqu,
3407 char *extra)
3408{
3409 int ret;
3410
3411 vos_ssr_protect(__func__);
3412 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
3413 vos_ssr_unprotect(__func__);
3414
3415 return ret;
3416}
3417
3418static int __iw_softap_version(struct net_device *dev,
3419 struct iw_request_info *info,
3420 union iwreq_data *wrqu,
3421 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003422{
Jeff Johnson295189b2012-06-20 16:38:30 -07003423 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003424
Jeff Johnson295189b2012-06-20 16:38:30 -07003425 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003426 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003427 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003428 return 0;
3429}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003430
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303431static int iw_softap_version(struct net_device *dev,
3432 struct iw_request_info *info,
3433 union iwreq_data *wrqu,
3434 char *extra)
3435{
3436 int ret;
3437
3438 vos_ssr_protect(__func__);
3439 ret = __iw_softap_version(dev, info, wrqu, extra);
3440 vos_ssr_unprotect(__func__);
3441
3442 return ret;
3443}
3444
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003445VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003446{
3447 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003448 int len = 0;
3449 const char sta_info_header[] = "staId staAddress\n";
3450
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303451 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3452 ptSapContext pSapCtx = NULL;
3453 pSapCtx = VOS_GET_SAP_CB(pVosContext);
3454 if(pSapCtx == NULL){
3455 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
3456 FL("psapCtx is NULL"));
3457 return VOS_STATUS_E_FAULT;
3458 }
3459
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003460 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003461 pBuf += len;
3462 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003463
3464 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
3465 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303466 if(pSapCtx->aStaInfo[i].isUsed)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003467 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003468 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303469 pSapCtx->aStaInfo[i].ucSTAId,
3470 pSapCtx->aStaInfo[i].macAddrSTA.bytes[0],
3471 pSapCtx->aStaInfo[i].macAddrSTA.bytes[1],
3472 pSapCtx->aStaInfo[i].macAddrSTA.bytes[2],
3473 pSapCtx->aStaInfo[i].macAddrSTA.bytes[3],
3474 pSapCtx->aStaInfo[i].macAddrSTA.bytes[4],
3475 pSapCtx->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003476 pBuf += len;
3477 buf_len -= len;
3478 }
3479 if(WE_GET_STA_INFO_SIZE > buf_len)
3480 {
3481 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003482 }
3483 }
3484 return VOS_STATUS_SUCCESS;
3485}
3486
3487static int iw_softap_get_sta_info(struct net_device *dev,
3488 struct iw_request_info *info,
3489 union iwreq_data *wrqu,
3490 char *extra)
3491{
3492 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3493 VOS_STATUS status;
3494 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003495 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003496 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003498 return -EINVAL;
3499 }
3500 wrqu->data.length = strlen(extra);
3501 EXIT();
3502 return 0;
3503}
3504
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303505static int __iw_set_ap_genie(struct net_device *dev,
3506 struct iw_request_info *info,
3507 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003508{
3509
3510 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3511 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3512 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003513 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003514
3515 ENTER();
3516
3517 if(!wrqu->data.length)
3518 {
3519 EXIT();
3520 return 0;
3521 }
Arif Hussained667642013-10-27 23:01:14 -07003522
Jeff Johnson295189b2012-06-20 16:38:30 -07003523 switch (genie[0])
3524 {
3525 case DOT11F_EID_WPA:
3526 case DOT11F_EID_RSN:
3527 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3528 {
3529 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3530 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3531 }
3532 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003533 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003534 break;
3535
3536 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003537 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003538 halStatus = 0;
3539 }
3540
3541 EXIT();
3542 return halStatus;
3543}
3544
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303545static int iw_set_ap_genie(struct net_device *dev,
3546 struct iw_request_info *info,
3547 union iwreq_data *wrqu, char *extra)
3548{
3549 int ret;
3550
3551 vos_ssr_protect(__func__);
3552 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
3553 vos_ssr_unprotect(__func__);
3554
3555 return ret;
3556}
3557
Jeff Johnson295189b2012-06-20 16:38:30 -07003558static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3559{
3560 eHalStatus hstatus;
3561 long lrc;
3562 struct statsContext context;
3563
3564 if (NULL == pAdapter)
3565 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303566 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003567 return VOS_STATUS_E_FAULT;
3568 }
3569
3570 init_completion(&context.completion);
3571 context.pAdapter = pAdapter;
3572 context.magic = STATS_CONTEXT_MAGIC;
3573 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3574 eCSR_HDD,
3575 SME_GLOBAL_CLASSA_STATS,
3576 hdd_GetClassA_statisticsCB,
3577 0, // not periodic
3578 FALSE, //non-cached results
3579 staid,
3580 &context);
3581 if (eHAL_STATUS_SUCCESS != hstatus)
3582 {
3583 hddLog(VOS_TRACE_LEVEL_ERROR,
3584 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003585 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 }
3587 else
3588 {
3589 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3590 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003591 if (lrc <= 0)
3592 {
3593 hddLog(VOS_TRACE_LEVEL_ERROR,
3594 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003595 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 }
3597 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003598
3599 /* either we never sent a request, we sent a request and received a
3600 response or we sent a request and timed out. if we never sent a
3601 request or if we sent a request and got a response, we want to
3602 clear the magic out of paranoia. if we timed out there is a
3603 race condition such that the callback function could be
3604 executing at the same time we are. of primary concern is if the
3605 callback function had already verified the "magic" but had not
3606 yet set the completion variable when a timeout occurred. we
3607 serialize these activities by invalidating the magic while
3608 holding a shared spinlock which will cause us to block if the
3609 callback is currently executing */
3610 spin_lock(&hdd_context_lock);
3611 context.magic = 0;
3612 spin_unlock(&hdd_context_lock);
3613
Jeff Johnson295189b2012-06-20 16:38:30 -07003614 return VOS_STATUS_SUCCESS;
3615}
3616
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303617int __iw_get_softap_linkspeed(struct net_device *dev,
3618 struct iw_request_info *info,
3619 union iwreq_data *wrqu,
3620 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003621
3622{
3623 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303624 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003625 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003626 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303627 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003628 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303629 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003631 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303632 int rc, valid;
3633
3634 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3635
3636 valid = wlan_hdd_validate_context(pHddCtx);
3637
3638 if (0 != valid)
3639 {
3640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3641 return valid;
3642 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003643
Arif Hussain6d2a3322013-11-17 19:50:10 -08003644 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003645
3646 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003647 {
Arif Hussaina9571842014-01-15 16:43:41 -08003648 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3649 if (NULL == pmacAddress) {
3650 hddLog(LOG1, "unable to allocate memory");
3651 return -ENOMEM;
3652 }
3653 if (copy_from_user((void *)pmacAddress,
3654 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3655 {
3656 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3657 kfree(pmacAddress);
3658 return -EFAULT;
3659 }
3660 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3661
3662 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003663 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003664
3665 if (!VOS_IS_STATUS_SUCCESS(status ))
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3668 }
Arif Hussained667642013-10-27 23:01:14 -07003669 }
Kiet Lam61589852013-09-19 17:10:58 +05303670 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303671 * link speed for first connected client will be returned.
3672 */
Arif Hussaina9571842014-01-15 16:43:41 -08003673 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303674 {
3675 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3676 }
3677 else
3678 {
3679 status = hdd_softap_GetStaId(pHostapdAdapter,
3680 (v_MACADDR_t *)macAddress, (void *)(&staId));
3681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003682
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303683 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003684 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003686 link_speed = 0;
3687 }
3688 else
3689 {
3690 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303691
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 if (!VOS_IS_STATUS_SUCCESS(status ))
3693 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003695 return -EINVAL;
3696 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303697
3698 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3699 staId, &link_speed);
3700
3701 link_speed = link_speed / 10;
3702
3703 if (0 == link_speed)
3704 {
3705 /* The linkspeed returned by HAL is in units of 500kbps.
3706 * converting it to mbps.
3707 * This is required to support legacy firmware which does
3708 * not return link capacity.
3709 */
3710 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3711 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003712 }
3713
3714 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003715 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303716
Jeff Johnson295189b2012-06-20 16:38:30 -07003717 if ((rc < 0) || (rc >= len))
3718 {
3719 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303720 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003721 return -EIO;
3722 }
3723
3724 return 0;
3725}
3726
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303727int iw_get_softap_linkspeed(struct net_device *dev,
3728 struct iw_request_info *info,
3729 union iwreq_data *wrqu,
3730 char *extra)
3731{
3732 int ret;
3733
3734 vos_ssr_protect(__func__);
3735 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
3736 vos_ssr_unprotect(__func__);
3737
3738 return ret;
3739}
3740
3741
Jeff Johnson295189b2012-06-20 16:38:30 -07003742static const iw_handler hostapd_handler[] =
3743{
3744 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3745 (iw_handler) NULL, /* SIOCGIWNAME */
3746 (iw_handler) NULL, /* SIOCSIWNWID */
3747 (iw_handler) NULL, /* SIOCGIWNWID */
3748 (iw_handler) NULL, /* SIOCSIWFREQ */
3749 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3750 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303751 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003752 (iw_handler) NULL, /* SIOCSIWSENS */
3753 (iw_handler) NULL, /* SIOCGIWSENS */
3754 (iw_handler) NULL, /* SIOCSIWRANGE */
3755 (iw_handler) NULL, /* SIOCGIWRANGE */
3756 (iw_handler) NULL, /* SIOCSIWPRIV */
3757 (iw_handler) NULL, /* SIOCGIWPRIV */
3758 (iw_handler) NULL, /* SIOCSIWSTATS */
3759 (iw_handler) NULL, /* SIOCGIWSTATS */
3760 (iw_handler) NULL, /* SIOCSIWSPY */
3761 (iw_handler) NULL, /* SIOCGIWSPY */
3762 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3763 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3764 (iw_handler) NULL, /* SIOCSIWAP */
3765 (iw_handler) NULL, /* SIOCGIWAP */
3766 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3767 (iw_handler) NULL, /* SIOCGIWAPLIST */
3768 (iw_handler) NULL, /* SIOCSIWSCAN */
3769 (iw_handler) NULL, /* SIOCGIWSCAN */
3770 (iw_handler) NULL, /* SIOCSIWESSID */
3771 (iw_handler) NULL, /* SIOCGIWESSID */
3772 (iw_handler) NULL, /* SIOCSIWNICKN */
3773 (iw_handler) NULL, /* SIOCGIWNICKN */
3774 (iw_handler) NULL, /* -- hole -- */
3775 (iw_handler) NULL, /* -- hole -- */
3776 (iw_handler) NULL, /* SIOCSIWRATE */
3777 (iw_handler) NULL, /* SIOCGIWRATE */
3778 (iw_handler) NULL, /* SIOCSIWRTS */
3779 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3780 (iw_handler) NULL, /* SIOCSIWFRAG */
3781 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3782 (iw_handler) NULL, /* SIOCSIWTXPOW */
3783 (iw_handler) NULL, /* SIOCGIWTXPOW */
3784 (iw_handler) NULL, /* SIOCSIWRETRY */
3785 (iw_handler) NULL, /* SIOCGIWRETRY */
3786 (iw_handler) NULL, /* SIOCSIWENCODE */
3787 (iw_handler) NULL, /* SIOCGIWENCODE */
3788 (iw_handler) NULL, /* SIOCSIWPOWER */
3789 (iw_handler) NULL, /* SIOCGIWPOWER */
3790 (iw_handler) NULL, /* -- hole -- */
3791 (iw_handler) NULL, /* -- hole -- */
3792 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3793 (iw_handler) NULL, /* SIOCGIWGENIE */
3794 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3795 (iw_handler) NULL, /* SIOCGIWAUTH */
3796 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3797 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3798 (iw_handler) NULL, /* SIOCSIWPMKSA */
3799};
3800
Jeff Johnson224f3702014-03-26 11:09:47 -07003801/*
3802 * Note that the following ioctls were defined with semantics which
3803 * cannot be handled by the "iwpriv" userspace application and hence
3804 * they are not included in the hostapd_private_args array
3805 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3806 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003807
3808static const struct iw_priv_args hostapd_private_args[] = {
3809 { QCSAP_IOCTL_SETPARAM,
3810 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3811 { QCSAP_IOCTL_SETPARAM,
3812 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3813 { QCSAP_PARAM_MAX_ASSOC,
3814 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3815 { QCSAP_PARAM_HIDE_SSID,
3816 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003817 { QCSAP_PARAM_SET_MC_RATE,
3818 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003819 { QCSAP_IOCTL_GETPARAM,
3820 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3821 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3822 { QCSAP_IOCTL_GETPARAM, 0,
3823 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3824 { QCSAP_PARAM_MAX_ASSOC, 0,
3825 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003826 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3827 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3828 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3829 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303830 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3831 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003832 { QCSAP_PARAM_CLR_ACL, 0,
3833 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3834 { QCSAP_PARAM_ACL_MODE,
3835 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003836 { QCSAP_IOCTL_GET_STAWPAIE,
3837 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3838 { QCSAP_IOCTL_SETWPAIE,
3839 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3840 { QCSAP_IOCTL_STOPBSS,
3841 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3842 { QCSAP_IOCTL_VERSION, 0,
3843 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003844 { QCSAP_IOCTL_GET_STA_INFO, 0,
3845 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003846 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003847 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003848 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003849 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003850 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003851 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05303852 { QCSAP_IOCTL_AP_STATS, 0,
3853 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003854 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3855 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303856 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003857
3858 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3859 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3860 /* handlers for sub-ioctl */
3861 { WE_SET_WLAN_DBG,
3862 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3863 0,
3864 "setwlandbg" },
3865
3866 /* handlers for main ioctl */
3867 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3868 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3869 0,
3870 "" },
3871
3872 /* handlers for sub-ioctl */
3873 { WE_LOG_DUMP_CMD,
3874 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3875 0,
3876 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003877 { WE_P2P_NOA_CMD,
3878 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3879 0,
3880 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003881 /* handlers for sub ioctl */
3882 {
3883 WE_MCC_CONFIG_CREDENTIAL,
3884 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3885 0,
3886 "setMccCrdnl" },
3887
3888 /* handlers for sub ioctl */
3889 {
3890 WE_MCC_CONFIG_PARAMS,
3891 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3892 0,
3893 "setMccConfig" },
3894
Jeff Johnson295189b2012-06-20 16:38:30 -07003895 /* handlers for main ioctl */
3896 { QCSAP_IOCTL_MODIFY_ACL,
3897 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3898 0,
3899 "modify_acl" },
3900
3901 /* handlers for main ioctl */
3902 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3903 0,
3904 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3905 "getChannelList" },
3906
Jeff Johnsone7245742012-09-05 17:12:55 -07003907 /* handlers for main ioctl */
3908 { QCSAP_IOCTL_SET_TX_POWER,
3909 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3910 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303911 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003912
3913 /* handlers for main ioctl */
3914 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3915 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3916 0,
3917 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303918
3919 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3920 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3921 0,
3922 "dataSnapshot" },
3923
3924 /* handlers for main ioctl */
3925 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3926 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3927 0,
3928 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003929};
Jeff Johnsone7245742012-09-05 17:12:55 -07003930
Jeff Johnson295189b2012-06-20 16:38:30 -07003931static const iw_handler hostapd_private[] = {
3932 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3933 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07003934 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3935 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3936 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3937 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3938 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3939 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3940 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3941 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3942 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3943 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3944 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3945 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3946 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3947 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003948 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003949 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3950 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003951 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303952 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303953 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003954};
3955const struct iw_handler_def hostapd_handler_def = {
3956 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3957 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3958 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3959 .standard = (iw_handler *)hostapd_handler,
3960 .private = (iw_handler *)hostapd_private,
3961 .private_args = hostapd_private_args,
3962 .get_wireless_stats = NULL,
3963};
3964#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3965struct net_device_ops net_ops_struct = {
3966 .ndo_open = hdd_hostapd_open,
3967 .ndo_stop = hdd_hostapd_stop,
3968 .ndo_uninit = hdd_hostapd_uninit,
3969 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3970 .ndo_tx_timeout = hdd_softap_tx_timeout,
3971 .ndo_get_stats = hdd_softap_stats,
3972 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3973 .ndo_do_ioctl = hdd_hostapd_ioctl,
3974 .ndo_change_mtu = hdd_hostapd_change_mtu,
3975 .ndo_select_queue = hdd_hostapd_select_queue,
3976 };
3977#endif
3978
3979int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3980{
3981 return VOS_STATUS_SUCCESS;
3982}
3983
3984void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3985{
3986#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3987 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3988#else
3989 pWlanHostapdDev->open = hdd_hostapd_open;
3990 pWlanHostapdDev->stop = hdd_hostapd_stop;
3991 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3992 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3993 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3994 pWlanHostapdDev->get_stats = hdd_softap_stats;
3995 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3996 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3997#endif
3998}
3999
4000VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
4001{
4002 hdd_hostapd_state_t * phostapdBuf;
4003 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004004 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004005 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08004006#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08004007 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
4008 v_U16_t unsafeChannelCount;
4009#endif /* FEATURE_WLAN_CH_AVOID */
4010
Jeff Johnson295189b2012-06-20 16:38:30 -07004011 ENTER();
4012 // Allocate the Wireless Extensions state structure
4013 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
4014
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004015 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
4016
Leo Chang0b0e45a2013-12-15 15:18:55 -08004017#ifdef FEATURE_WLAN_CH_AVOID
4018 /* Get unsafe cahnnel list from cached location */
4019 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
4020 sizeof(unsafeChannelList),
4021 &unsafeChannelCount);
4022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4023 "%s : Unsafe Channel count %d",
4024 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05304025 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08004026 unsafeChannelList,
4027 unsafeChannelCount);
4028#endif /* FEATURE_WLAN_CH_AVOID */
4029
Jeff Johnson295189b2012-06-20 16:38:30 -07004030 // Zero the memory. This zeros the profile structure.
4031 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
4032
4033 // Set up the pointer to the Wireless Extensions state structure
4034 // NOP
4035 status = hdd_set_hostapd(pAdapter);
4036 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004038 return status;
4039 }
4040
4041 status = vos_event_init(&phostapdBuf->vosEvent);
4042 if (!VOS_IS_STATUS_SUCCESS(status))
4043 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004045 return status;
4046 }
4047
4048 init_completion(&pAdapter->session_close_comp_var);
4049 init_completion(&pAdapter->session_open_comp_var);
4050
4051 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
4052
4053 // Register as a wireless device
4054 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
4055
4056 //Initialize the data path module
4057 status = hdd_softap_init_tx_rx(pAdapter);
4058 if ( !VOS_IS_STATUS_SUCCESS( status ))
4059 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004060 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004061 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304062
4063 status = hdd_wmm_adapter_init( pAdapter );
4064 if (!VOS_IS_STATUS_SUCCESS(status))
4065 {
4066 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004067 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304068 status, status );
4069 goto error_wmm_init;
4070 }
4071
4072 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
4073
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304075
4076 return status;
4077
4078error_wmm_init:
4079 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07004080 EXIT();
4081 return status;
4082}
4083
4084hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
4085{
4086 struct net_device *pWlanHostapdDev = NULL;
4087 hdd_adapter_t *pHostapdAdapter = NULL;
4088 v_CONTEXT_t pVosContext= NULL;
4089
Jeff Johnson295189b2012-06-20 16:38:30 -07004090 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07004091
4092 if (pWlanHostapdDev != NULL)
4093 {
4094 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
4095
4096 //Init the net_device structure
4097 ether_setup(pWlanHostapdDev);
4098
4099 //Initialize the adapter context to zeros.
4100 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
4101 pHostapdAdapter->dev = pWlanHostapdDev;
4102 pHostapdAdapter->pHddCtx = pHddCtx;
4103 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
4104
4105 //Get the Global VOSS context.
4106 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4107 //Save the adapter context in global context for future.
4108 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
4109
4110 //Init the net_device structure
4111 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
4112
4113 hdd_set_ap_ops( pHostapdAdapter->dev );
4114
Jeff Johnson295189b2012-06-20 16:38:30 -07004115 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
4116 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
4117
4118 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
4119 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
4120
4121 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07004122 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
4123 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
4124 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
4125 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004126 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
4127 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05304128 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07004129#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4130 init_completion(&pHostapdAdapter->offchannel_tx_event);
4131#endif
4132
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
4134 }
4135 return pHostapdAdapter;
4136}
4137
4138VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
4139{
4140 struct net_device *dev = pAdapter->dev;
4141 VOS_STATUS status = VOS_STATUS_SUCCESS;
4142
4143 ENTER();
4144
4145 if( rtnl_lock_held )
4146 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08004147 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07004148 if( dev_alloc_name(dev, dev->name) < 0 )
4149 {
4150 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
4151 return VOS_STATUS_E_FAILURE;
4152 }
4153 }
4154 if (register_netdevice(dev))
4155 {
4156 hddLog(VOS_TRACE_LEVEL_FATAL,
4157 "%s:Failed:register_netdevice", __func__);
4158 return VOS_STATUS_E_FAILURE;
4159 }
4160 }
4161 else
4162 {
4163 if (register_netdev(dev))
4164 {
4165 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
4166 return VOS_STATUS_E_FAILURE;
4167 }
4168 }
4169 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
4170
4171 EXIT();
4172 return status;
4173}
4174
4175VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
4176{
4177 ENTER();
4178
4179 hdd_softap_deinit_tx_rx(pAdapter);
4180
4181 /* if we are being called during driver unload, then the dev has already
4182 been invalidated. if we are being called at other times, then we can
4183 detatch the wireless device handlers */
4184 if (pAdapter->dev)
4185 {
4186 pAdapter->dev->wireless_handlers = NULL;
4187 }
4188 EXIT();
4189 return 0;
4190}