blob: 57f3a8ef6ccc157642b04189017db771ad89ab5d [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
Jeff Johnson295189b2012-06-20 16:38:30 -070033
34 ========================================================================*/
35/**=========================================================================
36 EDIT HISTORY FOR FILE
37
38
39 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
41
42 $Header:$ $DateTime: $ $Author: $
43
44
45 when who what, where, why
46 -------- --- --------------------------------------------------------
47 04/5/09 Shailender Created module.
48 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
49 ==========================================================================*/
50/*--------------------------------------------------------------------------
51 Include Files
52 ------------------------------------------------------------------------*/
53
54#include <linux/version.h>
55#include <linux/module.h>
56#include <linux/kernel.h>
57#include <linux/init.h>
58#include <linux/wireless.h>
59#include <linux/semaphore.h>
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -070060#include <linux/compat.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070061#include <vos_api.h>
62#include <vos_sched.h>
63#include <linux/etherdevice.h>
64#include <wlan_hdd_includes.h>
65#include <qc_sap_ioctl.h>
66#include <wlan_hdd_hostapd.h>
67#include <sapApi.h>
68#include <sapInternal.h>
69#include <wlan_qct_tl.h>
70#include <wlan_hdd_softap_tx_rx.h>
71#include <wlan_hdd_main.h>
72#include <linux/netdevice.h>
73#include <linux/mmc/sdio_func.h>
74#include "wlan_nlink_common.h"
75#include "wlan_btc_svc.h"
76#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070077#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070078#include "cfgApi.h"
79#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070080
Leo Chang0b0e45a2013-12-15 15:18:55 -080081#ifdef FEATURE_WLAN_CH_AVOID
82#include "wcnss_wlan.h"
83#endif /* FEATURE_WLAN_CH_AVOID */
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Leo Chang0b0e45a2013-12-15 15:18:55 -080087
Jeff Johnson295189b2012-06-20 16:38:30 -070088#define IS_UP(_dev) \
89 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
90#define IS_UP_AUTO(_ic) \
91 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
92#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -070093#define WE_GET_STA_INFO_SIZE 30
94/* WEXT limition: MAX allowed buf len for any *
95 * IW_PRIV_TYPE_CHAR is 2Kbytes *
96 */
97#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -070098
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053099#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700100
Leo Chang0b0e45a2013-12-15 15:18:55 -0800101#ifdef FEATURE_WLAN_CH_AVOID
102/* Channle/Freqency table */
103extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
104safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
105{
106 /*CH , SAFE, default safe */
107 {1 , VOS_TRUE}, //RF_CHAN_1,
108 {2 , VOS_TRUE}, //RF_CHAN_2,
109 {3 , VOS_TRUE}, //RF_CHAN_3,
110 {4 , VOS_TRUE}, //RF_CHAN_4,
111 {5 , VOS_TRUE}, //RF_CHAN_5,
112 {6 , VOS_TRUE}, //RF_CHAN_6,
113 {7 , VOS_TRUE}, //RF_CHAN_7,
114 {8 , VOS_TRUE}, //RF_CHAN_8,
115 {9 , VOS_TRUE}, //RF_CHAN_9,
116 {10 , VOS_TRUE}, //RF_CHAN_10,
117 {11 , VOS_TRUE}, //RF_CHAN_11,
118 {12 , VOS_TRUE}, //RF_CHAN_12,
119 {13 , VOS_TRUE}, //RF_CHAN_13,
120 {14 , VOS_TRUE}, //RF_CHAN_14,
121 {240, VOS_TRUE}, //RF_CHAN_240,
122 {244, VOS_TRUE}, //RF_CHAN_244,
123 {248, VOS_TRUE}, //RF_CHAN_248,
124 {252, VOS_TRUE}, //RF_CHAN_252,
125 {208, VOS_TRUE}, //RF_CHAN_208,
126 {212, VOS_TRUE}, //RF_CHAN_212,
127 {216, VOS_TRUE}, //RF_CHAN_216,
128 {36 , VOS_TRUE}, //RF_CHAN_36,
129 {40 , VOS_TRUE}, //RF_CHAN_40,
130 {44 , VOS_TRUE}, //RF_CHAN_44,
131 {48 , VOS_TRUE}, //RF_CHAN_48,
132 {52 , VOS_TRUE}, //RF_CHAN_52,
133 {56 , VOS_TRUE}, //RF_CHAN_56,
134 {60 , VOS_TRUE}, //RF_CHAN_60,
135 {64 , VOS_TRUE}, //RF_CHAN_64,
136 {100, VOS_TRUE}, //RF_CHAN_100,
137 {104, VOS_TRUE}, //RF_CHAN_104,
138 {108, VOS_TRUE}, //RF_CHAN_108,
139 {112, VOS_TRUE}, //RF_CHAN_112,
140 {116, VOS_TRUE}, //RF_CHAN_116,
141 {120, VOS_TRUE}, //RF_CHAN_120,
142 {124, VOS_TRUE}, //RF_CHAN_124,
143 {128, VOS_TRUE}, //RF_CHAN_128,
144 {132, VOS_TRUE}, //RF_CHAN_132,
145 {136, VOS_TRUE}, //RF_CHAN_136,
146 {140, VOS_TRUE}, //RF_CHAN_140,
147 {149, VOS_TRUE}, //RF_CHAN_149,
148 {153, VOS_TRUE}, //RF_CHAN_153,
149 {157, VOS_TRUE}, //RF_CHAN_157,
150 {161, VOS_TRUE}, //RF_CHAN_161,
151 {165, VOS_TRUE}, //RF_CHAN_165,
152};
153#endif /* FEATURE_WLAN_CH_AVOID */
154
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530155/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700156 * Function definitions
157 *-------------------------------------------------------------------------*/
158/**---------------------------------------------------------------------------
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530159
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530160 \brief __hdd_hostapd_open() - HDD Open function for hostapd interface
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530161
Jeff Johnson295189b2012-06-20 16:38:30 -0700162 This is called in response to ifconfig up
163
164 \param - dev Pointer to net_device structure
165
166 \return - 0 for success non-zero for failure
167
168 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530169int __hdd_hostapd_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700170{
Siddharth Bhal2db319d2014-12-03 12:37:18 +0530171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
172
Jeff Johnson295189b2012-06-20 16:38:30 -0700173 ENTER();
174
Siddharth Bhal2db319d2014-12-03 12:37:18 +0530175 if(!test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
176 {
177 //WMM_INIT OR BSS_START not completed
178 hddLog( LOGW, "Ignore hostadp open request");
179 EXIT();
180 return 0;
181 }
182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
184 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -0700185 //Turn ON carrier state
186 netif_carrier_on(dev);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530187 //Enable all Tx queues
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530188 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700189 netif_tx_start_all_queues(dev);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530190
Jeff Johnson295189b2012-06-20 16:38:30 -0700191 EXIT();
192 return 0;
193}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530194
195int hdd_hostapd_open (struct net_device *dev)
196{
197 int ret;
198
199 vos_ssr_protect(__func__);
200 ret = __hdd_hostapd_open(dev);
201 vos_ssr_unprotect(__func__);
202
203 return ret;
204}
205
Jeff Johnson295189b2012-06-20 16:38:30 -0700206/**---------------------------------------------------------------------------
207
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530208 \brief __hdd_hostapd_stop() - HDD stop function for hostapd interface
Jeff Johnson295189b2012-06-20 16:38:30 -0700209
210 This is called in response to ifconfig down
211
212 \param - dev Pointer to net_device structure
213
214 \return - 0 for success non-zero for failure
215
216 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530217int __hdd_hostapd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700218{
219 ENTER();
220
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +0530221 if(NULL != dev) {
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +0530223 //Stop all tx queues
224 netif_tx_disable(dev);
225
226 //Turn OFF carrier state
227 netif_carrier_off(dev);
228 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230 EXIT();
231 return 0;
232}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530233
234int hdd_hostapd_stop (struct net_device *dev)
235{
236 int ret;
237
238 vos_ssr_protect(__func__);
239 ret = __hdd_hostapd_stop(dev);
240 vos_ssr_unprotect(__func__);
241
242 return ret;
243}
244
Jeff Johnson295189b2012-06-20 16:38:30 -0700245/**---------------------------------------------------------------------------
246
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530247 \brief __hdd_hostapd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -0700248
249 This is called during the netdev unregister to uninitialize all data
250associated with the device
251
252 \param - dev Pointer to net_device structure
253
254 \return - void
255
256 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530257static void __hdd_hostapd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700258{
259 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
260
261 ENTER();
262
263 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
264 {
265 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
266
267 /* after uninit our adapter structure will no longer be valid */
268 pHostapdAdapter->dev = NULL;
269 }
270
271 EXIT();
272}
273
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530274static void hdd_hostapd_uninit (struct net_device *dev)
275{
276 vos_ssr_protect(__func__);
277 __hdd_hostapd_uninit(dev);
278 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530280 return;
281}
Jeff Johnson295189b2012-06-20 16:38:30 -0700282/**============================================================================
283 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
284 transmitting packets. There are 2 versions of this function. One that uses
285 locked queue and other that uses lockless queues. Both have been retained to
286 do some performance testing
287 @param skb : [in] pointer to OS packet (sk_buff)
288 @param dev : [in] pointer to Libra network device
289
290 @return : NET_XMIT_DROP if packets are dropped
291 : NET_XMIT_SUCCESS if packet is enqueued succesfully
292 ===========================================================================*/
293int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
294{
295 return 0;
296}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530297
298int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
Jeff Johnson295189b2012-06-20 16:38:30 -0700299{
300 return 0;
301}
302
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530303int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
304{
305 int ret;
306 vos_ssr_protect(__func__);
307 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
308 vos_ssr_unprotect(__func__);
309
310 return ret;
311}
312
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700313static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
314 hdd_priv_data_t *priv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -0700315{
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700316 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530317 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
318 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700319 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530320 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700321 /*
322 * Note that valid pointers are provided by caller
323 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700324
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700325 if (priv_data->total_len <= 0 ||
326 priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
327 {
328 /* below we allocate one more byte for command buffer.
329 * To avoid addition overflow total_len should be
330 * smaller than INT_MAX. */
331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
332 __func__, priv_data->total_len);
333 ret = -EFAULT;
334 goto exit;
335 }
Kaushik, Sushant96122442014-10-21 16:40:18 +0530336 status = wlan_hdd_validate_context(pHddCtx);
337
338 if (0 != status)
339 {
340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
341 "%s: HDD context is not valid", __func__);
342 return status;
343 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700344
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700345 /* Allocate +1 for '\0' */
346 command = kmalloc((priv_data->total_len + 1), GFP_KERNEL);
347 if (!command)
348 {
349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__);
350 ret = -ENOMEM;
351 goto exit;
352 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700353
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700354 if (copy_from_user(command, priv_data->buf, priv_data->total_len))
355 {
356 ret = -EFAULT;
357 goto exit;
358 }
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800359
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700360 /* Make sure the command is NUL-terminated */
361 command[priv_data->total_len] = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -0700362
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700363 hddLog(VOS_TRACE_LEVEL_INFO,
364 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700366 if (strncmp(command, "P2P_SET_NOA", 11) == 0)
367 {
368 hdd_setP2pNoa(pAdapter->dev, command);
369 }
370 else if (strncmp(command, "P2P_SET_PS", 10) == 0)
371 {
372 hdd_setP2pOpps(pAdapter->dev, command);
373 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800374#ifdef FEATURE_WLAN_BATCH_SCAN
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700375 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
376 {
377 ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command);
378 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800379#endif
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700380 else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
381 {
382 /*
383 * command should be a string having format
384 * SET_SAP_CHANNEL_LIST <num channels> <channels seperated by spaces>
385 */
386 hddLog(VOS_TRACE_LEVEL_INFO,
387 "%s: Received Command to Set Preferred Channels for SAP",
388 __func__);
Rajeev Kumar8b373292014-01-08 20:36:55 -0800389
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700390 ret = sapSetPreferredChannel(command);
391 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530392 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
393 {
394 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
395 tANI_U8 filterType = 0;
396 tANI_U8 *value;
397 value = command + 9;
398
399 /* Convert the value from ascii to integer */
400 ret = kstrtou8(value, 10, &filterType);
401 if (ret < 0)
402 {
403 /* If the input value is greater than max value of datatype,
404 * then also kstrtou8 fails
405 */
406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
407 "%s: kstrtou8 failed range ", __func__);
408 ret = -EINVAL;
409 goto exit;
410 }
411 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
412 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
413 {
414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
415 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
416 " 2-Sink ", __func__);
417 ret = -EINVAL;
418 goto exit;
419 }
420 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
421 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530422 pScanInfo = &pHddCtx->scan_info;
423 if (filterType && pScanInfo != NULL &&
424 pHddCtx->scan_info.mScanPending)
425 {
426 /*Miracast Session started. Abort Scan */
427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
428 "%s, Aborting Scan For Miracast",__func__);
429 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
430 eCSR_SCAN_ABORT_DEFAULT);
431 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530432 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
433 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
434 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700435
Jeff Johnson295189b2012-06-20 16:38:30 -0700436exit:
437 if (command)
438 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700439 kfree(command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700440 }
441 return ret;
442}
443
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700444#ifdef CONFIG_COMPAT
445static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
446 struct ifreq *ifr)
447{
448 struct {
449 compat_uptr_t buf;
450 int used_len;
451 int total_len;
452 } compat_priv_data;
453 hdd_priv_data_t priv_data;
454 int ret = 0;
455
456 /*
457 * Note that pAdapter and ifr have already been verified by caller,
458 * and HDD context has also been validated
459 */
460 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
461 sizeof(compat_priv_data))) {
462 ret = -EFAULT;
463 goto exit;
464 }
465 priv_data.buf = compat_ptr(compat_priv_data.buf);
466 priv_data.used_len = compat_priv_data.used_len;
467 priv_data.total_len = compat_priv_data.total_len;
468 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
469 exit:
470 return ret;
471}
472#else /* CONFIG_COMPAT */
473static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
474 struct ifreq *ifr)
475{
476 /* will never be invoked */
477 return 0;
478}
479#endif /* CONFIG_COMPAT */
480
481static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
482{
483 hdd_priv_data_t priv_data;
484 int ret = 0;
485
486 /*
487 * Note that pAdapter and ifr have already been verified by caller,
488 * and HDD context has also been validated
489 */
490 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
491 ret = -EFAULT;
492 } else {
493 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
494 }
495 return ret;
496}
497
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530498static int __hdd_hostapd_ioctl(struct net_device *dev,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700499 struct ifreq *ifr, int cmd)
500{
501 hdd_adapter_t *pAdapter;
502 hdd_context_t *pHddCtx;
503 int ret;
504
505 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
506 if (NULL == pAdapter) {
507 hddLog(VOS_TRACE_LEVEL_ERROR,
508 "%s: HDD adapter context is Null", __func__);
509 ret = -ENODEV;
510 goto exit;
511 }
512 if (dev != pAdapter->dev) {
513 hddLog(VOS_TRACE_LEVEL_ERROR,
514 "%s: HDD adapter/dev inconsistency", __func__);
515 ret = -ENODEV;
516 goto exit;
517 }
518
519 if ((!ifr) || (!ifr->ifr_data)) {
520 ret = -EINVAL;
521 goto exit;
522 }
523
524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
525 ret = wlan_hdd_validate_context(pHddCtx);
526 if (ret) {
527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__);
528 ret = -EBUSY;
529 goto exit;
530 }
531
532 switch (cmd) {
533 case (SIOCDEVPRIVATE + 1):
534 if (is_compat_task())
535 ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
536 else
537 ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
538 break;
539 default:
540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
541 __func__, cmd);
542 ret = -EINVAL;
543 break;
544 }
545 exit:
546 return ret;
547}
548
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530549static int hdd_hostapd_ioctl(struct net_device *dev,
550 struct ifreq *ifr, int cmd)
551{
552 int ret;
553
554 vos_ssr_protect(__func__);
555 ret = __hdd_hostapd_ioctl(dev, ifr, cmd);
556 vos_ssr_unprotect(__func__);
557
558 return ret;
559}
560
Jeff Johnson295189b2012-06-20 16:38:30 -0700561/**---------------------------------------------------------------------------
562
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530563 \brief __hdd_hostapd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -0700564 This function sets the user specified mac address using
565 the command ifconfig wlanX hw ether <mac adress>.
566
567 \param - dev - Pointer to the net device.
568 - addr - Pointer to the sockaddr.
569 \return - 0 for success, non zero for failure
570
571 --------------------------------------------------------------------------*/
572
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530573static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -0700574{
575 struct sockaddr *psta_mac_addr = addr;
576 ENTER();
577 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
578 EXIT();
579 return 0;
580}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530581
582static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
583{
584 int ret;
585
586 vos_ssr_protect(__func__);
587 ret = __hdd_hostapd_set_mac_address(dev, addr);
588 vos_ssr_unprotect(__func__);
589
590 return ret;
591}
592
Jeff Johnson295189b2012-06-20 16:38:30 -0700593void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
594{
595 struct net_device *dev = (struct net_device *)usrDataForCallback;
596 v_BYTE_t we_custom_event[64];
597 union iwreq_data wrqu;
598#ifdef DISABLE_CONCURRENCY_AUTOSAVE
599 VOS_STATUS vos_status;
600 hdd_adapter_t *pHostapdAdapter;
601 hdd_ap_ctx_t *pHddApCtx;
602#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
603
604 /* event_name space-delimiter driver_module_name */
605 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
606 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
607 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
608
609 ENTER();
610
Agarwal Ashish51325b52014-06-16 16:50:49 +0530611#ifdef DISABLE_CONCURRENCY_AUTOSAVE
612 if (vos_concurrent_open_sessions_running())
Jeff Johnson295189b2012-06-20 16:38:30 -0700613 {
614 /*
615 This timer routine is going to be called only when AP
616 persona is up.
617 If there are concurrent sessions running we do not want
618 to shut down the Bss.Instead we run the timer again so
619 that if Autosave is enabled next time and other session
620 was down only then we bring down AP
621 */
622 pHostapdAdapter = netdev_priv(dev);
623 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
624 vos_status = vos_timer_start(
625 &pHddApCtx->hdd_ap_inactivity_timer,
626 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
627 * 1000);
628 if (!VOS_IS_STATUS_SUCCESS(vos_status))
629 {
630 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
631 }
632 EXIT();
633 return;
634 }
635#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
636 memset(&we_custom_event, '\0', sizeof(we_custom_event));
637 memcpy(&we_custom_event, autoShutEvent, event_len);
638
639 memset(&wrqu, 0, sizeof(wrqu));
640 wrqu.data.length = event_len;
641
642 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
643 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
644
645 EXIT();
646}
647
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800648VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
649{
650 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
651 ptSapContext pSapCtx = NULL;
652 eHalStatus halStatus = eHAL_STATUS_FAILURE;
653 v_PVOID_t hHal = NULL;
654
655 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
656 "%s: UPDATE Beacon Params", __func__);
657
658 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
659 pSapCtx = VOS_GET_SAP_CB(pVosContext);
660 if ( NULL == pSapCtx )
661 {
662 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
663 "%s: Invalid SAP pointer from pvosGCtx", __func__);
664 return VOS_STATUS_E_FAULT;
665 }
666
667 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
668 if ( NULL == hHal ){
669 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
670 "%s: Invalid HAL pointer from pvosGCtx", __func__);
671 return VOS_STATUS_E_FAULT;
672 }
673 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
674 if(halStatus == eHAL_STATUS_FAILURE ){
675 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
676 "%s: Failed to update Beacon Params", __func__);
677 return VOS_STATUS_E_FAILURE;
678 }
679 }
680 return VOS_STATUS_SUCCESS;
681}
682
683void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
684{
685 v_U8_t staId = 0;
686 struct net_device *dev;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530687 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
688 ptSapContext pSapCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800689
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530690 dev = (struct net_device *)usrDataForCallback;
691 pSapCtx = VOS_GET_SAP_CB(pVosContext);
692 if(pSapCtx == NULL){
693 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
694 FL("psapCtx is NULL"));
695 return;
696 }
Arif Hussain6d2a3322013-11-17 19:50:10 -0800697 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800698 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
699 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530700 if ( pSapCtx->aStaInfo[staId].isUsed &&
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800701 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
702 {
703 //Disconnect all the stations
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530704 hdd_softap_sta_disassoc(pHostapdAdapter, &pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800705 }
706 }
707}
708
Agarwal Ashish8e538932014-12-24 18:12:52 +0530709static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800710{
711 struct net_device *dev;
Agarwal Ashish51325b52014-06-16 16:50:49 +0530712 hdd_context_t *pHddCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800713 VOS_STATUS status = VOS_STATUS_SUCCESS;
714 dev = (struct net_device *)usrDataForCallback;
715 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +0530716
717 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
718 status = wlan_hdd_validate_context(pHddCtx);
719
720 if (0 != status) {
721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
722 return status;
723 }
724
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800725 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
726 {
727 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
728 {
Agarwal Ashish8e538932014-12-24 18:12:52 +0530729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting SAP/P2P link!!!!!!"));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800730 }
731 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +0530732 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800733 }
734 EXIT();
735 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
736}
Jeff Johnson295189b2012-06-20 16:38:30 -0700737
738VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
739{
740 hdd_adapter_t *pHostapdAdapter;
741 hdd_ap_ctx_t *pHddApCtx;
742 hdd_hostapd_state_t *pHostapdState;
743 struct net_device *dev;
744 eSapHddEvent sapEvent;
745 union iwreq_data wrqu;
746 v_BYTE_t *we_custom_event_generic = NULL;
747 int we_event = 0;
748 int i = 0;
749 v_U8_t staId;
750 VOS_STATUS vos_status;
751 v_BOOL_t bWPSState;
752 v_BOOL_t bApActive = FALSE;
753 v_BOOL_t bAuthRequired = TRUE;
754 tpSap_AssocMacAddr pAssocStasArray = NULL;
755 char unknownSTAEvent[IW_CUSTOM_MAX+1];
756 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
757 v_BYTE_t we_custom_start_event[64];
758 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800759 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800760 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700761 struct iw_michaelmicfailure msg;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530762 v_CONTEXT_t pVosContext = NULL;
763 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700764
765 dev = (struct net_device *)usrDataForCallback;
766 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530767
768 if ((NULL == pHostapdAdapter) ||
769 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
770 {
771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
772 "invalid adapter or adapter has invalid magic");
773 return eHAL_STATUS_FAILURE;
774 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530775 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
776 pSapCtx = VOS_GET_SAP_CB(pVosContext);
777 if(pSapCtx == NULL){
778 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
779 FL("psapCtx is NULL"));
780 return eHAL_STATUS_FAILURE;
781 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
783 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
784 sapEvent = pSapEvent->sapHddEventCode;
785 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800786 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700787
788 switch(sapEvent)
789 {
790 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800791 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700792 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
793 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
794 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
795
796 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
797 vos_status = vos_event_set(&pHostapdState->vosEvent);
798
799 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
800 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 goto stopbss;
803 }
804 else
805 {
806 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
807 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530808 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
809 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Agarwal Ashish8e538932014-12-24 18:12:52 +0530810 {
c_hpothuffdb5272013-10-02 16:42:35 +0530811 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
Agarwal Ashish8e538932014-12-24 18:12:52 +0530812 hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
813 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700814 }
815
816 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
817 {
818 // AP Inactivity timer init and start
819 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
820 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
821 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800822 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700823
824 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
825 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800826 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700827
828 }
829 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
830 pHostapdState->bssState = BSS_START;
831
832 // Send current operating channel of SoftAP to BTC-ES
833 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
834
Jeff Johnson295189b2012-06-20 16:38:30 -0700835 //Check if there is any group key pending to set.
836 if( pHddApCtx->groupKey.keyLength )
837 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700838 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
840 &pHddApCtx->groupKey ) )
841 {
842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
843 "%s: WLANSAP_SetKeySta failed", __func__);
844 }
845 pHddApCtx->groupKey.keyLength = 0;
846 }
847 else if ( pHddApCtx->wepKey[0].keyLength )
848 {
849 int i=0;
850 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
851 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700852 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
854 &pHddApCtx->wepKey[i] ) )
855 {
856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
857 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
858 }
859 pHddApCtx->wepKey[i].keyLength = 0;
860 }
861 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700862 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
863 startBssEvent = "SOFTAP.enabled";
864 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
865 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
866 memset(&wrqu, 0, sizeof(wrqu));
867 wrqu.data.length = strlen(startBssEvent);
868 we_event = IWEVCUSTOM;
869 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700870 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 break; //Event will be sent after Switch-Case stmt
872
873 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800874 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700875 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
876
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700877 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700878 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700879
Jeff Johnson295189b2012-06-20 16:38:30 -0700880 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 goto stopbss;
882 case eSAP_STA_SET_KEY_EVENT:
883 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800884 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700885 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
886 return VOS_STATUS_SUCCESS;
887 case eSAP_STA_DEL_KEY_EVENT:
888 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800889 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 return VOS_STATUS_SUCCESS;
891 case eSAP_STA_MIC_FAILURE_EVENT:
892 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700893 memset(&msg, '\0', sizeof(msg));
894 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800895 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800896 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700897 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700898 msg.flags = IW_MICFAILURE_GROUP;
899 else
900 msg.flags = IW_MICFAILURE_PAIRWISE;
901 memset(&wrqu, 0, sizeof(wrqu));
902 wrqu.data.length = sizeof(msg);
903 we_event = IWEVMICHAELMICFAILURE;
904 we_custom_event_generic = (v_BYTE_t *)&msg;
905 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700906 /* inform mic failure to nl80211 */
907 cfg80211_michael_mic_failure(dev,
908 pSapEvent->sapevt.
909 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700910 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700911 NL80211_KEYTYPE_GROUP :
912 NL80211_KEYTYPE_PAIRWISE),
913 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
914 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
915 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 break;
917
918 case eSAP_STA_ASSOC_EVENT:
919 case eSAP_STA_REASSOC_EVENT:
920 wrqu.addr.sa_family = ARPHRD_ETHER;
921 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800922 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800923 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 we_event = IWEVREGISTERED;
925
926 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
927
928 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
929 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
930 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
931 {
932 bAuthRequired = FALSE;
933 }
934
935 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
936 {
c_hpothuffdb5272013-10-02 16:42:35 +0530937 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700938 TRUE,
939 pHddApCtx->uPrivacy,
940 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
941 0,
942 0,
943 (v_MACADDR_t *)wrqu.addr.sa_data,
944 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530945
946 if (!VOS_IS_STATUS_SUCCESS(vos_status))
947 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
948 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700949 }
950 else
951 {
c_hpothuffdb5272013-10-02 16:42:35 +0530952 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 FALSE,
954 pHddApCtx->uPrivacy,
955 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
956 0,
957 0,
958 (v_MACADDR_t *)wrqu.addr.sa_data,
959 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530960 if (!VOS_IS_STATUS_SUCCESS(vos_status))
961 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
962 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Amar Singhal6144c002013-05-03 16:11:42 -0700963 }
964
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 // Stop AP inactivity timer
966 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
967 {
968 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
969 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800970 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800972#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800973 if (wake_lock_active(&pHddCtx->sap_wake_lock))
974 {
975 wake_unlock(&pHddCtx->sap_wake_lock);
976 }
Amar Singhal6144c002013-05-03 16:11:42 -0700977 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800978#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
980 {
981 struct station_info staInfo;
982 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
983
984 memset(&staInfo, 0, sizeof(staInfo));
985 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
986 {
987 staInfo.assoc_req_ies =
988 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
989 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700991 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 cfg80211_new_sta(dev,
994 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
995 &staInfo, GFP_KERNEL);
996 }
997 else
998 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800999 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 }
1001 }
1002#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08001003 pScanInfo = &pHddCtx->scan_info;
1004 // Lets do abort scan to ensure smooth authentication for client
1005 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
1006 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05301007 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301008 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08001009 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001010
1011 break;
1012 case eSAP_STA_DISASSOC_EVENT:
1013 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -08001014 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -08001015 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -07001016 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
1017 hddLog(LOG1," User initiated disassociation");
1018 else
1019 hddLog(LOG1," MAC initiated disassociation");
1020 we_event = IWEVEXPIRED;
1021 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
1022 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1023 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001024 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 -07001025 return VOS_STATUS_E_FAILURE;
1026 }
1027 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
1028
1029 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1030 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301031 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001032 // Start AP inactivity timer if no stations associated with it
1033 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1034 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301035 if (pSapCtx->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
Jeff Johnson295189b2012-06-20 16:38:30 -07001036 {
1037 bApActive = TRUE;
1038 break;
1039 }
1040 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301041 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001042
1043 if (bApActive == FALSE)
1044 {
1045 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
1046 {
1047 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
1048 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -08001049 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 }
1051 else
1052 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
1053 }
1054 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1056 cfg80211_del_sta(dev,
1057 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
1058 GFP_KERNEL);
1059#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001060 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +05301061 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
1062 if (VOS_STATUS_SUCCESS != vos_status)
1063 {
1064 hddLog(LOGE, "%s: failed to update Beacon interval %d",
1065 __func__, vos_status);
1066 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 break;
1068 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1069 {
1070 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
1071 union iwreq_data wreq;
1072
1073 down(&pHddApCtx->semWpsPBCOverlapInd);
1074 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
1075
1076 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
1077 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1078
1079 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -08001080 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 memset(&wreq, 0, sizeof(wreq));
1082 wreq.data.length = strlen(message); // This is length of message
1083 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
1084
1085 return VOS_STATUS_SUCCESS;
1086 }
1087 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1088 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1089 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
1090 { // List of associated stations
1091 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
1092 {
1093 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
1094 i+1,
1095 pAssocStasArray->assocId,
1096 pAssocStasArray->staId,
1097 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
1098 pAssocStasArray++;
1099 }
1100 }
1101 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001102 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 case eSAP_INDICATE_MGMT_FRAME:
1105 hdd_indicateMgmtFrame( pHostapdAdapter,
1106 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
1107 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
1108 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05301109 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 return VOS_STATUS_SUCCESS;
1111 case eSAP_REMAIN_CHAN_READY:
1112 hdd_remainChanReadyHandler( pHostapdAdapter );
1113 return VOS_STATUS_SUCCESS;
1114 case eSAP_SEND_ACTION_CNF:
1115 hdd_sendActionCnf( pHostapdAdapter,
1116 ( eSAP_STATUS_SUCCESS ==
1117 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
1118 TRUE : FALSE );
1119 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 case eSAP_UNKNOWN_STA_JOIN:
1121 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1122 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1123 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1124 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1125 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1126 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1127 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1128 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1129 wrqu.data.pointer = unknownSTAEvent;
1130 wrqu.data.length = strlen(unknownSTAEvent);
1131 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +05301132 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001133 break;
1134
1135 case eSAP_MAX_ASSOC_EXCEEDED:
1136 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1137 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1138 " one or more devices to enable the new device connection",
1139 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1140 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1141 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1142 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1143 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1144 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
1145 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1146 wrqu.data.pointer = maxAssocExceededEvent;
1147 wrqu.data.length = strlen(maxAssocExceededEvent);
1148 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001149 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 break;
1151 case eSAP_STA_ASSOC_IND:
1152 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001153
1154 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001155 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001156 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
1157 return VOS_STATUS_SUCCESS;
1158
1159 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
Agarwal Ashish8e538932014-12-24 18:12:52 +05301160 vos_status = hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
c_hpothuffdb5272013-10-02 16:42:35 +05301161 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1162 {
Agarwal Ashish8e538932014-12-24 18:12:52 +05301163 hddLog(LOGW, FL("hdd_stop_bss_link failed %d"), vos_status);
c_hpothuffdb5272013-10-02 16:42:35 +05301164 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001165 return VOS_STATUS_SUCCESS;
1166
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001168 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 goto stopbss;
1170 return VOS_STATUS_SUCCESS;
1171 }
1172 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1173 return VOS_STATUS_SUCCESS;
1174
1175stopbss :
1176 {
1177 v_BYTE_t we_custom_event[64];
1178 char *stopBssEvent = "STOP-BSS.response";//17
1179 int event_len = strlen(stopBssEvent);
1180
1181 hddLog(LOG1, FL("BSS stop status = %s"),
1182 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1183 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1184
1185 /* Change the BSS state now since, as we are shutting things down,
1186 * we don't want interfaces to become re-enabled */
1187 pHostapdState->bssState = BSS_STOP;
1188
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301189 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1190 {
1191 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1192 {
1193 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1194 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1195 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1196 }
1197
1198 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1199 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1200 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1201 }
1202
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 /* Stop the pkts from n/w stack as we are going to free all of
1204 * the TX WMM queues for all STAID's */
1205 hdd_hostapd_stop(dev);
1206
1207 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301208 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1209 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1210 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001211
Amar Singhal37e6f052013-03-05 16:16:54 -08001212 /* once the event is set, structure dev/pHostapdAdapter should
1213 * not be touched since they are now subject to being deleted
1214 * by another thread */
1215 if (eSAP_STOP_BSS_EVENT == sapEvent)
1216 vos_event_set(&pHostapdState->vosEvent);
1217
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 /* notify userspace that the BSS has stopped */
1219 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1220 memcpy(&we_custom_event, stopBssEvent, event_len);
1221 memset(&wrqu, 0, sizeof(wrqu));
1222 wrqu.data.length = event_len;
1223 we_event = IWEVCUSTOM;
1224 we_custom_event_generic = we_custom_event;
1225 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001226 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 }
1228 return VOS_STATUS_SUCCESS;
1229}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001230
1231int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001233 eCsrEncryptionType *pEncryptType,
1234 eCsrEncryptionType *mcEncryptType,
1235 eCsrAuthType *pAuthType,
1236 v_BOOL_t *pMFPCapable,
1237 v_BOOL_t *pMFPRequired,
1238 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 u_int8_t *gen_ie )
1240{
1241 tDot11fIERSN dot11RSNIE;
1242 tDot11fIEWPA dot11WPAIE;
1243
1244 tANI_U8 *pRsnIe;
1245 tANI_U16 RSNIeLen;
1246
1247 if (NULL == halHandle)
1248 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001249 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001250 return -EINVAL;
1251 }
1252
1253 // Validity checks
1254 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1255 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1256 return -EINVAL;
1257 // Type check
1258 if ( gen_ie[0] == DOT11F_EID_RSN)
1259 {
1260 // Validity checks
1261 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1262 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1263 {
1264 return VOS_STATUS_E_FAILURE;
1265 }
1266 // Skip past the EID byte and length byte
1267 pRsnIe = gen_ie + 2;
1268 RSNIeLen = gen_ie_len - 2;
1269 // Unpack the RSN IE
1270 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1271 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1272 pRsnIe,
1273 RSNIeLen,
1274 &dot11RSNIE);
1275 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001276 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001277 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001278 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001279 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001280 /*Here we have followed the apple base code,
1281 but probably I suspect we can do something different*/
1282 //dot11RSNIE.akm_suite_count
1283 // Just translate the FIRST one
1284 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1285 //dot11RSNIE.pwise_cipher_suite_count
1286 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1287 //dot11RSNIE.gp_cipher_suite_count
1288 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1289 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001290 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1291 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001292
1293 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1294 } else
1295 if (gen_ie[0] == DOT11F_EID_WPA)
1296 {
1297 // Validity checks
1298 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1299 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1300 {
1301 return VOS_STATUS_E_FAILURE;
1302 }
1303 // Skip past the EID byte and length byte - and four byte WiFi OUI
1304 pRsnIe = gen_ie + 2 + 4;
1305 RSNIeLen = gen_ie_len - (2 + 4);
1306 // Unpack the WPA IE
1307 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1308 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1309 pRsnIe,
1310 RSNIeLen,
1311 &dot11WPAIE);
1312 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001313 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001314 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001315 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001316 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 //dot11WPAIE.auth_suite_count
1318 // Just translate the FIRST one
1319 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1320 //dot11WPAIE.unicast_cipher_count
1321 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1322 //dot11WPAIE.unicast_cipher_count
1323 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001324 *pMFPCapable = VOS_FALSE;
1325 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001326 }
1327 else
1328 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001329 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 return VOS_STATUS_E_FAILURE;
1331 }
1332 return VOS_STATUS_SUCCESS;
1333}
Leo Chang614d2072013-08-22 14:59:44 -07001334
Leo Chang0b0e45a2013-12-15 15:18:55 -08001335#ifdef FEATURE_WLAN_CH_AVOID
1336/**---------------------------------------------------------------------------
1337
1338 \brief hdd_hostapd_freq_to_chn() -
1339
1340 Input frequency translated into channel number
1341
1342 \param - freq input frequency with order of kHz
1343
1344 \return - corresponding channel number.
1345 incannot find correct channel number, return 0
1346
1347 --------------------------------------------------------------------------*/
1348v_U16_t hdd_hostapd_freq_to_chn
1349(
1350 v_U16_t freq
1351)
1352{
1353 int loop;
1354
1355 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1356 {
1357 if (rfChannels[loop].targetFreq == freq)
1358 {
1359 return rfChannels[loop].channelNum;
1360 }
1361 }
1362
1363 return (0);
1364}
1365
1366/*==========================================================================
1367 FUNCTION sapUpdateUnsafeChannelList
1368
1369 DESCRIPTION
1370 Function Undate unsafe channel list table
1371
1372 DEPENDENCIES
1373 NA.
1374
1375 PARAMETERS
1376
1377 IN
1378 pSapCtx : SAP context pointer, include unsafe channel list
1379
1380 RETURN VALUE
1381 NONE
1382============================================================================*/
1383void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1384 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1385{
1386 v_U16_t i, j;
1387
1388 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1389 sizeof(pHddCtx->unsafeChannelList));
1390 if (0 == unsafeChannelCount)
1391 {
1392 pHddCtx->unsafeChannelCount = 0;
1393 }
1394 else
1395 {
c_hpothu8de53e42014-08-22 15:00:37 +05301396 if (unsafeChannelCount > NUM_20MHZ_RF_CHANNELS)
1397 {
1398 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1399 FL("unsafeChannelCount%hd greater than %d"),
1400 unsafeChannelCount, NUM_20MHZ_RF_CHANNELS);
1401 unsafeChannelCount = NUM_20MHZ_RF_CHANNELS;
1402 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001403 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1404 unsafeChannelList,
1405 unsafeChannelCount * sizeof(tANI_U16));
1406 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1407 }
1408
1409 /* Flush, default set all channel safe */
1410 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1411 {
1412 safeChannels[i].isSafe = VOS_TRUE;
1413 }
1414
1415 /* Try to find unsafe channel */
1416 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1417 {
1418 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1419 {
1420 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1421 {
1422 /* Found unsafe channel, update it */
1423 safeChannels[j].isSafe = VOS_FALSE;
1424 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1425 "%s : CH %d is not safe",
1426 __func__, pHddCtx->unsafeChannelList[i]);
1427 break;
1428 }
1429 }
1430 }
1431
1432 return;
1433}
1434
1435/**---------------------------------------------------------------------------
1436
1437 \brief hdd_hostapd_ch_avoid_cb() -
1438
1439 Avoid channel notification from FW handler.
1440 FW will send un-safe channle list to avoid overwrapping.
1441 hostapd should not use notified channel
1442
1443 \param - pAdapter HDD adapter pointer
1444 indParam channel avoid notification parameter
1445
1446 \return - None
1447
1448 --------------------------------------------------------------------------*/
1449void hdd_hostapd_ch_avoid_cb
1450(
1451 void *pAdapter,
1452 void *indParam
1453)
1454{
1455 hdd_adapter_t *pHostapdAdapter = NULL;
1456 hdd_context_t *hddCtxt;
1457 tSirChAvoidIndType *chAvoidInd;
1458 v_U8_t rangeLoop;
1459 v_U16_t channelLoop;
1460 v_U16_t dupCheck;
1461 v_U16_t startChannel;
1462 v_U16_t endChannel;
1463 v_U16_t unsafeChannelCount = 0;
1464 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1465 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001466 tHddAvoidFreqList hddAvoidFreqList;
1467 tANI_U32 i;
Hardik Kantilal Patel8c2d5232015-01-08 00:31:38 +05301468#ifdef WLAN_FEATURE_AP_HT40_24G
1469 ptSapContext pSapCtx = NULL;
1470 tHalHandle hHal;
1471 v_U8_t cbMode;
1472 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1473 v_U32_t delay;
1474#endif
Leo Chang0b0e45a2013-12-15 15:18:55 -08001475
1476 /* Basic sanity */
1477 if ((NULL == pAdapter) || (NULL == indParam))
1478 {
1479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1480 "%s : Invalid arguments", __func__);
1481 return;
1482 }
1483
1484 hddCtxt = (hdd_context_t *)pAdapter;
1485 chAvoidInd = (tSirChAvoidIndType *)indParam;
1486 pVosContext = hddCtxt->pvosContext;
1487
1488 /* Make unsafe channel list */
1489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1490 "%s : band count %d",
1491 __func__, chAvoidInd->avoidRangeCount);
1492 vos_mem_zero((void *)unsafeChannelList,
1493 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1494 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1495 {
1496 startChannel = hdd_hostapd_freq_to_chn(
1497 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1498 endChannel = hdd_hostapd_freq_to_chn(
1499 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1501 "%s : start %d : %d, end %d : %d",
1502 __func__,
1503 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1504 startChannel,
1505 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1506 endChannel);
1507 for (channelLoop = startChannel;
1508 channelLoop < (endChannel + 1);
1509 channelLoop++)
1510 {
1511 /* Channel duplicate check routine */
1512 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1513 {
1514 if (unsafeChannelList[dupCheck] == channelLoop)
1515 {
1516 /* This channel is duplicated */
1517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1518 "%s : found duplicated channel %d",
1519 __func__, channelLoop);
1520 break;
1521 }
1522 }
1523 if (dupCheck == unsafeChannelCount)
1524 {
c_hpothu8de53e42014-08-22 15:00:37 +05301525 int ii;
1526 for(ii=0; ii<NUM_20MHZ_RF_CHANNELS; ii++)
1527 {
1528 if (channelLoop == safeChannels[ii].channelNumber)
1529 {
1530 unsafeChannelList[unsafeChannelCount] = channelLoop;
1531 unsafeChannelCount++;
1532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1533 "%s : unsafe channel %d, count %d",
1534 __func__,
1535 channelLoop, unsafeChannelCount);
1536 }
1537 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001538 }
1539 else
1540 {
1541 /* DUP, do nothing */
1542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1543 "%s : duplicated channel %d",
1544 __func__, channelLoop);
1545 }
1546 }
1547 }
1548 /* Update unsafe channel cache
1549 * WCN Platform Driver cache */
1550 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1551 unsafeChannelCount);
1552
1553 /* Store into local cache
1554 * Start with STA and later start SAP
1555 * in this scenario, local cache will be used */
1556 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1557 unsafeChannelList,
1558 unsafeChannelCount);
1559
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001560 /* generate vendor specific event */
1561 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1562 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1563 {
1564 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1565 chAvoidInd->avoidFreqRange[i].startFreq;
1566 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1567 chAvoidInd->avoidFreqRange[i].endFreq;
1568 }
1569 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1570
1571 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1572
Leo Chang0b0e45a2013-12-15 15:18:55 -08001573 /* Get SAP context first
1574 * SAP and P2PGO would not concurrent */
1575 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
Hardik Kantilal Patel8c2d5232015-01-08 00:31:38 +05301576#ifdef WLAN_FEATURE_AP_HT40_24G
1577 if (NULL == pHostapdAdapter)
1578 {
1579 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_P2P_GO);
1580 }
1581#endif
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +05301582 if ((pHostapdAdapter) &&
1583 (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) &&
1584 (unsafeChannelCount))
Leo Chang0b0e45a2013-12-15 15:18:55 -08001585 {
1586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1587 "%s : Current operation channel %d",
1588 __func__,
1589 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1590 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1591 {
Hardik Kantilal Patel8c2d5232015-01-08 00:31:38 +05301592 if ((unsafeChannelList[channelLoop] ==
1593 pHostapdAdapter->sessionCtx.ap.operatingChannel))
1594 {
1595 if ((AUTO_CHANNEL_SELECT ==
1596 pHostapdAdapter->sessionCtx.ap.sapConfig.channel)
1597 && (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode))
1598 {
1599 /* current operating channel is un-safe channel
1600 * restart driver */
1601 hdd_hostapd_stop(pHostapdAdapter->dev);
1602 /* On LE, this event is handled by wlan-services to
1603 * restart SAP. On android, this event would be
1604 * ignored.
1605 */
1606 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND,
1607 NULL, 0);
1608 }
1609 return;
1610 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001611 }
1612 }
1613
Hardik Kantilal Patel8c2d5232015-01-08 00:31:38 +05301614#ifdef WLAN_FEATURE_AP_HT40_24G
1615 if (hddCtxt->cfg_ini->apHT40_24GEnabled)
1616 {
1617 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1618
1619 if(pSapCtx == NULL)
1620 {
1621 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1622 FL("psapCtx is NULL"));
1623 return;
1624 }
1625
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1627 FL("SAP Secondary channel: %d "),
1628 pSapCtx->sap_sec_chan);
1629
1630 /* tHalHandle */
1631 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
1632
1633 if (NULL == hHal)
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1636 FL("In invalid hHal"));
1637 return;
1638 }
1639
1640 cbMode = sme_GetChannelBondingMode24G(hHal);
1641
1642 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1643 FL("Selected Channel bonding : %d"), cbMode);
1644
1645 if (cbMode && (pSapCtx->sap_sec_chan > 0))
1646 {
1647 int i;
1648 eHalStatus halStatus;
1649
1650 for (i = 0; i < unsafeChannelCount; i++)
1651 {
1652 if ((pSapCtx->sap_sec_chan == unsafeChannelList[i]))
1653 {
1654 /* Current SAP Secondary channel is un-safe channel */
1655 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1656 FL("Move SAP from HT40 to HT20"));
1657
1658 halStatus = sme_SetHT2040Mode(hHal, pSapCtx->sessionId,
1659 PHY_SINGLE_CHANNEL_CENTERED);
1660
1661 if (halStatus == eHAL_STATUS_FAILURE)
1662 {
1663 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1664 FL("Failed to change HT20/40 mode"));
1665 return;
1666 }
1667
1668 /* Disable Channel Bonding for 2.4GHz */
1669 sme_UpdateChannelBondingMode24G(hHal,
1670 PHY_SINGLE_CHANNEL_CENTERED);
1671 return;
1672 }
1673 }
1674 }
1675
1676 if ((!pSapCtx->numHT40IntoSta)
1677 && (pHostapdAdapter)
1678 && (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)))
1679 {
1680 /* if Unsafe channel is Zero or SAP Primary/Secondary channel
1681 * are Safe then start HT20/40 timer to Move SAP from HT20
1682 * to HT40.
1683 */
1684 if (((!unsafeChannelCount)
1685 || (!sapCheckHT40SecondaryIsNotAllowed(pSapCtx))) && (!cbMode))
1686 {
1687 /* Stop Previous Running HT20/40 Timer & Start timer
1688 with (OBSS TransitionDelayFactor * obss interval)
1689 delay after time out move AP from HT20 -> HT40
1690 mode
1691 */
1692 if (VOS_TIMER_STATE_RUNNING == pSapCtx->sap_HT2040_timer.state)
1693 {
1694 vosStatus = vos_timer_stop(&pSapCtx->sap_HT2040_timer);
1695 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1696 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1697 FL("Failed to Stop HT20/40 timer"));
1698 }
1699
1700 delay =
1701 (pSapCtx->ObssScanInterval * pSapCtx->ObssTransitionDelayFactor);
1702
1703 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1704 FL("Start HT20/40 transition timer (%d sec)"), delay);
1705
1706 vosStatus = vos_timer_start( &pSapCtx->sap_HT2040_timer,
1707 (delay * 1000));
1708
1709 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1710 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1711 FL("Failed to Start HT20/40 timer"));
1712 }
1713 else
1714 {
1715 /* Stop HT20/40 Timer */
1716 if (VOS_TIMER_STATE_RUNNING == pSapCtx->sap_HT2040_timer.state)
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1719 FL("Stop HT20/40 transition timer"));
1720 vosStatus = vos_timer_stop(&pSapCtx->sap_HT2040_timer);
1721 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1722 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1723 FL("Failed to Stop HT20/40 timer"));
1724 }
1725 }
1726 }
1727 }
1728#endif
Leo Chang0b0e45a2013-12-15 15:18:55 -08001729 return;
1730}
Leo Chang0b0e45a2013-12-15 15:18:55 -08001731#endif /* FEATURE_WLAN_CH_AVOID */
1732
Jeff Johnson295189b2012-06-20 16:38:30 -07001733int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301734static __iw_softap_setparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001735 struct iw_request_info *info,
1736 union iwreq_data *wrqu, char *extra)
1737{
1738 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001739 tHalHandle hHal;
Mahesh A Saptasagarc449f102015-01-09 21:15:18 +05301740 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001741 int *value = (int *)extra;
1742 int sub_cmd = value[0];
1743 int set_value = value[1];
1744 eHalStatus status;
1745 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001746 v_CONTEXT_t pVosContext;
1747
Mahesh A Saptasagarc449f102015-01-09 21:15:18 +05301748 if (NULL == pHostapdAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001749 {
1750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagarc449f102015-01-09 21:15:18 +05301751 "%s: hostapd Adapter is null",
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001752 __func__);
1753 return -1;
1754 }
1755
Mahesh A Saptasagarc449f102015-01-09 21:15:18 +05301756 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
1757 ret = wlan_hdd_validate_context(pHddCtx);
1758 if (0 != ret)
1759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301761 "%s: HDD context is not valid",__func__);
Mahesh A Saptasagarc449f102015-01-09 21:15:18 +05301762 return -1;
1763 }
1764
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001765 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1766 if (!hHal)
1767 {
1768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1769 "%s: Hal ctx is null", __func__);
1770 return -1;
1771 }
1772
1773 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1774 if (!pVosContext)
1775 {
1776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1777 "%s: Vos ctx is null", __func__);
1778 return -1;
1779 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001780
1781 switch(sub_cmd)
1782 {
1783
1784 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001785 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001786 {
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301787 ret = -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001788 }
1789 break;
1790
1791 case QCSAP_PARAM_ACL_MODE:
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301792 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1794 {
1795 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1796 ret = -EINVAL;
1797 }
1798 else
1799 {
1800 WLANSAP_SetMode(pVosContext, set_value);
1801 }
1802 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301803
1804 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1805 if ((0 != set_value) && (1 != set_value))
1806 {
1807 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1808 ret = -EINVAL;
1809 }
1810 else
1811 {
1812 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1813 }
1814 break;
1815
Jeff Johnson295189b2012-06-20 16:38:30 -07001816 case QCSAP_PARAM_MAX_ASSOC:
1817 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1818 {
1819 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1820 ret = -EINVAL;
1821 }
1822 else
1823 {
1824 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1825 {
1826 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1827 "Setting it to max allowed and continuing"),
1828 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1829 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1830 }
1831 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1832 set_value, NULL, eANI_BOOLEAN_FALSE);
1833 if ( status != eHAL_STATUS_SUCCESS )
1834 {
1835 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1836 status);
1837 ret = -EIO;
1838 }
1839 }
1840 break;
1841
1842 case QCSAP_PARAM_HIDE_SSID:
1843 {
1844 eHalStatus status = eHAL_STATUS_SUCCESS;
1845 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1846 if(eHAL_STATUS_SUCCESS != status)
1847 {
1848 hddLog(VOS_TRACE_LEVEL_ERROR,
1849 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001850 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001851 return status;
1852 }
1853 break;
1854 }
1855
Leo Chang614d2072013-08-22 14:59:44 -07001856 case QCSAP_PARAM_SET_MC_RATE:
1857 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001858 tSirRateUpdateInd *rateUpdate;
1859
1860 rateUpdate = (tSirRateUpdateInd *)
1861 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1862 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001863 {
1864 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001865 "%s: SET_MC_RATE indication alloc fail", __func__);
1866 ret = -1;
1867 break;
1868 }
1869 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1870
1871 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1872 /* Ignore unicast */
1873 rateUpdate->ucastDataRate = -1;
1874 rateUpdate->mcastDataRate24GHz = set_value;
1875 rateUpdate->mcastDataRate5GHz = set_value;
1876 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1877 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1878 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1879 if (eHAL_STATUS_SUCCESS != status)
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 "%s: SET_MC_RATE failed", __func__);
1883 vos_mem_free(rateUpdate);
1884 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001885 }
1886 break;
1887 }
1888
Jeff Johnson295189b2012-06-20 16:38:30 -07001889 default:
1890 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1891 sub_cmd, set_value);
1892 ret = -EINVAL;
1893 break;
1894 }
1895
1896 return ret;
1897}
1898
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301899int
1900static iw_softap_setparam(struct net_device *dev,
1901 struct iw_request_info *info,
1902 union iwreq_data *wrqu, char *extra)
1903{
1904 int ret;
1905
1906 vos_ssr_protect(__func__);
1907 ret = __iw_softap_setparam(dev, info, wrqu, extra);
1908 vos_ssr_unprotect(__func__);
1909
1910 return ret;
1911}
Jeff Johnson295189b2012-06-20 16:38:30 -07001912
1913int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301914static __iw_softap_getparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 struct iw_request_info *info,
1916 union iwreq_data *wrqu, char *extra)
1917{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301918 hdd_adapter_t *pHostapdAdapter;
1919 tHalHandle hHal;
1920 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 int *value = (int *)extra;
1922 int sub_cmd = value[0];
1923 eHalStatus status;
1924 int ret = 0; /* success */
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301925 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001926
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301927 pHostapdAdapter = (netdev_priv(dev));
1928 if (NULL == pHostapdAdapter)
1929 {
1930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1931 "%s: Adapter is NULL",__func__);
1932 return -EINVAL;
1933 }
1934 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
1935 ret = wlan_hdd_validate_context(pHddCtx);
1936 if (0 != ret)
1937 {
1938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1939 "%s: HDD context is not valid",__func__);
1940 return ret;
1941 }
1942 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1943 if (NULL == hHal)
1944 {
1945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1946 "%s: Hal Context is NULL",__func__);
1947 return -EINVAL;
1948 }
1949 pVosContext = pHddCtx->pvosContext;
1950 if (NULL == pVosContext)
1951 {
1952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1953 "%s: pVosContext Context is NULL",__func__);
1954 return -EINVAL;
1955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 switch (sub_cmd)
1957 {
1958 case QCSAP_PARAM_MAX_ASSOC:
1959 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1960 if (eHAL_STATUS_SUCCESS != status)
1961 {
c_hpothuffdb5272013-10-02 16:42:35 +05301962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1963 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 ret = -EIO;
1965 }
Girish Gowli385be612014-09-18 11:17:20 +05301966
1967#ifdef WLAN_SOFTAP_VSTA_FEATURE
1968 if (pHddCtx->cfg_ini->fEnableVSTASupport)
1969 {
1970 if (*value > VSTA_NUM_ASSOC_STA)
1971 {
1972 *value = VSTA_NUM_ASSOC_STA;
1973 }
1974 if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) &&
1975 (*value > (VSTA_NUM_ASSOC_STA -
1976 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA))))
1977 {
1978 *value = (VSTA_NUM_ASSOC_STA -
1979 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA));
1980 }
1981 }
1982 else
1983#endif
1984 {
1985 if (*value > NUM_ASSOC_STA)
1986 {
1987 *value = NUM_ASSOC_STA;
1988 }
1989 if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) &&
1990 (*value > (NUM_ASSOC_STA -
1991 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA))))
1992 {
1993 *value = (NUM_ASSOC_STA -
1994 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA));
1995 }
1996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 break;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05301998
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07002000 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 {
c_hpothuffdb5272013-10-02 16:42:35 +05302002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2003 FL("WLANSAP_ClearACL failed"));
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302004 ret = -EIO;
2005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002006 *value = 0;
2007 break;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302008
Jeff Johnson43971f52012-07-17 12:26:56 -07002009 case QCSAP_PARAM_GET_WLAN_DBG:
2010 {
2011 vos_trace_display();
2012 *value = 0;
2013 break;
2014 }
2015
2016 case QCSAP_PARAM_AUTO_CHANNEL:
2017 {
2018 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
2019 break;
2020 }
2021
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 default:
2023 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
2024 ret = -EINVAL;
2025 break;
2026
2027 }
2028
2029 return ret;
2030}
2031
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302032int
2033static iw_softap_getparam(struct net_device *dev,
2034 struct iw_request_info *info,
2035 union iwreq_data *wrqu, char *extra)
2036{
2037 int ret;
2038
2039 vos_ssr_protect(__func__);
2040 ret = __iw_softap_getparam(dev, info, wrqu, extra);
2041 vos_ssr_unprotect(__func__);
2042
2043 return ret;
2044}
Jeff Johnson295189b2012-06-20 16:38:30 -07002045/* Usage:
2046 BLACK_LIST = 0
2047 WHITE_LIST = 1
2048 ADD MAC = 0
2049 REMOVE MAC = 1
2050
2051 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
2052 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
2053 while using this ioctl
2054
2055 Syntax:
2056 iwpriv softap.0 modify_acl
2057 <6 octet mac addr> <list type> <cmd type>
2058
2059 Examples:
2060 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
2061 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
2062 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
2063 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
2064*/
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302065int __iw_softap_modify_acl(struct net_device *dev,
2066 struct iw_request_info *info,
2067 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002068{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302069 hdd_adapter_t *pHostapdAdapter;
2070 v_CONTEXT_t pVosContext;
2071 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 v_BYTE_t *value = (v_BYTE_t*)extra;
2073 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
2074 int listType, cmd, i;
2075 int ret = 0; /* success */
2076
2077 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302078 pHostapdAdapter = (netdev_priv(dev));
2079 if (NULL == pHostapdAdapter)
2080 {
2081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2082 "%s: Adapter is NULL",__func__);
2083 return -EINVAL;
2084 }
2085 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2086 ret = wlan_hdd_validate_context(pHddCtx);
2087 if (0 != ret)
2088 {
2089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2090 "%s: HDD context is not valid",__func__);
2091 return ret;
2092 }
2093 pVosContext = pHddCtx->pvosContext;
2094 if (NULL == pVosContext)
2095 {
2096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2097 "%s: Vos Context is NULL",__func__);
2098 return -EINVAL;
2099 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
2101 {
2102 pPeerStaMac[i] = *(value+i);
2103 }
2104 listType = (int)(*(value+i));
2105 i++;
2106 cmd = (int)(*(value+i));
2107
Arif Hussain24bafea2013-11-15 15:10:03 -08002108 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
2109 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002110
2111 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
2112 != VOS_STATUS_SUCCESS)
2113 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002114 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 ret = -EIO;
2116 }
2117 EXIT();
2118 return ret;
2119}
2120
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302121int iw_softap_modify_acl(struct net_device *dev,
2122 struct iw_request_info *info,
2123 union iwreq_data *wrqu, char *extra)
2124{
2125 int ret;
2126
2127 vos_ssr_protect(__func__);
2128 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
2129 vos_ssr_unprotect(__func__);
2130
2131 return ret;
2132}
2133
Jeff Johnson295189b2012-06-20 16:38:30 -07002134int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302135static __iw_softap_getchannel(struct net_device *dev,
2136 struct iw_request_info *info,
2137 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002138{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302139 hdd_adapter_t *pHostapdAdapter;
2140 hdd_context_t *pHddCtx;
2141 int ret = 0;
2142 int *value;
2143 pHostapdAdapter = (netdev_priv(dev));
2144 if (NULL == pHostapdAdapter)
2145 {
2146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2147 "%s: Adapter is NULL",__func__);
2148 return -EINVAL;
2149 }
2150 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2151 ret = wlan_hdd_validate_context(pHddCtx);
2152 if (0 != ret)
2153 {
2154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2155 "%s: HDD context is not valid",__func__);
2156 return ret;
2157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002158
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302159 *value = *(int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07002160
Jeff Johnson43971f52012-07-17 12:26:56 -07002161 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07002162 return 0;
2163}
2164
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302165
Jeff Johnsone7245742012-09-05 17:12:55 -07002166int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302167static iw_softap_getchannel(struct net_device *dev,
2168 struct iw_request_info *info,
2169 union iwreq_data *wrqu, char *extra)
2170{
2171 int ret;
2172
2173 vos_ssr_protect(__func__);
2174 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
2175 vos_ssr_unprotect(__func__);
2176
2177 return ret;
2178}
2179
2180int
2181static __iw_softap_set_max_tx_power(struct net_device *dev,
2182 struct iw_request_info *info,
2183 union iwreq_data *wrqu, char *extra)
Jeff Johnsone7245742012-09-05 17:12:55 -07002184{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302185 hdd_adapter_t *pHostapdAdapter;
2186 tHalHandle hHal;
2187 hdd_context_t *pHddCtx;
schang86c22c42013-03-13 18:41:24 -07002188 int *value = (int *)extra;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302189 int set_value, ret = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002190 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2191 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2192
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302193 pHostapdAdapter = (netdev_priv(dev));
2194 if (NULL == pHostapdAdapter)
2195 {
2196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2197 "%s: Adapter is NULL",__func__);
2198 return -EINVAL;
2199 }
2200 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2201 ret = wlan_hdd_validate_context(pHddCtx);
2202 if (0 != ret)
2203 {
2204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2205 "%s: HDD context is not valid",__func__);
2206 return ret;
2207 }
2208 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2209 if (NULL == hHal)
2210 {
2211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2212 "%s: Hal Context is NULL",__func__);
2213 return -EINVAL;
2214 }
schang86c22c42013-03-13 18:41:24 -07002215 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07002216 return -ENOMEM;
2217
Leo Changd37675a2013-08-01 13:19:45 -07002218 /* Assign correct slef MAC address */
2219 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
2220 VOS_MAC_ADDR_SIZE);
2221 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
2222 VOS_MAC_ADDR_SIZE);
2223
schang86c22c42013-03-13 18:41:24 -07002224 set_value = value[0];
2225 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
2226 {
2227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002228 __func__);
schang86c22c42013-03-13 18:41:24 -07002229 return -EIO;
2230 }
2231
2232 return 0;
2233}
2234
2235int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302236static iw_softap_set_max_tx_power(struct net_device *dev,
2237 struct iw_request_info *info,
2238 union iwreq_data *wrqu, char *extra)
2239{
2240 int ret;
2241
2242 vos_ssr_protect(__func__);
2243 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
2244 vos_ssr_unprotect(__func__);
2245
2246 return ret;
2247}
2248
2249
2250int
2251static __iw_display_data_path_snapshot(struct net_device *dev,
2252 struct iw_request_info *info,
2253 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05302254{
2255
2256 /* Function intitiating dumping states of
2257 * HDD(WMM Tx Queues)
2258 * TL State (with Per Client infor)
2259 * DXE Snapshot (Called at the end of TL Snapshot)
2260 */
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302261 hdd_adapter_t *pHostapdAdapter;
2262 hdd_context_t *pHddCtx;
2263 int ret = 0;
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05302264 hddLog(LOGE, "%s: called for SAP",__func__);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302265 pHostapdAdapter = (netdev_priv(dev));
2266 if (NULL == pHostapdAdapter)
2267 {
2268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2269 "%s: Adapter is NULL",__func__);
2270 return -EINVAL;
2271 }
2272 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2273 ret = wlan_hdd_validate_context(pHddCtx);
2274 if (0 != ret)
2275 {
2276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2277 "%s: HDD context is not valid",__func__);
2278 return ret;
2279 }
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05302280 hdd_wmm_tx_snapshot(pHostapdAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +05302281 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05302282 return 0;
2283}
2284
2285int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302286static iw_display_data_path_snapshot(struct net_device *dev,
2287 struct iw_request_info *info,
2288 union iwreq_data *wrqu, char *extra)
2289{
2290 int ret;
2291
2292 vos_ssr_protect(__func__);
2293 ret = __iw_display_data_path_snapshot(dev, info, wrqu, extra);
2294 vos_ssr_unprotect(__func__);
2295
2296 return ret;
2297}
2298
2299int
2300static __iw_softap_set_tx_power(struct net_device *dev,
2301 struct iw_request_info *info,
2302 union iwreq_data *wrqu, char *extra)
schang86c22c42013-03-13 18:41:24 -07002303{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302304 hdd_adapter_t *pHostapdAdapter;
2305 hdd_context_t *pHddCtx;
2306 v_CONTEXT_t pVosContext;
2307 tHalHandle hHal;
schang86c22c42013-03-13 18:41:24 -07002308 int *value = (int *)extra;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302309 int set_value, ret = 0;
schang86c22c42013-03-13 18:41:24 -07002310 ptSapContext pSapCtx = NULL;
2311
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302312 pHostapdAdapter = (netdev_priv(dev));
2313 if (NULL == pHostapdAdapter)
2314 {
2315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2316 "%s: Adapter is NULL",__func__);
2317 return -EINVAL;
2318 }
2319 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2320 ret = wlan_hdd_validate_context(pHddCtx);
2321 if (0 != ret)
2322 {
2323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2324 "%s: HDD context is not valid",__func__);
2325 return ret;
2326 }
2327 pVosContext = pHddCtx->pvosContext;
2328 if (NULL == pVosContext)
2329 {
2330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2331 "%s: Vos Context is NULL",__func__);
2332 return -EINVAL;
2333 }
2334 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2335 if (NULL == hHal)
2336 {
2337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2338 "%s: Hal Context is NULL",__func__);
2339 return -EINVAL;
2340 }
schang86c22c42013-03-13 18:41:24 -07002341 if (NULL == value)
2342 return -ENOMEM;
2343
2344 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2345 if (NULL == pSapCtx)
2346 {
2347 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2348 "%s: Invalid SAP pointer from pvosGCtx", __func__);
2349 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07002350 }
2351
2352 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07002353 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07002354 {
schang86c22c42013-03-13 18:41:24 -07002355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07002356 __func__);
2357 return -EIO;
2358 }
2359
2360 return 0;
2361}
2362
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302363int
2364static iw_softap_set_tx_power(struct net_device *dev,
2365 struct iw_request_info *info,
2366 union iwreq_data *wrqu, char *extra)
2367{
2368 int ret;
2369
2370 vos_ssr_protect(__func__);
2371 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
2372 vos_ssr_unprotect(__func__);
2373
2374 return ret;
2375}
2376
Kiet Lambcf38522013-10-26 18:28:27 +05302377/**---------------------------------------------------------------------------
2378
2379 \brief iw_softap_set_trafficmonitor() -
2380 This function dynamically enable/disable traffic monitor functonality
2381 the command iwpriv wlanX setTrafficMon <value>.
2382
2383 \param - dev - Pointer to the net device.
2384 - addr - Pointer to the sockaddr.
2385 \return - 0 for success, non zero for failure
2386
2387 --------------------------------------------------------------------------*/
2388
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302389static int __iw_softap_set_trafficmonitor(struct net_device *dev,
2390 struct iw_request_info *info,
2391 union iwreq_data *wrqu, char *extra)
Kiet Lambcf38522013-10-26 18:28:27 +05302392{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302393 hdd_adapter_t *pAdapter;
Sushant Kaushik128a0bb2014-08-07 20:24:54 +05302394 int *isSetTrafficMon = (int *)extra;
Kiet Lambcf38522013-10-26 18:28:27 +05302395 hdd_context_t *pHddCtx;
2396 int status;
2397
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302398 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kiet Lambcf38522013-10-26 18:28:27 +05302399 if (NULL == pAdapter)
2400 {
2401 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2402 "%s: HDD adapter is Null", __func__);
2403 return -ENODEV;
2404 }
2405
2406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2407
2408 status = wlan_hdd_validate_context(pHddCtx);
2409
2410 if (0 != status)
2411 {
2412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: HDD context is not valid", __func__);
2414 return status;
2415 }
2416
2417 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
2418
2419 if (NULL == isSetTrafficMon)
2420 {
2421 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2422 "%s: Invalid SAP pointer from extra", __func__);
2423 return -ENOMEM;
2424 }
2425
2426 if (TRUE == *isSetTrafficMon)
2427 {
2428 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
2429 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
2430 {
2431 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2432 "%s: failed to Start Traffic Monitor timer ", __func__ );
2433 return -EIO;
2434 }
2435 }
2436 else if (FALSE == *isSetTrafficMon)
2437 {
2438 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
2439 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
2440 {
2441 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2442 "%s: failed to Stop Traffic Monitor timer ", __func__ );
2443 return -EIO;
2444 }
2445
2446 }
2447 return 0;
2448}
2449
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302450static int iw_softap_set_trafficmonitor(struct net_device *dev,
2451 struct iw_request_info *info,
2452 union iwreq_data *wrqu, char *extra)
2453{
2454 int ret;
2455
2456 vos_ssr_protect(__func__);
2457 ret = __iw_softap_set_trafficmonitor(dev, info, wrqu, extra);
2458 vos_ssr_unprotect(__func__);
2459
2460 return ret;
2461}
2462
Jeff Johnson295189b2012-06-20 16:38:30 -07002463#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
2464
2465int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302466static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
2467 struct iw_request_info *info,
2468 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002469{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302470 hdd_adapter_t *pHostapdAdapter;
2471 hdd_context_t *pHddCtx;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302472 hdd_station_info_t *pStaInfo = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002473 char *buf;
2474 int cnt = 0;
2475 int left;
2476 int ret = 0;
2477 /* maclist_index must be u32 to match userspace */
2478 u32 maclist_index;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302479 v_CONTEXT_t pVosContext = NULL;
2480 ptSapContext pSapCtx = NULL;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302481
2482 pHostapdAdapter = (netdev_priv(dev));
2483 if (NULL == pHostapdAdapter)
2484 {
2485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2486 "%s: Adapter is NULL",__func__);
2487 return -EINVAL;
2488 }
2489 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2490 ret = wlan_hdd_validate_context(pHddCtx);
2491 if (0 != ret)
2492 {
2493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2494 "%s: HDD context is not valid",__func__);
2495 return ret;
2496 }
2497
Jeff Johnson224f3702014-03-26 11:09:47 -07002498 /*
2499 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
2500 * number, and even numbered iocts are supposed to have "set"
2501 * semantics. Hence the wireless extensions support in the kernel
2502 * won't correctly copy the result to userspace, so the ioctl
2503 * handler itself must copy the data. Output format is 32-bit
2504 * record length, followed by 0 or more 6-byte STA MAC addresses.
2505 *
2506 * Further note that due to the incorrect semantics, the "iwpriv"
2507 * userspace application is unable to correctly invoke this API,
2508 * hence it is not registered in the hostapd_private_args. This
2509 * API can only be invoked by directly invoking the ioctl() system
2510 * call.
2511 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002512
Jeff Johnson224f3702014-03-26 11:09:47 -07002513 /* make sure userspace allocated a reasonable buffer size */
2514 if (wrqu->data.length < sizeof(maclist_index)) {
2515 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
2516 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07002517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002518
Jeff Johnson224f3702014-03-26 11:09:47 -07002519 /* allocate local buffer to build the response */
2520 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
2521 if (!buf) {
2522 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
2523 return -ENOMEM;
2524 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302525 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2526 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2527 if(pSapCtx == NULL){
2528 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2529 FL("psapCtx is NULL"));
2530 return -EFAULT;
2531 }
2532 pStaInfo = pSapCtx->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07002533 /* start indexing beyond where the record count will be written */
2534 maclist_index = sizeof(maclist_index);
2535 left = wrqu->data.length - maclist_index;
2536
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302537 spin_lock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002538 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
2539 if ((pStaInfo[cnt].isUsed) &&
2540 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
2541 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
2542 VOS_MAC_ADDR_SIZE);
2543 maclist_index += VOS_MAC_ADDR_SIZE;
2544 left -= VOS_MAC_ADDR_SIZE;
2545 }
2546 cnt++;
2547 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302548 spin_unlock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002549
2550 *((u32 *)buf) = maclist_index;
2551 wrqu->data.length = maclist_index;
2552 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
2553 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
2554 ret = -EFAULT;
2555 }
2556 kfree(buf);
2557 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002558}
2559
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302560int
2561static iw_softap_getassoc_stamacaddr(struct net_device *dev,
2562 struct iw_request_info *info,
2563 union iwreq_data *wrqu, char *extra)
2564{
2565 int ret;
2566
2567 vos_ssr_protect(__func__);
2568 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
2569 vos_ssr_unprotect(__func__);
2570
2571 return ret;
2572}
2573
Jeff Johnson295189b2012-06-20 16:38:30 -07002574/* Usage:
2575 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
2576 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
2577 while using this ioctl
2578
2579 Syntax:
2580 iwpriv softap.0 disassoc_sta <6 octet mac address>
2581
2582 e.g.
2583 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
2584 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
2585*/
2586
2587int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302588static __iw_softap_disassoc_sta(struct net_device *dev,
2589 struct iw_request_info *info,
2590 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002591{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302592 hdd_adapter_t *pHostapdAdapter;
2593 hdd_context_t *pHddCtx;
2594 v_U8_t *peerMacAddr;
2595 int ret = 0;
2596
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302598 pHostapdAdapter = (netdev_priv(dev));
2599 if (NULL == pHostapdAdapter)
2600 {
2601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2602 "%s: Adapter is NULL",__func__);
2603 return -EINVAL;
2604 }
2605 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2606 ret = wlan_hdd_validate_context(pHddCtx);
2607 if (0 != ret)
2608 {
2609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2610 "%s: HDD context is not valid",__func__);
2611 return ret;
2612 }
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302613 /* iwpriv tool or framework calls this ioctl with
2614 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07002615 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302616 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002617
Arif Hussain24bafea2013-11-15 15:10:03 -08002618 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
2619 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002620 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
2621 EXIT();
2622 return 0;
2623}
2624
2625int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302626static iw_softap_disassoc_sta(struct net_device *dev,
2627 struct iw_request_info *info,
2628 union iwreq_data *wrqu, char *extra)
2629{
2630 int ret;
2631
2632 vos_ssr_protect(__func__);
2633 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
2634 vos_ssr_unprotect(__func__);
2635
2636 return ret;
2637}
2638
2639int
2640static __iw_softap_ap_stats(struct net_device *dev,
2641 struct iw_request_info *info,
2642 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002643{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302644 hdd_adapter_t *pHostapdAdapter;
2645 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002646 WLANTL_TRANSFER_STA_TYPE statBuffer;
2647 char *pstatbuf;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302648 int len, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002649
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302650 pHostapdAdapter = (netdev_priv(dev));
2651 if (NULL == pHostapdAdapter)
2652 {
2653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2654 "%s: Adapter is NULL",__func__);
2655 return -EINVAL;
2656 }
2657 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2658 ret = wlan_hdd_validate_context(pHddCtx);
2659 if (0 != ret)
2660 {
2661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2662 "%s: HDD context is not valid",__func__);
2663 return ret;
2664 }
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002665 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07002666 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
2667 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002668
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302669 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07002670 if(NULL == pstatbuf) {
2671 hddLog(LOG1, "unable to allocate memory");
2672 return -ENOMEM;
2673 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302674
2675 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07002676 "RUF=%d RMF=%d RBF=%d "
2677 "RUB=%d RMB=%d RBB=%d "
2678 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302679 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002680 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2681 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2682 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2683 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2684 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2685 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002686
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302687 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002688 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2689 kfree(pstatbuf);
2690 return -EFAULT;
2691 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302692
2693 strlcpy(extra, pstatbuf, len);
2694 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002695 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 return 0;
2697}
2698
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302699int
2700static iw_softap_ap_stats(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002701 struct iw_request_info *info,
2702 union iwreq_data *wrqu, char *extra)
2703{
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302704 int ret;
2705
2706 vos_ssr_protect(__func__);
2707 ret = __iw_softap_ap_stats(dev, info, wrqu, extra);
2708 vos_ssr_unprotect(__func__);
2709
2710 return ret;
2711}
2712
2713static int __iw_softap_set_channel_range(struct net_device *dev,
2714 struct iw_request_info *info,
2715 union iwreq_data *wrqu, char *extra)
2716{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302717 hdd_adapter_t *pHostapdAdapter;
2718 tHalHandle hHal;
2719 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002720 int *value = (int *)extra;
2721 int startChannel = value[0];
2722 int endChannel = value[1];
2723 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002724 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 int ret = 0; /* success */
2726
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302727 pHostapdAdapter = (netdev_priv(dev));
2728 if (NULL == pHostapdAdapter)
2729 {
2730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2731 "%s: Adapter is NULL",__func__);
2732 return -EINVAL;
2733 }
2734 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2735 ret = wlan_hdd_validate_context(pHddCtx);
2736 if (0 != ret)
2737 {
2738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2739 "%s: HDD context is not valid",__func__);
2740 return ret;
2741 }
2742 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2743 if (NULL == hHal)
2744 {
2745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2746 "%s: Hal Context is NULL",__func__);
2747 return -EINVAL;
2748 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2750 if(status != VOS_STATUS_SUCCESS)
2751 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002752 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 startChannel,endChannel, band);
2754 ret = -EINVAL;
2755 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002756
2757 pHddCtx->is_dynamic_channel_range_set = 1;
2758
Jeff Johnson295189b2012-06-20 16:38:30 -07002759 return ret;
2760}
2761
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302762static int iw_softap_set_channel_range(struct net_device *dev,
2763 struct iw_request_info *info,
2764 union iwreq_data *wrqu, char *extra)
2765{
2766 int ret;
2767
2768 vos_ssr_protect(__func__);
2769 ret = __iw_softap_set_channel_range(dev, info, wrqu, extra);
2770 vos_ssr_unprotect(__func__);
2771
2772 return ret;
2773}
2774
2775
2776int __iw_softap_get_channel_list(struct net_device *dev,
2777 struct iw_request_info *info,
2778 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002779{
2780 v_U32_t num_channels = 0;
2781 v_U8_t i = 0;
2782 v_U8_t bandStartChannel = RF_CHAN_1;
2783 v_U8_t bandEndChannel = RF_CHAN_165;
2784 v_U32_t temp_num_channels = 0;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302785 hdd_adapter_t *pHostapdAdapter;
2786 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07002787 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002788 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002789 eCsrBand curBand = eCSR_BAND_ALL;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302790 hdd_context_t *pHddCtx;
2791 int ret = 0;
2792 pHostapdAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2793 if (NULL == pHostapdAdapter)
2794 {
2795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2796 "%s: Adapter is NULL",__func__);
2797 return -EINVAL;
2798 }
2799 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2800 ret = wlan_hdd_validate_context(pHddCtx);
2801 if (0 != ret)
2802 {
2803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2804 "%s: HDD context is not valid",__func__);
2805 return ret;
2806 }
2807 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2808 if (NULL == hHal)
2809 {
2810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2811 "%s: Hal Context is NULL",__func__);
2812 return -EINVAL;
2813 }
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002814 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2815 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002816 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002817 return -EIO;
2818 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002819 wrqu->data.length = sizeof(tChannelListInfo);
2820 ENTER();
2821
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002822 if (eCSR_BAND_24 == curBand)
2823 {
2824 bandStartChannel = RF_CHAN_1;
2825 bandEndChannel = RF_CHAN_14;
2826 }
2827 else if (eCSR_BAND_5G == curBand)
2828 {
2829 bandStartChannel = RF_CHAN_36;
2830 bandEndChannel = RF_CHAN_165;
2831 }
2832
Arif Hussain6d2a3322013-11-17 19:50:10 -08002833 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302834 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002835 bandStartChannel, bandEndChannel );
2836
Jeff Johnson295189b2012-06-20 16:38:30 -07002837 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2838 {
2839 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2840 {
2841 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2842 num_channels++;
2843 }
2844 }
2845
2846 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2847
2848 temp_num_channels = num_channels;
2849
2850 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2851 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302852 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002853 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002854 }
2855
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302856 if(REGDOMAIN_FCC == domainIdCurrentSoftap &&
2857 pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC )
Jeff Johnson295189b2012-06-20 16:38:30 -07002858 {
2859 for(i = 0; i < temp_num_channels; i++)
2860 {
2861
2862 if((channel_list->channels[i] > 35) &&
2863 (channel_list->channels[i] < 49))
2864 {
2865 vos_mem_move(&channel_list->channels[i],
2866 &channel_list->channels[i+1],
2867 temp_num_channels - (i-1));
2868 num_channels--;
2869 temp_num_channels--;
2870 i--;
2871 }
2872 }
2873 }
2874
Arif Hussain6d2a3322013-11-17 19:50:10 -08002875 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002876
2877 if (num_channels > IW_MAX_FREQUENCIES)
2878 {
2879 num_channels = IW_MAX_FREQUENCIES;
2880 }
2881
2882 channel_list->num_channels = num_channels;
2883 EXIT();
2884
2885 return 0;
2886}
2887
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302888int iw_softap_get_channel_list(struct net_device *dev,
2889 struct iw_request_info *info,
2890 union iwreq_data *wrqu, char *extra)
2891{
2892 int ret;
2893
2894 vos_ssr_protect(__func__);
2895 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
2896 vos_ssr_unprotect(__func__);
2897
2898 return ret;
2899}
2900
2901static
2902int __iw_get_genie(struct net_device *dev,
2903 struct iw_request_info *info,
2904 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002905{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302906 hdd_adapter_t *pHostapdAdapter;
2907 hdd_context_t *pHddCtx;
2908 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 eHalStatus status;
2910 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2911 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302912 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002913 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302914
2915 pHostapdAdapter = (netdev_priv(dev));
2916 if (NULL == pHostapdAdapter)
2917 {
2918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2919 "%s: Adapter is NULL",__func__);
2920 return -EINVAL;
2921 }
2922 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2923 ret = wlan_hdd_validate_context(pHddCtx);
2924 if (0 != ret)
2925 {
2926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2927 "%s: HDD context is not valid",__func__);
2928 return ret;
2929 }
2930 pVosContext = pHddCtx->pvosContext;
2931 if (NULL == pVosContext)
2932 {
2933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2934 "%s: vos context is not valid ",__func__);
2935 return -EINVAL;
2936 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002937 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2939 status = WLANSap_getstationIE_information(pVosContext,
2940 &length,
2941 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002942 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2943 if (wrqu->data.length < length ||
2944 copy_to_user(wrqu->data.pointer,
2945 (v_VOID_t*)genIeBytes, length))
2946 {
2947 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2948 return -EFAULT;
2949 }
2950 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002951
Arif Hussain6d2a3322013-11-17 19:50:10 -08002952 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002953
2954
2955 EXIT();
2956 return 0;
2957}
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302958
2959static
2960int iw_get_genie(struct net_device *dev,
2961 struct iw_request_info *info,
2962 union iwreq_data *wrqu, char *extra)
2963{
2964 int ret;
2965
2966 vos_ssr_protect(__func__);
2967 ret = __iw_get_genie(dev, info, wrqu, extra);
2968 vos_ssr_unprotect(__func__);
2969
2970 return ret;
2971}
2972
2973static
2974int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2975 struct iw_request_info *info,
2976 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002977{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302978 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002979 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302980 hdd_ap_ctx_t *pHddApCtx;
2981 hdd_context_t *pHddCtx;
2982 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002984
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05302985 pHostapdAdapter = (netdev_priv(dev));
2986 if (NULL == pHostapdAdapter)
2987 {
2988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2989 "%s: Adapter is NULL",__func__);
2990 return -EINVAL;
2991 }
2992 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2993 ret = wlan_hdd_validate_context(pHddCtx);
2994 if (0 != ret)
2995 {
2996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2997 "%s: HDD context is not valid",__func__);
2998 return ret;
2999 }
3000 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3001 if (NULL == pHddApCtx)
3002 {
3003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3004 "%s: AP context is NULL",__func__);
3005 return -EINVAL;
3006 }
3007
Arif Hussain6d2a3322013-11-17 19:50:10 -08003008 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07003009 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
3010
3011 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
3012 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
3013 pHddApCtx->WPSPBCProbeReq.probeReqIE,
3014 WPSPBCProbeReqIEs.probeReqIELen);
3015 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
3016 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
3017 sizeof(v_MACADDR_t));
3018 if (copy_to_user(wrqu->data.pointer,
3019 (void *)&WPSPBCProbeReqIEs,
3020 sizeof(WPSPBCProbeReqIEs)))
3021 {
3022 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3023 return -EFAULT;
3024 }
3025 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003026 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07003027 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07003028 up(&pHddApCtx->semWpsPBCOverlapInd);
3029 EXIT();
3030 return 0;
3031}
3032
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303033static
3034int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
3035 struct iw_request_info *info,
3036 union iwreq_data *wrqu, char *extra)
3037{
3038 int ret;
3039
3040 vos_ssr_protect(__func__);
3041 ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra);
3042 vos_ssr_unprotect(__func__);
3043
3044 return ret;
3045}
3046
Jeff Johnson295189b2012-06-20 16:38:30 -07003047/**---------------------------------------------------------------------------
3048
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303049 \brief __iw_set_auth_hostap() -
Jeff Johnson295189b2012-06-20 16:38:30 -07003050 This function sets the auth type received from the wpa_supplicant.
3051
3052 \param - dev - Pointer to the net device.
3053 - info - Pointer to the iw_request_info.
3054 - wrqu - Pointer to the iwreq_data.
3055 - extra - Pointer to the data.
3056 \return - 0 for success, non zero for failure
3057
3058 --------------------------------------------------------------------------*/
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303059int __iw_set_auth_hostap(struct net_device *dev,
3060 struct iw_request_info *info,
3061 union iwreq_data *wrqu,char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003062{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303063 hdd_adapter_t *pAdapter;
3064 hdd_context_t *pHddCtx;
3065 hdd_wext_state_t *pWextState;
3066 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003067 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303068
3069 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3070 if (NULL == pAdapter)
3071 {
3072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3073 "%s: Adapter is NULL",__func__);
3074 return -EINVAL;
3075 }
3076
3077 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3078 ret = wlan_hdd_validate_context(pHddCtx);
3079 if (0 != ret)
3080 {
3081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3082 "%s: HDD context is not valid",__func__);
3083 return ret;
3084 }
3085 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3086 if (NULL == pWextState)
3087 {
3088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3089 "%s: pWextState is NULL",__func__);
3090 return -EINVAL;
3091 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003092 switch(wrqu->param.flags & IW_AUTH_INDEX)
3093 {
3094 case IW_AUTH_TKIP_COUNTERMEASURES:
3095 {
3096 if(wrqu->param.value) {
3097 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3098 "Counter Measure started %d", wrqu->param.value);
3099 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303100 }
3101 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3103 "Counter Measure stopped=%d", wrqu->param.value);
3104 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
3105 }
3106
3107 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
3108 wrqu->param.value);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303109 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003110 break;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303111
Jeff Johnson295189b2012-06-20 16:38:30 -07003112 default:
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303113
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003114 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003115 wrqu->param.flags & IW_AUTH_INDEX);
3116 break;
3117 }
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303118
Jeff Johnson295189b2012-06-20 16:38:30 -07003119 EXIT();
3120 return 0;
3121}
3122
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303123int iw_set_auth_hostap(struct net_device *dev,
3124 struct iw_request_info *info,
3125 union iwreq_data *wrqu,char *extra)
3126{
3127 int ret;
3128
3129 vos_ssr_protect(__func__);
3130 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
3131 vos_ssr_unprotect(__func__);
3132
3133 return ret;
3134}
3135
3136static int __iw_set_ap_encodeext(struct net_device *dev,
3137 struct iw_request_info *info,
3138 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003139{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303140 hdd_adapter_t *pHostapdAdapter;
3141 v_CONTEXT_t pVosContext;
3142 hdd_context_t *pHddCtx;
3143 hdd_ap_ctx_t *pHddApCtx;
Jeff Johnson43971f52012-07-17 12:26:56 -07003144 int retval = 0;
3145 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003146 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
3147 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3148 int key_index;
3149 struct iw_point *encoding = &wrqu->encoding;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303150 tCsrRoamSetKey setKey;
Jeff Johnson295189b2012-06-20 16:38:30 -07003151// tCsrRoamRemoveKey RemoveKey;
3152 int i;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303153 ENTER();
3154 pHostapdAdapter = (netdev_priv(dev));
3155 if (NULL == pHostapdAdapter)
3156 {
3157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3158 "%s: Adapter is NULL",__func__);
3159 return -EINVAL;
3160 }
Jeff Johnson43971f52012-07-17 12:26:56 -07003161
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303162 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3163 retval = wlan_hdd_validate_context(pHddCtx);
3164 if (0 != retval)
3165 {
3166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3167 "%s: HDD context is not valid",__func__);
3168 return retval;
3169 }
3170 pVosContext = pHddCtx->pvosContext;
3171 if (NULL == pVosContext)
3172 {
3173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3174 "%s: pVosContext is NULL",__func__);
3175 return -EINVAL;
3176 }
3177 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3178 if (NULL == pHddApCtx)
3179 {
3180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3181 "%s: AP Context is NULL",__func__);
3182 return -EINVAL;
3183 }
3184
Jeff Johnson295189b2012-06-20 16:38:30 -07003185 key_index = encoding->flags & IW_ENCODE_INDEX;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303186
Jeff Johnson295189b2012-06-20 16:38:30 -07003187 if(key_index > 0) {
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303188
Jeff Johnson295189b2012-06-20 16:38:30 -07003189 /*Convert from 1-based to 0-based keying*/
3190 key_index--;
3191 }
3192 if(!ext->key_len) {
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303193#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -07003194 /*Set the encrytion type to NONE*/
3195#if 0
3196 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
3197#endif
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303198
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 RemoveKey.keyId = key_index;
3200 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3201 /*Key direction for group is RX only*/
3202 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3203 }
3204 else {
3205 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
3206 }
3207 switch(ext->alg)
3208 {
3209 case IW_ENCODE_ALG_NONE:
3210 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3211 break;
3212 case IW_ENCODE_ALG_WEP:
3213 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
3214 break;
3215 case IW_ENCODE_ALG_TKIP:
3216 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07003217 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07003218 case IW_ENCODE_ALG_CCMP:
3219 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
3220 break;
3221 default:
3222 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3223 break;
3224 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08003225 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 -07003226 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003228 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 );
Jeff Johnson43971f52012-07-17 12:26:56 -07003230 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
3231 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07003232 {
3233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07003234 __LINE__, vstatus );
3235 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003236 }
Jeff Johnson43971f52012-07-17 12:26:56 -07003237#endif
3238 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07003239
Jeff Johnson43971f52012-07-17 12:26:56 -07003240 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003241
3242 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3243
3244 setKey.keyId = key_index;
3245 setKey.keyLength = ext->key_len;
3246
3247 if(ext->key_len <= CSR_MAX_KEY_LEN) {
3248 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
3249 }
3250
3251 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3252 /*Key direction for group is RX only*/
3253 setKey.keyDirection = eSIR_RX_ONLY;
3254 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3255 }
3256 else {
3257
3258 setKey.keyDirection = eSIR_TX_RX;
3259 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
3260 }
3261 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3262 {
3263 setKey.keyDirection = eSIR_TX_DEFAULT;
3264 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
3265 }
3266
3267 /*For supplicant pae role is zero*/
3268 setKey.paeRole = 0;
3269
3270 switch(ext->alg)
3271 {
3272 case IW_ENCODE_ALG_NONE:
3273 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3274 break;
3275
3276 case IW_ENCODE_ALG_WEP:
3277 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
3278 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003279 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07003280 break;
3281
3282 case IW_ENCODE_ALG_TKIP:
3283 {
3284 v_U8_t *pKey = &setKey.Key[0];
3285
3286 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3287
3288 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3289
3290 /*Supplicant sends the 32bytes key in this order
3291
3292 |--------------|----------|----------|
3293 | Tk1 |TX-MIC | RX Mic |
3294 |--------------|----------|----------|
3295 <---16bytes---><--8bytes--><--8bytes-->
3296
3297 */
3298 /*Sme expects the 32 bytes key to be in the below order
3299
3300 |--------------|----------|----------|
3301 | Tk1 |RX-MIC | TX Mic |
3302 |--------------|----------|----------|
3303 <---16bytes---><--8bytes--><--8bytes-->
3304 */
3305 /* Copy the Temporal Key 1 (TK1) */
3306 vos_mem_copy(pKey,ext->key,16);
3307
3308 /*Copy the rx mic first*/
3309 vos_mem_copy(&pKey[16],&ext->key[24],8);
3310
3311 /*Copy the tx mic */
3312 vos_mem_copy(&pKey[24],&ext->key[16],8);
3313
3314 }
3315 break;
3316
3317 case IW_ENCODE_ALG_CCMP:
3318 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3319 break;
3320
3321 default:
3322 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3323 break;
3324 }
3325
3326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05303327 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07003328 setKey.keyId);
3329 for(i=0; i< ext->key_len; i++)
3330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3331 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07003332
3333 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
3334 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07003335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07003337 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
3338 retval = -EINVAL;
3339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003340
Jeff Johnson43971f52012-07-17 12:26:56 -07003341 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07003342}
Jeff Johnson43971f52012-07-17 12:26:56 -07003343
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303344static int iw_set_ap_encodeext(struct net_device *dev,
3345 struct iw_request_info *info,
3346 union iwreq_data *wrqu, char *extra)
3347{
3348 int ret;
3349
3350 vos_ssr_protect(__func__);
3351 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
3352 vos_ssr_unprotect(__func__);
3353
3354 return ret;
3355}
Jeff Johnson43971f52012-07-17 12:26:56 -07003356
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05303357static int __iw_set_ap_mlme(struct net_device *dev,
3358 struct iw_request_info *info,
3359 union iwreq_data *wrqu,
3360 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003361{
3362#if 0
3363 hdd_adapter_t *pAdapter = (netdev_priv(dev));
3364 struct iw_mlme *mlme = (struct iw_mlme *)extra;
3365
3366 ENTER();
3367
3368 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
3369 switch (mlme->cmd) {
3370 case IW_MLME_DISASSOC:
3371 case IW_MLME_DEAUTH:
3372 hddLog(LOG1, "Station disassociate");
3373 if( pAdapter->conn_info.connState == eConnectionState_Associated )
3374 {
3375 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
3376
3377 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
3378 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
3379
3380 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
3381
3382 //clear all the reason codes
3383 if (status != 0)
3384 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003385 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07003386 }
3387
3388 netif_stop_queue(dev);
3389 netif_carrier_off(dev);
3390 }
3391 else
3392 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003393 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 -07003394 }
3395 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08003396 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07003397 return -EINVAL;
3398 }//end of switch
3399 EXIT();
3400#endif
3401 return 0;
3402// return status;
3403}
3404
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05303405static int iw_set_ap_mlme(struct net_device *dev,
3406 struct iw_request_info *info,
3407 union iwreq_data *wrqu,
3408 char *extra)
3409{
3410 int ret;
3411
3412 vos_ssr_protect(__func__);
3413 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
3414 vos_ssr_unprotect(__func__);
3415
3416 return ret;
3417}
3418
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303419static int __iw_get_ap_rts_threshold(struct net_device *dev,
3420 struct iw_request_info *info,
3421 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003422{
3423 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3424 v_U32_t status = 0;
3425
3426 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
3427
3428 return status;
3429}
3430
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303431static int iw_get_ap_rts_threshold(struct net_device *dev,
3432 struct iw_request_info *info,
3433 union iwreq_data *wrqu, char *extra)
3434{
3435 int ret;
3436
3437 vos_ssr_protect(__func__);
3438 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
3439 vos_ssr_unprotect(__func__);
3440
3441 return ret;
3442}
3443
3444static int __iw_get_ap_frag_threshold(struct net_device *dev,
3445 struct iw_request_info *info,
3446 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003447{
3448 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3449 v_U32_t status = 0;
3450
3451 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
3452
3453 return status;
3454}
3455
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303456static int iw_get_ap_frag_threshold(struct net_device *dev,
3457 struct iw_request_info *info,
3458 union iwreq_data *wrqu, char *extra)
3459{
3460 int ret;
3461
3462 vos_ssr_protect(__func__);
3463 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
3464 vos_ssr_unprotect(__func__);
3465
3466 return ret;
3467}
3468
3469static int __iw_get_ap_freq(struct net_device *dev,
3470 struct iw_request_info *info,
3471 struct iw_freq *fwrq, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003472{
Jeff Johnsone7245742012-09-05 17:12:55 -07003473 v_U32_t status = FALSE, channel = 0, freq = 0;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303474 hdd_adapter_t *pHostapdAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07003475 tHalHandle hHal;
3476 hdd_hostapd_state_t *pHostapdState;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303477 hdd_ap_ctx_t *pHddApCtx;
3478 hdd_context_t *pHddCtx;
3479 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003480
3481 ENTER();
3482
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303483 pHostapdAdapter = (netdev_priv(dev));
3484 if (NULL == pHostapdAdapter)
3485 {
3486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3487 "%s: Adapter is NULL",__func__);
3488 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003489 }
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303490 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3491 ret = wlan_hdd_validate_context(pHddCtx);
3492 if (0 != ret)
3493 {
3494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3495 "%s: HDD context is not valid",__func__);
3496 return ret;
3497 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003498 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303499 if (NULL == pHostapdState)
3500 {
3501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3502 "%s: pHostapdState is NULL",__func__);
3503 return -EINVAL;
3504 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003505 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303506 if (NULL == hHal)
3507 {
3508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3509 "%s: Hal Context is NULL",__func__);
3510 return -EINVAL;
3511 }
3512 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3513 if (NULL == pHddApCtx)
3514 {
3515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3516 "%s: AP context is NULL",__func__);
3517 return -EINVAL;
3518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003519 if(pHostapdState->bssState == BSS_STOP )
3520 {
3521 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
3522 != eHAL_STATUS_SUCCESS)
3523 {
c_hpothuffdb5272013-10-02 16:42:35 +05303524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3525 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 return -EIO;
3527 }
3528 else
3529 {
3530 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07003531 if( TRUE == status)
3532 {
3533 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
3534 * iwlist & iwconfig command shows frequency into proper
3535 * format (2.412 GHz instead of 246.2 MHz)*/
3536 fwrq->m = freq;
3537 fwrq->e = MHZ;
3538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003539 }
3540 }
3541 else
3542 {
3543 channel = pHddApCtx->operatingChannel;
3544 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07003545 if( TRUE == status)
3546 {
3547 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
3548 * iwlist & iwconfig command shows frequency into proper
3549 * format (2.412 GHz instead of 246.2 MHz)*/
3550 fwrq->m = freq;
3551 fwrq->e = MHZ;
3552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003553 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003554 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003555}
3556
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303557static int iw_get_ap_freq(struct net_device *dev,
3558 struct iw_request_info *info,
3559 struct iw_freq *fwrq, char *extra)
3560{
3561 int ret;
3562
3563 vos_ssr_protect(__func__);
3564 ret = __iw_get_ap_freq(dev, info, fwrq, extra);
3565 vos_ssr_unprotect(__func__);
3566
3567 return ret;
3568}
3569
3570static int __iw_get_mode(struct net_device *dev,
3571 struct iw_request_info *info,
3572 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303573{
3574 int status = 0;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303575 hdd_adapter_t *pAdapter;
3576 hdd_context_t *pHddCtx;
3577
3578 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3579 if (NULL == pAdapter)
3580 {
3581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3582 "%s: Adapter is NULL",__func__);
3583 return -EINVAL;
3584 }
3585 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3586 status = wlan_hdd_validate_context(pHddCtx);
3587 if (0 != status)
3588 {
3589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3590 "%s: HDD context is not valid",__func__);
3591 return status;
3592 }
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303593
3594 wrqu->mode = IW_MODE_MASTER;
3595
3596 return status;
3597}
3598
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303599static int iw_get_mode(struct net_device *dev,
3600 struct iw_request_info *info,
3601 union iwreq_data *wrqu, char *extra)
3602{
3603 int ret;
3604
3605 vos_ssr_protect(__func__);
3606 ret = __iw_get_mode(dev, info, wrqu, extra);
3607 vos_ssr_unprotect(__func__);
3608
3609 return ret;
3610}
3611
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303612static int __iw_softap_setwpsie(struct net_device *dev,
3613 struct iw_request_info *info,
3614 union iwreq_data *wrqu,
3615 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003616{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303617 hdd_adapter_t *pHostapdAdapter;
3618 hdd_context_t *pHddCtx;
3619 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003620 hdd_hostapd_state_t *pHostapdState;
3621 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003622 u_int8_t *wps_genie;
3623 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07003624 u_int8_t *pos;
3625 tpSap_WPSIE pSap_WPSIe;
3626 u_int8_t WPSIeType;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303627 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05303628 struct iw_point s_priv_data;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303629 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 ENTER();
3631
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303632 pHostapdAdapter = (netdev_priv(dev));
3633 if (NULL == pHostapdAdapter)
3634 {
3635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3636 "%s: Adapter is NULL",__func__);
3637 return -EINVAL;
3638 }
3639 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3640 ret = wlan_hdd_validate_context(pHddCtx);
3641 if (0 != ret)
3642 {
3643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3644 "%s: HDD context is not valid",__func__);
3645 return ret;
3646 }
3647 pVosContext = pHddCtx->pvosContext;
3648 if (NULL == pVosContext)
3649 {
3650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3651 "%s: HDD context is not valid ",__func__);
3652 return -EINVAL;
3653 }
Girish Gowli07c05ec2014-06-17 20:47:03 +05303654 /* helper function to get iwreq_data with compat handling. */
3655 if (hdd_priv_get_data(&s_priv_data, wrqu))
3656 {
3657 return -EINVAL;
3658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003659
Girish Gowli07c05ec2014-06-17 20:47:03 +05303660 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
3661 {
3662 return -EINVAL;
3663 }
3664
3665 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
3666 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07003667
Girish Gowli86c471e2014-06-17 19:28:05 +05303668 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07003669 {
Girish Gowli86c471e2014-06-17 19:28:05 +05303670 hddLog(LOG1, "%s: failed to alloc memory "
3671 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07003672 return -EFAULT;
3673 }
3674
Girish Gowli86c471e2014-06-17 19:28:05 +05303675 fwps_genie = wps_genie;
3676
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
3678 if (NULL == pSap_WPSIe)
3679 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003680 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07003681 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 return -ENOMEM;
3683 }
3684 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
3685
Arif Hussain6d2a3322013-11-17 19:50:10 -08003686 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 -07003687 WPSIeType = wps_genie[0];
3688 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
3689 {
3690 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
3691 wps_genie = wps_genie + 1;
3692 switch ( wps_genie[0] )
3693 {
3694 case DOT11F_EID_WPA:
3695 if (wps_genie[1] < 2 + 4)
3696 {
3697 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003698 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 return -EINVAL;
3700 }
3701 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3702 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003703 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 pos = &wps_genie[6];
3705 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3706 {
3707 switch((u_int16_t)(*pos<<8) | *(pos+1))
3708 {
3709 case HDD_WPS_ELEM_VERSION:
3710 pos += 4;
3711 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003712 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003713 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
3714 pos += 1;
3715 break;
3716
3717 case HDD_WPS_ELEM_WPS_STATE:
3718 pos +=4;
3719 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003720 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003721 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
3722 pos += 1;
3723 break;
3724 case HDD_WPS_ELEM_APSETUPLOCK:
3725 pos += 4;
3726 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003727 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
3729 pos += 1;
3730 break;
3731 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3732 pos += 4;
3733 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003734 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
3736 pos += 1;
3737 break;
3738 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3739 pos += 4;
3740 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003741 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003742 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
3743 pos += 2;
3744 break;
3745 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3746 pos += 4;
3747 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003748 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003749 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
3750 pos += 2;
3751 break;
3752
3753 case HDD_WPS_ELEM_UUID_E:
3754 pos += 2;
3755 length = *pos<<8 | *(pos+1);
3756 pos += 2;
3757 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
3758 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
3759 pos += length;
3760 break;
3761 case HDD_WPS_ELEM_RF_BANDS:
3762 pos += 4;
3763 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003764 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003765 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
3766 pos += 1;
3767 break;
3768
3769 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08003770 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07003771 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003772 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003773 return -EINVAL;
3774 }
3775 }
3776 }
3777 else {
3778 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003779 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003780 }
3781 break;
3782
3783 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003784 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003785 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003786 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003787 return 0;
3788 }
3789 }
3790 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
3791 {
3792 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
3793 wps_genie = wps_genie + 1;
3794 switch ( wps_genie[0] )
3795 {
3796 case DOT11F_EID_WPA:
3797 if (wps_genie[1] < 2 + 4)
3798 {
3799 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003800 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003801 return -EINVAL;
3802 }
3803 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3804 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003805 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003806 pos = &wps_genie[6];
3807 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3808 {
3809 switch((u_int16_t)(*pos<<8) | *(pos+1))
3810 {
3811 case HDD_WPS_ELEM_VERSION:
3812 pos += 4;
3813 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003814 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003815 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
3816 pos += 1;
3817 break;
3818
3819 case HDD_WPS_ELEM_WPS_STATE:
3820 pos +=4;
3821 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003822 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003823 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
3824 pos += 1;
3825 break;
3826 case HDD_WPS_ELEM_APSETUPLOCK:
3827 pos += 4;
3828 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003829 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003830 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
3831 pos += 1;
3832 break;
3833 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3834 pos += 4;
3835 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003836 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003837 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
3838 pos += 1;
3839 break;
3840 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3841 pos += 4;
3842 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003843 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003844 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
3845 pos += 2;
3846 break;
3847 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3848 pos += 4;
3849 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003850 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003851 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
3852 pos += 2;
3853 break;
3854 case HDD_WPS_ELEM_RSP_TYPE:
3855 pos += 4;
3856 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003857 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07003858 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
3859 pos += 1;
3860 break;
3861 case HDD_WPS_ELEM_UUID_E:
3862 pos += 2;
3863 length = *pos<<8 | *(pos+1);
3864 pos += 2;
3865 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
3866 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
3867 pos += length;
3868 break;
3869
3870 case HDD_WPS_ELEM_MANUFACTURER:
3871 pos += 2;
3872 length = *pos<<8 | *(pos+1);
3873 pos += 2;
3874 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
3875 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
3876 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
3877 pos += length;
3878 break;
3879
3880 case HDD_WPS_ELEM_MODEL_NAME:
3881 pos += 2;
3882 length = *pos<<8 | *(pos+1);
3883 pos += 2;
3884 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
3885 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
3886 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
3887 pos += length;
3888 break;
3889 case HDD_WPS_ELEM_MODEL_NUM:
3890 pos += 2;
3891 length = *pos<<8 | *(pos+1);
3892 pos += 2;
3893 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
3894 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
3895 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
3896 pos += length;
3897 break;
3898 case HDD_WPS_ELEM_SERIAL_NUM:
3899 pos += 2;
3900 length = *pos<<8 | *(pos+1);
3901 pos += 2;
3902 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
3903 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
3904 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
3905 pos += length;
3906 break;
3907 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
3908 pos += 4;
3909 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003910 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003911 pos += 2;
3912
3913 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003914 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003915 pos += 4;
3916 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003917 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003918 pos += 2;
3919 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
3920 break;
3921 case HDD_WPS_ELEM_DEVICE_NAME:
3922 pos += 2;
3923 length = *pos<<8 | *(pos+1);
3924 pos += 2;
3925 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
3926 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
3927 pos += length;
3928 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
3929 break;
3930 case HDD_WPS_ELEM_CONFIG_METHODS:
3931 pos += 4;
3932 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003933 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003934 pos += 2;
3935 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
3936 break;
3937
3938 case HDD_WPS_ELEM_RF_BANDS:
3939 pos += 4;
3940 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003941 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003942 pos += 1;
3943 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
3944 break;
3945 } // switch
3946 }
3947 }
3948 else
3949 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003950 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003951 }
3952
3953 } // switch
3954 }
3955 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
3956 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3957 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3958 {
3959 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3960 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3961 WLANSAP_Update_WpsIe ( pVosContext );
3962 }
3963
3964 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003965 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 EXIT();
3967 return halStatus;
3968}
3969
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303970static int iw_softap_setwpsie(struct net_device *dev,
3971 struct iw_request_info *info,
3972 union iwreq_data *wrqu,
3973 char *extra)
3974{
3975 int ret;
3976
3977 vos_ssr_protect(__func__);
3978 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
3979 vos_ssr_unprotect(__func__);
3980
3981 return ret;
3982}
3983
3984static int __iw_softap_stopbss(struct net_device *dev,
3985 struct iw_request_info *info,
3986 union iwreq_data *wrqu,
3987 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003988{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303989 hdd_adapter_t *pHostapdAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07003990 VOS_STATUS status = VOS_STATUS_SUCCESS;
Agarwal Ashish51325b52014-06-16 16:50:49 +05303991 hdd_context_t *pHddCtx = NULL;
3992
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05303994 pHostapdAdapter = (netdev_priv(dev));
3995 if (NULL == pHostapdAdapter)
3996 {
3997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3998 "%s: Adapter is NULL",__func__);
3999 return -EINVAL;
4000 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05304001 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4002 status = wlan_hdd_validate_context(pHddCtx);
Agarwal Ashish51325b52014-06-16 16:50:49 +05304003 if (0 != status) {
4004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
4005 return status;
4006 }
4007
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304008 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07004009 {
4010 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
4011 {
4012 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4013
4014 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304015
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 if (!VOS_IS_STATUS_SUCCESS(status))
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304017 {
4018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004019 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004020 VOS_ASSERT(0);
4021 }
4022 }
4023 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05304024 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 }
4026 EXIT();
4027 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
4028}
4029
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05304030static int iw_softap_stopbss(struct net_device *dev,
4031 struct iw_request_info *info,
4032 union iwreq_data *wrqu,
4033 char *extra)
4034{
4035 int ret;
4036
4037 vos_ssr_protect(__func__);
4038 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
4039 vos_ssr_unprotect(__func__);
4040
4041 return ret;
4042}
4043
4044static int __iw_softap_version(struct net_device *dev,
4045 struct iw_request_info *info,
4046 union iwreq_data *wrqu,
4047 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07004048{
Jeff Johnson295189b2012-06-20 16:38:30 -07004049 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304050 hdd_context_t *pHddCtx;
4051 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004052 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304053 pHostapdAdapter = (netdev_priv(dev));
4054 if (NULL == pHostapdAdapter)
4055 {
4056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4057 "%s: Adapter is NULL",__func__);
4058 return -EINVAL;
4059 }
4060 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4061 ret = wlan_hdd_validate_context(pHddCtx);
4062 if (0 != ret)
4063 {
4064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4065 "%s: HDD context is not valid",__func__);
4066 return ret;
4067 }
Jeff Johnson4824d4c2013-02-12 14:23:57 -08004068 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 return 0;
4071}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004072
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05304073static int iw_softap_version(struct net_device *dev,
4074 struct iw_request_info *info,
4075 union iwreq_data *wrqu,
4076 char *extra)
4077{
4078 int ret;
4079
4080 vos_ssr_protect(__func__);
4081 ret = __iw_softap_version(dev, info, wrqu, extra);
4082 vos_ssr_unprotect(__func__);
4083
4084 return ret;
4085}
4086
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07004087VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004088{
4089 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07004090 int len = 0;
4091 const char sta_info_header[] = "staId staAddress\n";
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304092 v_CONTEXT_t pVosContext;
4093 hdd_context_t *pHddCtx;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05304094 ptSapContext pSapCtx = NULL;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304095
4096 if (NULL == pAdapter)
4097 {
4098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4099 "%s: Adapter is NULL",__func__);
4100 return -EINVAL;
4101 }
4102 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4103 if (0 != wlan_hdd_validate_context(pHddCtx))
4104 {
4105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4106 "%s: HDD context is not valid ",__func__);
4107 return VOS_STATUS_E_FAULT;
4108 }
4109 pVosContext = pHddCtx->pvosContext;
4110 if (NULL == pVosContext)
4111 {
4112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4113 "%s: VOS context is not valid",__func__);
4114 return VOS_STATUS_E_FAULT;
4115 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05304116 pSapCtx = VOS_GET_SAP_CB(pVosContext);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304117 if(pSapCtx == NULL)
4118 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05304119 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
4120 FL("psapCtx is NULL"));
4121 return VOS_STATUS_E_FAULT;
4122 }
4123
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004124 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07004125 pBuf += len;
4126 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004127
4128 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
4129 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05304130 if(pSapCtx->aStaInfo[i].isUsed)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004131 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08004132 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05304133 pSapCtx->aStaInfo[i].ucSTAId,
4134 pSapCtx->aStaInfo[i].macAddrSTA.bytes[0],
4135 pSapCtx->aStaInfo[i].macAddrSTA.bytes[1],
4136 pSapCtx->aStaInfo[i].macAddrSTA.bytes[2],
4137 pSapCtx->aStaInfo[i].macAddrSTA.bytes[3],
4138 pSapCtx->aStaInfo[i].macAddrSTA.bytes[4],
4139 pSapCtx->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07004140 pBuf += len;
4141 buf_len -= len;
4142 }
4143 if(WE_GET_STA_INFO_SIZE > buf_len)
4144 {
4145 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004146 }
4147 }
4148 return VOS_STATUS_SUCCESS;
4149}
4150
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05304151static int __iw_softap_get_sta_info(struct net_device *dev,
4152 struct iw_request_info *info,
4153 union iwreq_data *wrqu,
4154 char *extra)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004155{
4156 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4157 VOS_STATUS status;
4158 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07004159 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004160 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004162 return -EINVAL;
4163 }
4164 wrqu->data.length = strlen(extra);
4165 EXIT();
4166 return 0;
4167}
4168
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05304169static int iw_softap_get_sta_info(struct net_device *dev,
4170 struct iw_request_info *info,
4171 union iwreq_data *wrqu,
4172 char *extra)
4173{
4174 int ret;
4175
4176 vos_ssr_protect(__func__);
4177 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
4178 vos_ssr_unprotect(__func__);
4179
4180 return ret;
4181}
4182
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05304183static int __iw_set_ap_genie(struct net_device *dev,
4184 struct iw_request_info *info,
4185 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07004186{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304187
4188 hdd_adapter_t *pHostapdAdapter;
4189 hdd_context_t *pHddCtx;
4190 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004191 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07004192 u_int8_t *genie = (u_int8_t *)extra;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304193 int ret = 0;
4194
Jeff Johnson295189b2012-06-20 16:38:30 -07004195 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304196 pHostapdAdapter = (netdev_priv(dev));
4197 if (NULL == pHostapdAdapter)
4198 {
4199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4200 "%s: Adapter is NULL",__func__);
4201 return -EINVAL;
4202 }
4203 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4204 ret = wlan_hdd_validate_context(pHddCtx);
4205 if (0 != ret)
4206 {
4207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4208 "%s: HDD context is not valid",__func__);
4209 return ret;
4210 }
4211 pVosContext = pHddCtx->pvosContext;
4212 if (NULL == pVosContext)
4213 {
4214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4215 "%s: VOS Context is NULL",__func__);
4216 return -EINVAL;
4217 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 if(!wrqu->data.length)
4219 {
4220 EXIT();
4221 return 0;
4222 }
Arif Hussained667642013-10-27 23:01:14 -07004223
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304224 switch (genie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 {
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304226 case DOT11F_EID_WPA:
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 case DOT11F_EID_RSN:
4228 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
4229 {
4230 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
4231 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07004234 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 break;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304236
Jeff Johnson295189b2012-06-20 16:38:30 -07004237 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004238 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07004239 halStatus = 0;
4240 }
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304241
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 EXIT();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304243 return halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07004244}
4245
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05304246static int iw_set_ap_genie(struct net_device *dev,
4247 struct iw_request_info *info,
4248 union iwreq_data *wrqu, char *extra)
4249{
4250 int ret;
4251
4252 vos_ssr_protect(__func__);
4253 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
4254 vos_ssr_unprotect(__func__);
4255
4256 return ret;
4257}
4258
Jeff Johnson295189b2012-06-20 16:38:30 -07004259static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
4260{
4261 eHalStatus hstatus;
4262 long lrc;
4263 struct statsContext context;
4264
4265 if (NULL == pAdapter)
4266 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05304267 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004268 return VOS_STATUS_E_FAULT;
4269 }
4270
4271 init_completion(&context.completion);
4272 context.pAdapter = pAdapter;
4273 context.magic = STATS_CONTEXT_MAGIC;
4274 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
4275 eCSR_HDD,
4276 SME_GLOBAL_CLASSA_STATS,
4277 hdd_GetClassA_statisticsCB,
4278 0, // not periodic
4279 FALSE, //non-cached results
4280 staid,
4281 &context);
4282 if (eHAL_STATUS_SUCCESS != hstatus)
4283 {
4284 hddLog(VOS_TRACE_LEVEL_ERROR,
4285 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004286 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004287 }
4288 else
4289 {
4290 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4291 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 if (lrc <= 0)
4293 {
4294 hddLog(VOS_TRACE_LEVEL_ERROR,
4295 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004296 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07004297 }
4298 }
Jeff Johnson72a40512013-12-19 10:14:15 -08004299
4300 /* either we never sent a request, we sent a request and received a
4301 response or we sent a request and timed out. if we never sent a
4302 request or if we sent a request and got a response, we want to
4303 clear the magic out of paranoia. if we timed out there is a
4304 race condition such that the callback function could be
4305 executing at the same time we are. of primary concern is if the
4306 callback function had already verified the "magic" but had not
4307 yet set the completion variable when a timeout occurred. we
4308 serialize these activities by invalidating the magic while
4309 holding a shared spinlock which will cause us to block if the
4310 callback is currently executing */
4311 spin_lock(&hdd_context_lock);
4312 context.magic = 0;
4313 spin_unlock(&hdd_context_lock);
4314
Jeff Johnson295189b2012-06-20 16:38:30 -07004315 return VOS_STATUS_SUCCESS;
4316}
4317
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05304318int __iw_get_softap_linkspeed(struct net_device *dev,
4319 struct iw_request_info *info,
4320 union iwreq_data *wrqu,
4321 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07004322
4323{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304324 hdd_adapter_t *pHostapdAdapter;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304325 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004326 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07004327 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304328 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07004329 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304330 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004331 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08004332 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304333 int rc, valid;
4334
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304335 pHostapdAdapter = (netdev_priv(dev));
4336 if (NULL == pHostapdAdapter)
4337 {
4338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4339 "%s: Adapter is NULL",__func__);
4340 return -EINVAL;
4341 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304342 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304343 valid = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304344 if (0 != valid)
4345 {
4346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
4347 return valid;
4348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004349
Arif Hussain6d2a3322013-11-17 19:50:10 -08004350 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08004351
4352 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07004353 {
Arif Hussaina9571842014-01-15 16:43:41 -08004354 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
4355 if (NULL == pmacAddress) {
4356 hddLog(LOG1, "unable to allocate memory");
4357 return -ENOMEM;
4358 }
4359 if (copy_from_user((void *)pmacAddress,
4360 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
4361 {
4362 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
4363 kfree(pmacAddress);
4364 return -EFAULT;
4365 }
4366 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
4367
4368 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07004369 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08004370
4371 if (!VOS_IS_STATUS_SUCCESS(status ))
4372 {
4373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
4374 }
Arif Hussained667642013-10-27 23:01:14 -07004375 }
Kiet Lam61589852013-09-19 17:10:58 +05304376 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05304377 * link speed for first connected client will be returned.
4378 */
Arif Hussaina9571842014-01-15 16:43:41 -08004379 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05304380 {
4381 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
4382 }
4383 else
4384 {
4385 status = hdd_softap_GetStaId(pHostapdAdapter,
4386 (v_MACADDR_t *)macAddress, (void *)(&staId));
4387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004388
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304389 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07004390 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 link_speed = 0;
4393 }
4394 else
4395 {
4396 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304397
Jeff Johnson295189b2012-06-20 16:38:30 -07004398 if (!VOS_IS_STATUS_SUCCESS(status ))
4399 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004401 return -EINVAL;
4402 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304403
4404 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
4405 staId, &link_speed);
4406
4407 link_speed = link_speed / 10;
4408
4409 if (0 == link_speed)
4410 {
4411 /* The linkspeed returned by HAL is in units of 500kbps.
4412 * converting it to mbps.
4413 * This is required to support legacy firmware which does
4414 * not return link capacity.
4415 */
4416 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
4417 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004418 }
4419
4420 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07004421 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304422
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 if ((rc < 0) || (rc >= len))
4424 {
4425 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304426 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004427 return -EIO;
4428 }
4429
4430 return 0;
4431}
4432
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05304433int iw_get_softap_linkspeed(struct net_device *dev,
4434 struct iw_request_info *info,
4435 union iwreq_data *wrqu,
4436 char *extra)
4437{
4438 int ret;
4439
4440 vos_ssr_protect(__func__);
4441 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
4442 vos_ssr_unprotect(__func__);
4443
4444 return ret;
4445}
4446
4447
Jeff Johnson295189b2012-06-20 16:38:30 -07004448static const iw_handler hostapd_handler[] =
4449{
4450 (iw_handler) NULL, /* SIOCSIWCOMMIT */
4451 (iw_handler) NULL, /* SIOCGIWNAME */
4452 (iw_handler) NULL, /* SIOCSIWNWID */
4453 (iw_handler) NULL, /* SIOCGIWNWID */
4454 (iw_handler) NULL, /* SIOCSIWFREQ */
4455 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
4456 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05304457 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07004458 (iw_handler) NULL, /* SIOCSIWSENS */
4459 (iw_handler) NULL, /* SIOCGIWSENS */
4460 (iw_handler) NULL, /* SIOCSIWRANGE */
4461 (iw_handler) NULL, /* SIOCGIWRANGE */
4462 (iw_handler) NULL, /* SIOCSIWPRIV */
4463 (iw_handler) NULL, /* SIOCGIWPRIV */
4464 (iw_handler) NULL, /* SIOCSIWSTATS */
4465 (iw_handler) NULL, /* SIOCGIWSTATS */
4466 (iw_handler) NULL, /* SIOCSIWSPY */
4467 (iw_handler) NULL, /* SIOCGIWSPY */
4468 (iw_handler) NULL, /* SIOCSIWTHRSPY */
4469 (iw_handler) NULL, /* SIOCGIWTHRSPY */
4470 (iw_handler) NULL, /* SIOCSIWAP */
4471 (iw_handler) NULL, /* SIOCGIWAP */
4472 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
4473 (iw_handler) NULL, /* SIOCGIWAPLIST */
4474 (iw_handler) NULL, /* SIOCSIWSCAN */
4475 (iw_handler) NULL, /* SIOCGIWSCAN */
4476 (iw_handler) NULL, /* SIOCSIWESSID */
4477 (iw_handler) NULL, /* SIOCGIWESSID */
4478 (iw_handler) NULL, /* SIOCSIWNICKN */
4479 (iw_handler) NULL, /* SIOCGIWNICKN */
4480 (iw_handler) NULL, /* -- hole -- */
4481 (iw_handler) NULL, /* -- hole -- */
4482 (iw_handler) NULL, /* SIOCSIWRATE */
4483 (iw_handler) NULL, /* SIOCGIWRATE */
4484 (iw_handler) NULL, /* SIOCSIWRTS */
4485 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
4486 (iw_handler) NULL, /* SIOCSIWFRAG */
4487 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
4488 (iw_handler) NULL, /* SIOCSIWTXPOW */
4489 (iw_handler) NULL, /* SIOCGIWTXPOW */
4490 (iw_handler) NULL, /* SIOCSIWRETRY */
4491 (iw_handler) NULL, /* SIOCGIWRETRY */
4492 (iw_handler) NULL, /* SIOCSIWENCODE */
4493 (iw_handler) NULL, /* SIOCGIWENCODE */
4494 (iw_handler) NULL, /* SIOCSIWPOWER */
4495 (iw_handler) NULL, /* SIOCGIWPOWER */
4496 (iw_handler) NULL, /* -- hole -- */
4497 (iw_handler) NULL, /* -- hole -- */
4498 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
4499 (iw_handler) NULL, /* SIOCGIWGENIE */
4500 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
4501 (iw_handler) NULL, /* SIOCGIWAUTH */
4502 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
4503 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
4504 (iw_handler) NULL, /* SIOCSIWPMKSA */
4505};
4506
Jeff Johnson224f3702014-03-26 11:09:47 -07004507/*
4508 * Note that the following ioctls were defined with semantics which
4509 * cannot be handled by the "iwpriv" userspace application and hence
4510 * they are not included in the hostapd_private_args array
4511 * QCSAP_IOCTL_ASSOC_STA_MACADDR
4512 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004513
4514static const struct iw_priv_args hostapd_private_args[] = {
4515 { QCSAP_IOCTL_SETPARAM,
4516 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
4517 { QCSAP_IOCTL_SETPARAM,
4518 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
4519 { QCSAP_PARAM_MAX_ASSOC,
4520 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
4521 { QCSAP_PARAM_HIDE_SSID,
4522 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07004523 { QCSAP_PARAM_SET_MC_RATE,
4524 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004525 { QCSAP_IOCTL_GETPARAM,
4526 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4527 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
4528 { QCSAP_IOCTL_GETPARAM, 0,
4529 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
4530 { QCSAP_PARAM_MAX_ASSOC, 0,
4531 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07004532 { QCSAP_PARAM_GET_WLAN_DBG, 0,
4533 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
4534 { QCSAP_PARAM_AUTO_CHANNEL, 0,
4535 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05304536 { QCSAP_PARAM_SET_AUTO_CHANNEL,
4537 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004538 { QCSAP_PARAM_CLR_ACL, 0,
4539 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
4540 { QCSAP_PARAM_ACL_MODE,
4541 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 { QCSAP_IOCTL_GET_STAWPAIE,
4543 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
4544 { QCSAP_IOCTL_SETWPAIE,
4545 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
4546 { QCSAP_IOCTL_STOPBSS,
4547 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
4548 { QCSAP_IOCTL_VERSION, 0,
4549 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004550 { QCSAP_IOCTL_GET_STA_INFO, 0,
4551 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004552 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08004553 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004554 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07004555 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07004556 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07004557 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05304558 { QCSAP_IOCTL_AP_STATS, 0,
4559 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004560 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
4561 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05304562 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004563
4564 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
4565 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
4566 /* handlers for sub-ioctl */
4567 { WE_SET_WLAN_DBG,
4568 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
4569 0,
4570 "setwlandbg" },
4571
4572 /* handlers for main ioctl */
4573 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
4574 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
4575 0,
4576 "" },
4577
4578 /* handlers for sub-ioctl */
4579 { WE_LOG_DUMP_CMD,
4580 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
4581 0,
4582 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 { WE_P2P_NOA_CMD,
4584 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
4585 0,
4586 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08004587 /* handlers for sub ioctl */
4588 {
4589 WE_MCC_CONFIG_CREDENTIAL,
4590 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
4591 0,
4592 "setMccCrdnl" },
4593
4594 /* handlers for sub ioctl */
4595 {
4596 WE_MCC_CONFIG_PARAMS,
4597 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
4598 0,
4599 "setMccConfig" },
4600
Jeff Johnson295189b2012-06-20 16:38:30 -07004601 /* handlers for main ioctl */
4602 { QCSAP_IOCTL_MODIFY_ACL,
4603 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
4604 0,
4605 "modify_acl" },
4606
4607 /* handlers for main ioctl */
4608 { QCSAP_IOCTL_GET_CHANNEL_LIST,
4609 0,
4610 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
4611 "getChannelList" },
4612
Jeff Johnsone7245742012-09-05 17:12:55 -07004613 /* handlers for main ioctl */
4614 { QCSAP_IOCTL_SET_TX_POWER,
4615 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
4616 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05304617 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07004618
4619 /* handlers for main ioctl */
4620 { QCSAP_IOCTL_SET_MAX_TX_POWER,
4621 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
4622 0,
4623 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05304624
4625 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
4626 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
4627 0,
4628 "dataSnapshot" },
4629
4630 /* handlers for main ioctl */
4631 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
4632 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
4633 0,
4634 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004635};
Jeff Johnsone7245742012-09-05 17:12:55 -07004636
Jeff Johnson295189b2012-06-20 16:38:30 -07004637static const iw_handler hostapd_private[] = {
4638 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
4639 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07004640 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
4641 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
4642 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
4643 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
4644 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
4645 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
4646 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
4647 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
4648 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05304649 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
4651 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
4652 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
4653 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004654 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07004655 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
4656 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07004657 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05304658 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05304659 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07004660};
4661const struct iw_handler_def hostapd_handler_def = {
4662 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
4663 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
4664 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
4665 .standard = (iw_handler *)hostapd_handler,
4666 .private = (iw_handler *)hostapd_private,
4667 .private_args = hostapd_private_args,
4668 .get_wireless_stats = NULL,
4669};
4670#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4671struct net_device_ops net_ops_struct = {
4672 .ndo_open = hdd_hostapd_open,
4673 .ndo_stop = hdd_hostapd_stop,
4674 .ndo_uninit = hdd_hostapd_uninit,
4675 .ndo_start_xmit = hdd_softap_hard_start_xmit,
4676 .ndo_tx_timeout = hdd_softap_tx_timeout,
4677 .ndo_get_stats = hdd_softap_stats,
4678 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
4679 .ndo_do_ioctl = hdd_hostapd_ioctl,
4680 .ndo_change_mtu = hdd_hostapd_change_mtu,
4681 .ndo_select_queue = hdd_hostapd_select_queue,
4682 };
4683#endif
4684
4685int hdd_set_hostapd(hdd_adapter_t *pAdapter)
4686{
4687 return VOS_STATUS_SUCCESS;
4688}
4689
4690void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
4691{
4692#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4693 pWlanHostapdDev->netdev_ops = &net_ops_struct;
4694#else
4695 pWlanHostapdDev->open = hdd_hostapd_open;
4696 pWlanHostapdDev->stop = hdd_hostapd_stop;
4697 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
4698 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
4699 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
4700 pWlanHostapdDev->get_stats = hdd_softap_stats;
4701 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
4702 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
4703#endif
4704}
4705
4706VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304707{
Jeff Johnson295189b2012-06-20 16:38:30 -07004708 hdd_hostapd_state_t * phostapdBuf;
4709 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004710 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004711 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08004712#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08004713 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
4714 v_U16_t unsafeChannelCount;
4715#endif /* FEATURE_WLAN_CH_AVOID */
4716
Anand N Sunkad26d71b92014-12-24 18:08:22 +05304717 if (pHddCtx->isLogpInProgress) {
4718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4719 "%s:LOGP in Progress. Ignore!!!",__func__);
4720 status = VOS_STATUS_E_FAILURE;
4721 }
4722
Jeff Johnson295189b2012-06-20 16:38:30 -07004723 ENTER();
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304724 // Allocate the Wireless Extensions state structure
Jeff Johnson295189b2012-06-20 16:38:30 -07004725 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +05304726
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004727 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
4728
Leo Chang0b0e45a2013-12-15 15:18:55 -08004729#ifdef FEATURE_WLAN_CH_AVOID
4730 /* Get unsafe cahnnel list from cached location */
4731 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
4732 sizeof(unsafeChannelList),
4733 &unsafeChannelCount);
4734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4735 "%s : Unsafe Channel count %d",
4736 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05304737 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08004738 unsafeChannelList,
4739 unsafeChannelCount);
4740#endif /* FEATURE_WLAN_CH_AVOID */
4741
Jeff Johnson295189b2012-06-20 16:38:30 -07004742 // Zero the memory. This zeros the profile structure.
4743 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
4744
4745 // Set up the pointer to the Wireless Extensions state structure
4746 // NOP
4747 status = hdd_set_hostapd(pAdapter);
4748 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004750 return status;
4751 }
4752
4753 status = vos_event_init(&phostapdBuf->vosEvent);
4754 if (!VOS_IS_STATUS_SUCCESS(status))
4755 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004757 return status;
4758 }
4759
4760 init_completion(&pAdapter->session_close_comp_var);
4761 init_completion(&pAdapter->session_open_comp_var);
4762
4763 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
4764
4765 // Register as a wireless device
4766 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
4767
4768 //Initialize the data path module
4769 status = hdd_softap_init_tx_rx(pAdapter);
4770 if ( !VOS_IS_STATUS_SUCCESS( status ))
4771 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004773 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304774
4775 status = hdd_wmm_adapter_init( pAdapter );
4776 if (!VOS_IS_STATUS_SUCCESS(status))
4777 {
4778 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004779 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304780 status, status );
4781 goto error_wmm_init;
4782 }
4783
4784 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
4785
Jeff Johnson295189b2012-06-20 16:38:30 -07004786 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304787
4788 return status;
4789
4790error_wmm_init:
4791 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 EXIT();
4793 return status;
4794}
4795
4796hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
4797{
4798 struct net_device *pWlanHostapdDev = NULL;
4799 hdd_adapter_t *pHostapdAdapter = NULL;
4800 v_CONTEXT_t pVosContext= NULL;
4801
Jeff Johnson295189b2012-06-20 16:38:30 -07004802 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07004803
4804 if (pWlanHostapdDev != NULL)
4805 {
4806 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
4807
4808 //Init the net_device structure
4809 ether_setup(pWlanHostapdDev);
4810
4811 //Initialize the adapter context to zeros.
4812 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
4813 pHostapdAdapter->dev = pWlanHostapdDev;
4814 pHostapdAdapter->pHddCtx = pHddCtx;
4815 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
4816
4817 //Get the Global VOSS context.
4818 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4819 //Save the adapter context in global context for future.
4820 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
4821
4822 //Init the net_device structure
4823 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
4824
4825 hdd_set_ap_ops( pHostapdAdapter->dev );
4826
Jeff Johnson295189b2012-06-20 16:38:30 -07004827 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
4828 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
4829
4830 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
4831 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
4832
4833 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
4835 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
4836 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
4837 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004838 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
4839 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05304840 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07004841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4842 init_completion(&pHostapdAdapter->offchannel_tx_event);
4843#endif
4844
Jeff Johnson295189b2012-06-20 16:38:30 -07004845 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
4846 }
4847 return pHostapdAdapter;
4848}
4849
4850VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
4851{
4852 struct net_device *dev = pAdapter->dev;
4853 VOS_STATUS status = VOS_STATUS_SUCCESS;
4854
4855 ENTER();
4856
4857 if( rtnl_lock_held )
4858 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08004859 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07004860 if( dev_alloc_name(dev, dev->name) < 0 )
4861 {
4862 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
4863 return VOS_STATUS_E_FAILURE;
4864 }
4865 }
4866 if (register_netdevice(dev))
4867 {
4868 hddLog(VOS_TRACE_LEVEL_FATAL,
4869 "%s:Failed:register_netdevice", __func__);
4870 return VOS_STATUS_E_FAILURE;
4871 }
4872 }
4873 else
4874 {
4875 if (register_netdev(dev))
4876 {
4877 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
4878 return VOS_STATUS_E_FAILURE;
4879 }
4880 }
4881 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
4882
4883 EXIT();
4884 return status;
4885}
4886
4887VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
4888{
4889 ENTER();
4890
4891 hdd_softap_deinit_tx_rx(pAdapter);
4892
4893 /* if we are being called during driver unload, then the dev has already
4894 been invalidated. if we are being called at other times, then we can
4895 detatch the wireless device handlers */
4896 if (pAdapter->dev)
4897 {
4898 pAdapter->dev->wireless_handlers = NULL;
4899 }
4900 EXIT();
4901 return 0;
4902}