blob: d75ae291530708ec49af29285b3bd820a3f0a266 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
Jeff Johnson295189b2012-06-20 16:38:30 -070027
28/**========================================================================
29
30 \file wlan_hdd_hostapd.c
31 \brief WLAN Host Device Driver implementation
32
33 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
34
35 Qualcomm Confidential and Proprietary.
36
37 ========================================================================*/
38/**=========================================================================
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45 $Header:$ $DateTime: $ $Author: $
46
47
48 when who what, where, why
49 -------- --- --------------------------------------------------------
50 04/5/09 Shailender Created module.
51 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
52 ==========================================================================*/
53/*--------------------------------------------------------------------------
54 Include Files
55 ------------------------------------------------------------------------*/
56
57#include <linux/version.h>
58#include <linux/module.h>
59#include <linux/kernel.h>
60#include <linux/init.h>
61#include <linux/wireless.h>
62#include <linux/semaphore.h>
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -070063#include <linux/compat.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
66#include <linux/etherdevice.h>
67#include <wlan_hdd_includes.h>
68#include <qc_sap_ioctl.h>
69#include <wlan_hdd_hostapd.h>
70#include <sapApi.h>
71#include <sapInternal.h>
72#include <wlan_qct_tl.h>
73#include <wlan_hdd_softap_tx_rx.h>
74#include <wlan_hdd_main.h>
75#include <linux/netdevice.h>
76#include <linux/mmc/sdio_func.h>
77#include "wlan_nlink_common.h"
78#include "wlan_btc_svc.h"
79#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070080#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070081#include "cfgApi.h"
82#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070083
Leo Chang0b0e45a2013-12-15 15:18:55 -080084#ifdef FEATURE_WLAN_CH_AVOID
85#include "wcnss_wlan.h"
86#endif /* FEATURE_WLAN_CH_AVOID */
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Leo Chang0b0e45a2013-12-15 15:18:55 -080090
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define IS_UP(_dev) \
92 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
93#define IS_UP_AUTO(_ic) \
94 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
95#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -070096#define WE_GET_STA_INFO_SIZE 30
97/* WEXT limition: MAX allowed buf len for any *
98 * IW_PRIV_TYPE_CHAR is 2Kbytes *
99 */
100#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530102#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700103
Leo Chang0b0e45a2013-12-15 15:18:55 -0800104#ifdef FEATURE_WLAN_CH_AVOID
105/* Channle/Freqency table */
106extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
107safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
108{
109 /*CH , SAFE, default safe */
110 {1 , VOS_TRUE}, //RF_CHAN_1,
111 {2 , VOS_TRUE}, //RF_CHAN_2,
112 {3 , VOS_TRUE}, //RF_CHAN_3,
113 {4 , VOS_TRUE}, //RF_CHAN_4,
114 {5 , VOS_TRUE}, //RF_CHAN_5,
115 {6 , VOS_TRUE}, //RF_CHAN_6,
116 {7 , VOS_TRUE}, //RF_CHAN_7,
117 {8 , VOS_TRUE}, //RF_CHAN_8,
118 {9 , VOS_TRUE}, //RF_CHAN_9,
119 {10 , VOS_TRUE}, //RF_CHAN_10,
120 {11 , VOS_TRUE}, //RF_CHAN_11,
121 {12 , VOS_TRUE}, //RF_CHAN_12,
122 {13 , VOS_TRUE}, //RF_CHAN_13,
123 {14 , VOS_TRUE}, //RF_CHAN_14,
124 {240, VOS_TRUE}, //RF_CHAN_240,
125 {244, VOS_TRUE}, //RF_CHAN_244,
126 {248, VOS_TRUE}, //RF_CHAN_248,
127 {252, VOS_TRUE}, //RF_CHAN_252,
128 {208, VOS_TRUE}, //RF_CHAN_208,
129 {212, VOS_TRUE}, //RF_CHAN_212,
130 {216, VOS_TRUE}, //RF_CHAN_216,
131 {36 , VOS_TRUE}, //RF_CHAN_36,
132 {40 , VOS_TRUE}, //RF_CHAN_40,
133 {44 , VOS_TRUE}, //RF_CHAN_44,
134 {48 , VOS_TRUE}, //RF_CHAN_48,
135 {52 , VOS_TRUE}, //RF_CHAN_52,
136 {56 , VOS_TRUE}, //RF_CHAN_56,
137 {60 , VOS_TRUE}, //RF_CHAN_60,
138 {64 , VOS_TRUE}, //RF_CHAN_64,
139 {100, VOS_TRUE}, //RF_CHAN_100,
140 {104, VOS_TRUE}, //RF_CHAN_104,
141 {108, VOS_TRUE}, //RF_CHAN_108,
142 {112, VOS_TRUE}, //RF_CHAN_112,
143 {116, VOS_TRUE}, //RF_CHAN_116,
144 {120, VOS_TRUE}, //RF_CHAN_120,
145 {124, VOS_TRUE}, //RF_CHAN_124,
146 {128, VOS_TRUE}, //RF_CHAN_128,
147 {132, VOS_TRUE}, //RF_CHAN_132,
148 {136, VOS_TRUE}, //RF_CHAN_136,
149 {140, VOS_TRUE}, //RF_CHAN_140,
150 {149, VOS_TRUE}, //RF_CHAN_149,
151 {153, VOS_TRUE}, //RF_CHAN_153,
152 {157, VOS_TRUE}, //RF_CHAN_157,
153 {161, VOS_TRUE}, //RF_CHAN_161,
154 {165, VOS_TRUE}, //RF_CHAN_165,
155};
156#endif /* FEATURE_WLAN_CH_AVOID */
157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530158/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 * Function definitions
160 *-------------------------------------------------------------------------*/
161/**---------------------------------------------------------------------------
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530162
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530163 \brief __hdd_hostapd_open() - HDD Open function for hostapd interface
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530164
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 This is called in response to ifconfig up
166
167 \param - dev Pointer to net_device structure
168
169 \return - 0 for success non-zero for failure
170
171 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530172int __hdd_hostapd_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700173{
Siddharth Bhal2db319d2014-12-03 12:37:18 +0530174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
175
Jeff Johnson295189b2012-06-20 16:38:30 -0700176 ENTER();
177
Siddharth Bhal2db319d2014-12-03 12:37:18 +0530178 if(!test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
179 {
180 //WMM_INIT OR BSS_START not completed
181 hddLog( LOGW, "Ignore hostadp open request");
182 EXIT();
183 return 0;
184 }
185
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530186 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
187 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -0700188 //Turn ON carrier state
189 netif_carrier_on(dev);
190 //Enable all Tx queues
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 netif_tx_start_all_queues(dev);
193
194 EXIT();
195 return 0;
196}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530197
198int hdd_hostapd_open (struct net_device *dev)
199{
200 int ret;
201
202 vos_ssr_protect(__func__);
203 ret = __hdd_hostapd_open(dev);
204 vos_ssr_unprotect(__func__);
205
206 return ret;
207}
208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209/**---------------------------------------------------------------------------
210
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530211 \brief __hdd_hostapd_stop() - HDD stop function for hostapd interface
Jeff Johnson295189b2012-06-20 16:38:30 -0700212
213 This is called in response to ifconfig down
214
215 \param - dev Pointer to net_device structure
216
217 \return - 0 for success non-zero for failure
218
219 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530220int __hdd_hostapd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700221{
222 ENTER();
223
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +0530224 if(NULL != dev) {
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530225 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +0530226 //Stop all tx queues
227 netif_tx_disable(dev);
228
229 //Turn OFF carrier state
230 netif_carrier_off(dev);
231 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700232
233 EXIT();
234 return 0;
235}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530236
237int hdd_hostapd_stop (struct net_device *dev)
238{
239 int ret;
240
241 vos_ssr_protect(__func__);
242 ret = __hdd_hostapd_stop(dev);
243 vos_ssr_unprotect(__func__);
244
245 return ret;
246}
247
Jeff Johnson295189b2012-06-20 16:38:30 -0700248/**---------------------------------------------------------------------------
249
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530250 \brief __hdd_hostapd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -0700251
252 This is called during the netdev unregister to uninitialize all data
253associated with the device
254
255 \param - dev Pointer to net_device structure
256
257 \return - void
258
259 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530260static void __hdd_hostapd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700261{
262 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
263
264 ENTER();
265
266 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
267 {
268 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
269
270 /* after uninit our adapter structure will no longer be valid */
271 pHostapdAdapter->dev = NULL;
272 }
273
274 EXIT();
275}
276
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530277static void hdd_hostapd_uninit (struct net_device *dev)
278{
279 vos_ssr_protect(__func__);
280 __hdd_hostapd_uninit(dev);
281 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700282
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530283 return;
284}
Jeff Johnson295189b2012-06-20 16:38:30 -0700285/**============================================================================
286 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
287 transmitting packets. There are 2 versions of this function. One that uses
288 locked queue and other that uses lockless queues. Both have been retained to
289 do some performance testing
290 @param skb : [in] pointer to OS packet (sk_buff)
291 @param dev : [in] pointer to Libra network device
292
293 @return : NET_XMIT_DROP if packets are dropped
294 : NET_XMIT_SUCCESS if packet is enqueued succesfully
295 ===========================================================================*/
296int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
297{
298 return 0;
299}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530300
301int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
Jeff Johnson295189b2012-06-20 16:38:30 -0700302{
303 return 0;
304}
305
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530306int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
307{
308 int ret;
309 vos_ssr_protect(__func__);
310 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
311 vos_ssr_unprotect(__func__);
312
313 return ret;
314}
315
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700316static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
317 hdd_priv_data_t *priv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -0700318{
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700319 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530320 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
321 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700322 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530323 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700324 /*
325 * Note that valid pointers are provided by caller
326 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700328 if (priv_data->total_len <= 0 ||
329 priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
330 {
331 /* below we allocate one more byte for command buffer.
332 * To avoid addition overflow total_len should be
333 * smaller than INT_MAX. */
334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
335 __func__, priv_data->total_len);
336 ret = -EFAULT;
337 goto exit;
338 }
Kaushik, Sushant96122442014-10-21 16:40:18 +0530339 status = wlan_hdd_validate_context(pHddCtx);
340
341 if (0 != status)
342 {
343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
344 "%s: HDD context is not valid", __func__);
345 return status;
346 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700347
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700348 /* Allocate +1 for '\0' */
349 command = kmalloc((priv_data->total_len + 1), GFP_KERNEL);
350 if (!command)
351 {
352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__);
353 ret = -ENOMEM;
354 goto exit;
355 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700356
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700357 if (copy_from_user(command, priv_data->buf, priv_data->total_len))
358 {
359 ret = -EFAULT;
360 goto exit;
361 }
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800362
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700363 /* Make sure the command is NUL-terminated */
364 command[priv_data->total_len] = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -0700365
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700366 hddLog(VOS_TRACE_LEVEL_INFO,
367 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700369 if (strncmp(command, "P2P_SET_NOA", 11) == 0)
370 {
371 hdd_setP2pNoa(pAdapter->dev, command);
372 }
373 else if (strncmp(command, "P2P_SET_PS", 10) == 0)
374 {
375 hdd_setP2pOpps(pAdapter->dev, command);
376 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800377#ifdef FEATURE_WLAN_BATCH_SCAN
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700378 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
379 {
380 ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command);
381 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800382#endif
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700383 else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
384 {
385 /*
386 * command should be a string having format
387 * SET_SAP_CHANNEL_LIST <num channels> <channels seperated by spaces>
388 */
389 hddLog(VOS_TRACE_LEVEL_INFO,
390 "%s: Received Command to Set Preferred Channels for SAP",
391 __func__);
Rajeev Kumar8b373292014-01-08 20:36:55 -0800392
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700393 ret = sapSetPreferredChannel(command);
394 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530395 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
396 {
397 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
398 tANI_U8 filterType = 0;
399 tANI_U8 *value;
400 value = command + 9;
401
402 /* Convert the value from ascii to integer */
403 ret = kstrtou8(value, 10, &filterType);
404 if (ret < 0)
405 {
406 /* If the input value is greater than max value of datatype,
407 * then also kstrtou8 fails
408 */
409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
410 "%s: kstrtou8 failed range ", __func__);
411 ret = -EINVAL;
412 goto exit;
413 }
414 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
415 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
416 {
417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
418 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
419 " 2-Sink ", __func__);
420 ret = -EINVAL;
421 goto exit;
422 }
423 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
424 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +0530425 pScanInfo = &pHddCtx->scan_info;
426 if (filterType && pScanInfo != NULL &&
427 pHddCtx->scan_info.mScanPending)
428 {
429 /*Miracast Session started. Abort Scan */
430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
431 "%s, Aborting Scan For Miracast",__func__);
432 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
433 eCSR_SCAN_ABORT_DEFAULT);
434 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530435 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
436 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
437 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700438
Jeff Johnson295189b2012-06-20 16:38:30 -0700439exit:
440 if (command)
441 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700442 kfree(command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700443 }
444 return ret;
445}
446
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700447#ifdef CONFIG_COMPAT
448static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
449 struct ifreq *ifr)
450{
451 struct {
452 compat_uptr_t buf;
453 int used_len;
454 int total_len;
455 } compat_priv_data;
456 hdd_priv_data_t priv_data;
457 int ret = 0;
458
459 /*
460 * Note that pAdapter and ifr have already been verified by caller,
461 * and HDD context has also been validated
462 */
463 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
464 sizeof(compat_priv_data))) {
465 ret = -EFAULT;
466 goto exit;
467 }
468 priv_data.buf = compat_ptr(compat_priv_data.buf);
469 priv_data.used_len = compat_priv_data.used_len;
470 priv_data.total_len = compat_priv_data.total_len;
471 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
472 exit:
473 return ret;
474}
475#else /* CONFIG_COMPAT */
476static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
477 struct ifreq *ifr)
478{
479 /* will never be invoked */
480 return 0;
481}
482#endif /* CONFIG_COMPAT */
483
484static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
485{
486 hdd_priv_data_t priv_data;
487 int ret = 0;
488
489 /*
490 * Note that pAdapter and ifr have already been verified by caller,
491 * and HDD context has also been validated
492 */
493 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
494 ret = -EFAULT;
495 } else {
496 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
497 }
498 return ret;
499}
500
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530501static int __hdd_hostapd_ioctl(struct net_device *dev,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700502 struct ifreq *ifr, int cmd)
503{
504 hdd_adapter_t *pAdapter;
505 hdd_context_t *pHddCtx;
506 int ret;
507
508 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
509 if (NULL == pAdapter) {
510 hddLog(VOS_TRACE_LEVEL_ERROR,
511 "%s: HDD adapter context is Null", __func__);
512 ret = -ENODEV;
513 goto exit;
514 }
515 if (dev != pAdapter->dev) {
516 hddLog(VOS_TRACE_LEVEL_ERROR,
517 "%s: HDD adapter/dev inconsistency", __func__);
518 ret = -ENODEV;
519 goto exit;
520 }
521
522 if ((!ifr) || (!ifr->ifr_data)) {
523 ret = -EINVAL;
524 goto exit;
525 }
526
527 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
528 ret = wlan_hdd_validate_context(pHddCtx);
529 if (ret) {
530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__);
531 ret = -EBUSY;
532 goto exit;
533 }
534
535 switch (cmd) {
536 case (SIOCDEVPRIVATE + 1):
537 if (is_compat_task())
538 ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
539 else
540 ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
541 break;
542 default:
543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
544 __func__, cmd);
545 ret = -EINVAL;
546 break;
547 }
548 exit:
549 return ret;
550}
551
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530552static int hdd_hostapd_ioctl(struct net_device *dev,
553 struct ifreq *ifr, int cmd)
554{
555 int ret;
556
557 vos_ssr_protect(__func__);
558 ret = __hdd_hostapd_ioctl(dev, ifr, cmd);
559 vos_ssr_unprotect(__func__);
560
561 return ret;
562}
563
Jeff Johnson295189b2012-06-20 16:38:30 -0700564/**---------------------------------------------------------------------------
565
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530566 \brief __hdd_hostapd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -0700567 This function sets the user specified mac address using
568 the command ifconfig wlanX hw ether <mac adress>.
569
570 \param - dev - Pointer to the net device.
571 - addr - Pointer to the sockaddr.
572 \return - 0 for success, non zero for failure
573
574 --------------------------------------------------------------------------*/
575
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530576static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -0700577{
578 struct sockaddr *psta_mac_addr = addr;
579 ENTER();
580 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
581 EXIT();
582 return 0;
583}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530584
585static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
586{
587 int ret;
588
589 vos_ssr_protect(__func__);
590 ret = __hdd_hostapd_set_mac_address(dev, addr);
591 vos_ssr_unprotect(__func__);
592
593 return ret;
594}
595
Jeff Johnson295189b2012-06-20 16:38:30 -0700596void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
597{
598 struct net_device *dev = (struct net_device *)usrDataForCallback;
599 v_BYTE_t we_custom_event[64];
600 union iwreq_data wrqu;
601#ifdef DISABLE_CONCURRENCY_AUTOSAVE
602 VOS_STATUS vos_status;
603 hdd_adapter_t *pHostapdAdapter;
604 hdd_ap_ctx_t *pHddApCtx;
605#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
606
607 /* event_name space-delimiter driver_module_name */
608 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
609 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
610 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
611
612 ENTER();
613
Agarwal Ashish51325b52014-06-16 16:50:49 +0530614#ifdef DISABLE_CONCURRENCY_AUTOSAVE
615 if (vos_concurrent_open_sessions_running())
Jeff Johnson295189b2012-06-20 16:38:30 -0700616 {
617 /*
618 This timer routine is going to be called only when AP
619 persona is up.
620 If there are concurrent sessions running we do not want
621 to shut down the Bss.Instead we run the timer again so
622 that if Autosave is enabled next time and other session
623 was down only then we bring down AP
624 */
625 pHostapdAdapter = netdev_priv(dev);
626 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
627 vos_status = vos_timer_start(
628 &pHddApCtx->hdd_ap_inactivity_timer,
629 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
630 * 1000);
631 if (!VOS_IS_STATUS_SUCCESS(vos_status))
632 {
633 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
634 }
635 EXIT();
636 return;
637 }
638#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
639 memset(&we_custom_event, '\0', sizeof(we_custom_event));
640 memcpy(&we_custom_event, autoShutEvent, event_len);
641
642 memset(&wrqu, 0, sizeof(wrqu));
643 wrqu.data.length = event_len;
644
645 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
646 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
647
648 EXIT();
649}
650
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800651VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
652{
653 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
654 ptSapContext pSapCtx = NULL;
655 eHalStatus halStatus = eHAL_STATUS_FAILURE;
656 v_PVOID_t hHal = NULL;
657
658 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
659 "%s: UPDATE Beacon Params", __func__);
660
661 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
662 pSapCtx = VOS_GET_SAP_CB(pVosContext);
663 if ( NULL == pSapCtx )
664 {
665 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
666 "%s: Invalid SAP pointer from pvosGCtx", __func__);
667 return VOS_STATUS_E_FAULT;
668 }
669
670 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
671 if ( NULL == hHal ){
672 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
673 "%s: Invalid HAL pointer from pvosGCtx", __func__);
674 return VOS_STATUS_E_FAULT;
675 }
676 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
677 if(halStatus == eHAL_STATUS_FAILURE ){
678 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
679 "%s: Failed to update Beacon Params", __func__);
680 return VOS_STATUS_E_FAILURE;
681 }
682 }
683 return VOS_STATUS_SUCCESS;
684}
685
686void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
687{
688 v_U8_t staId = 0;
689 struct net_device *dev;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530690 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
691 ptSapContext pSapCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800692
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530693 dev = (struct net_device *)usrDataForCallback;
694 pSapCtx = VOS_GET_SAP_CB(pVosContext);
695 if(pSapCtx == NULL){
696 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
697 FL("psapCtx is NULL"));
698 return;
699 }
Arif Hussain6d2a3322013-11-17 19:50:10 -0800700 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800701 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
702 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530703 if ( pSapCtx->aStaInfo[staId].isUsed &&
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800704 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
705 {
706 //Disconnect all the stations
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530707 hdd_softap_sta_disassoc(pHostapdAdapter, &pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800708 }
709 }
710}
711
712static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
713{
714 struct net_device *dev;
Agarwal Ashish51325b52014-06-16 16:50:49 +0530715 hdd_context_t *pHddCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800716 VOS_STATUS status = VOS_STATUS_SUCCESS;
717 dev = (struct net_device *)usrDataForCallback;
718 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +0530719
720 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
721 status = wlan_hdd_validate_context(pHddCtx);
722
723 if (0 != status) {
724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
725 return status;
726 }
727
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800728 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
729 {
730 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
731 {
732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
733 }
734 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +0530735 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800736 }
737 EXIT();
738 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
739}
Jeff Johnson295189b2012-06-20 16:38:30 -0700740
741VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
742{
743 hdd_adapter_t *pHostapdAdapter;
744 hdd_ap_ctx_t *pHddApCtx;
745 hdd_hostapd_state_t *pHostapdState;
746 struct net_device *dev;
747 eSapHddEvent sapEvent;
748 union iwreq_data wrqu;
749 v_BYTE_t *we_custom_event_generic = NULL;
750 int we_event = 0;
751 int i = 0;
752 v_U8_t staId;
753 VOS_STATUS vos_status;
754 v_BOOL_t bWPSState;
755 v_BOOL_t bApActive = FALSE;
756 v_BOOL_t bAuthRequired = TRUE;
757 tpSap_AssocMacAddr pAssocStasArray = NULL;
758 char unknownSTAEvent[IW_CUSTOM_MAX+1];
759 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
760 v_BYTE_t we_custom_start_event[64];
761 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800762 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800763 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700764 struct iw_michaelmicfailure msg;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530765 v_CONTEXT_t pVosContext = NULL;
766 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700767
768 dev = (struct net_device *)usrDataForCallback;
769 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530770
771 if ((NULL == pHostapdAdapter) ||
772 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
773 {
774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
775 "invalid adapter or adapter has invalid magic");
776 return eHAL_STATUS_FAILURE;
777 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530778 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
779 pSapCtx = VOS_GET_SAP_CB(pVosContext);
780 if(pSapCtx == NULL){
781 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
782 FL("psapCtx is NULL"));
783 return eHAL_STATUS_FAILURE;
784 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
786 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
787 sapEvent = pSapEvent->sapHddEventCode;
788 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800789 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700790
791 switch(sapEvent)
792 {
793 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800794 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
796 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
797 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
798
799 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
800 vos_status = vos_event_set(&pHostapdState->vosEvent);
801
802 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
803 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 goto stopbss;
806 }
807 else
808 {
809 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
810 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530811 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
812 if (!VOS_IS_STATUS_SUCCESS(vos_status))
813 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
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 :
c_hpothuffdb5272013-10-02 16:42:35 +05301160 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1161 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1162 {
1163 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1164 }
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;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001468
1469 /* Basic sanity */
1470 if ((NULL == pAdapter) || (NULL == indParam))
1471 {
1472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1473 "%s : Invalid arguments", __func__);
1474 return;
1475 }
1476
1477 hddCtxt = (hdd_context_t *)pAdapter;
1478 chAvoidInd = (tSirChAvoidIndType *)indParam;
1479 pVosContext = hddCtxt->pvosContext;
1480
1481 /* Make unsafe channel list */
1482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1483 "%s : band count %d",
1484 __func__, chAvoidInd->avoidRangeCount);
1485 vos_mem_zero((void *)unsafeChannelList,
1486 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1487 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1488 {
1489 startChannel = hdd_hostapd_freq_to_chn(
1490 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1491 endChannel = hdd_hostapd_freq_to_chn(
1492 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1494 "%s : start %d : %d, end %d : %d",
1495 __func__,
1496 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1497 startChannel,
1498 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1499 endChannel);
1500 for (channelLoop = startChannel;
1501 channelLoop < (endChannel + 1);
1502 channelLoop++)
1503 {
1504 /* Channel duplicate check routine */
1505 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1506 {
1507 if (unsafeChannelList[dupCheck] == channelLoop)
1508 {
1509 /* This channel is duplicated */
1510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1511 "%s : found duplicated channel %d",
1512 __func__, channelLoop);
1513 break;
1514 }
1515 }
1516 if (dupCheck == unsafeChannelCount)
1517 {
c_hpothu8de53e42014-08-22 15:00:37 +05301518 int ii;
1519 for(ii=0; ii<NUM_20MHZ_RF_CHANNELS; ii++)
1520 {
1521 if (channelLoop == safeChannels[ii].channelNumber)
1522 {
1523 unsafeChannelList[unsafeChannelCount] = channelLoop;
1524 unsafeChannelCount++;
1525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1526 "%s : unsafe channel %d, count %d",
1527 __func__,
1528 channelLoop, unsafeChannelCount);
1529 }
1530 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001531 }
1532 else
1533 {
1534 /* DUP, do nothing */
1535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1536 "%s : duplicated channel %d",
1537 __func__, channelLoop);
1538 }
1539 }
1540 }
1541 /* Update unsafe channel cache
1542 * WCN Platform Driver cache */
1543 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1544 unsafeChannelCount);
1545
1546 /* Store into local cache
1547 * Start with STA and later start SAP
1548 * in this scenario, local cache will be used */
1549 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1550 unsafeChannelList,
1551 unsafeChannelCount);
1552
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001553 /* generate vendor specific event */
1554 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1555 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1556 {
1557 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1558 chAvoidInd->avoidFreqRange[i].startFreq;
1559 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1560 chAvoidInd->avoidFreqRange[i].endFreq;
1561 }
1562 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1563
1564 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1565
Leo Chang0b0e45a2013-12-15 15:18:55 -08001566 /* Get SAP context first
1567 * SAP and P2PGO would not concurrent */
1568 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +05301569 if ((pHostapdAdapter) &&
1570 (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) &&
1571 (unsafeChannelCount))
Leo Chang0b0e45a2013-12-15 15:18:55 -08001572 {
1573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1574 "%s : Current operation channel %d",
1575 __func__,
1576 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1577 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1578 {
1579 if (((unsafeChannelList[channelLoop] ==
1580 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1581 (AUTO_CHANNEL_SELECT ==
1582 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1583 {
1584 /* current operating channel is un-safe channel
1585 * restart driver */
1586 hdd_hostapd_stop(pHostapdAdapter->dev);
Neelansh Mittaledafed22014-09-04 18:54:39 +05301587 /* On LE, this event is handled by wlan-services to restart SAP.
1588 On android, this event would be ignored. */
1589 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND, NULL, 0);
Leo Chang0b0e45a2013-12-15 15:18:55 -08001590 break;
1591 }
1592 }
1593 }
1594
1595 return;
1596}
1597
1598#endif /* FEATURE_WLAN_CH_AVOID */
1599
Jeff Johnson295189b2012-06-20 16:38:30 -07001600int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301601static __iw_softap_setparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 struct iw_request_info *info,
1603 union iwreq_data *wrqu, char *extra)
1604{
1605 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001606 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 int *value = (int *)extra;
1608 int sub_cmd = value[0];
1609 int set_value = value[1];
1610 eHalStatus status;
1611 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001612 v_CONTEXT_t pVosContext;
1613
1614 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1615 {
1616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1617 "%s: either hostapd Adapter is null or HDD ctx is null",
1618 __func__);
1619 return -1;
1620 }
1621
1622 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1623 if (!hHal)
1624 {
1625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1626 "%s: Hal ctx is null", __func__);
1627 return -1;
1628 }
1629
1630 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1631 if (!pVosContext)
1632 {
1633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1634 "%s: Vos ctx is null", __func__);
1635 return -1;
1636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001637
1638 switch(sub_cmd)
1639 {
1640
1641 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001642 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 {
1644 ret = -EIO;
1645 }
1646 break;
1647
1648 case QCSAP_PARAM_ACL_MODE:
1649 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1650 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1651 {
1652 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1653 ret = -EINVAL;
1654 }
1655 else
1656 {
1657 WLANSAP_SetMode(pVosContext, set_value);
1658 }
1659 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301660
1661 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1662 if ((0 != set_value) && (1 != set_value))
1663 {
1664 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1665 ret = -EINVAL;
1666 }
1667 else
1668 {
1669 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1670 }
1671 break;
1672
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 case QCSAP_PARAM_MAX_ASSOC:
1674 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1675 {
1676 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1677 ret = -EINVAL;
1678 }
1679 else
1680 {
1681 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1682 {
1683 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1684 "Setting it to max allowed and continuing"),
1685 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1686 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1687 }
1688 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1689 set_value, NULL, eANI_BOOLEAN_FALSE);
1690 if ( status != eHAL_STATUS_SUCCESS )
1691 {
1692 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1693 status);
1694 ret = -EIO;
1695 }
1696 }
1697 break;
1698
1699 case QCSAP_PARAM_HIDE_SSID:
1700 {
1701 eHalStatus status = eHAL_STATUS_SUCCESS;
1702 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1703 if(eHAL_STATUS_SUCCESS != status)
1704 {
1705 hddLog(VOS_TRACE_LEVEL_ERROR,
1706 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001707 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001708 return status;
1709 }
1710 break;
1711 }
1712
Leo Chang614d2072013-08-22 14:59:44 -07001713 case QCSAP_PARAM_SET_MC_RATE:
1714 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001715 tSirRateUpdateInd *rateUpdate;
1716
1717 rateUpdate = (tSirRateUpdateInd *)
1718 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1719 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001720 {
1721 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001722 "%s: SET_MC_RATE indication alloc fail", __func__);
1723 ret = -1;
1724 break;
1725 }
1726 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1727
1728 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1729 /* Ignore unicast */
1730 rateUpdate->ucastDataRate = -1;
1731 rateUpdate->mcastDataRate24GHz = set_value;
1732 rateUpdate->mcastDataRate5GHz = set_value;
1733 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1734 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1735 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1736 if (eHAL_STATUS_SUCCESS != status)
1737 {
1738 hddLog(VOS_TRACE_LEVEL_ERROR,
1739 "%s: SET_MC_RATE failed", __func__);
1740 vos_mem_free(rateUpdate);
1741 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001742 }
1743 break;
1744 }
1745
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 default:
1747 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1748 sub_cmd, set_value);
1749 ret = -EINVAL;
1750 break;
1751 }
1752
1753 return ret;
1754}
1755
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301756int
1757static iw_softap_setparam(struct net_device *dev,
1758 struct iw_request_info *info,
1759 union iwreq_data *wrqu, char *extra)
1760{
1761 int ret;
1762
1763 vos_ssr_protect(__func__);
1764 ret = __iw_softap_setparam(dev, info, wrqu, extra);
1765 vos_ssr_unprotect(__func__);
1766
1767 return ret;
1768}
Jeff Johnson295189b2012-06-20 16:38:30 -07001769
1770int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301771static __iw_softap_getparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 struct iw_request_info *info,
1773 union iwreq_data *wrqu, char *extra)
1774{
1775 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1776 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Girish Gowli385be612014-09-18 11:17:20 +05301777 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001778 int *value = (int *)extra;
1779 int sub_cmd = value[0];
1780 eHalStatus status;
1781 int ret = 0; /* success */
1782 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1783
1784 switch (sub_cmd)
1785 {
1786 case QCSAP_PARAM_MAX_ASSOC:
1787 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1788 if (eHAL_STATUS_SUCCESS != status)
1789 {
c_hpothuffdb5272013-10-02 16:42:35 +05301790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 ret = -EIO;
1793 }
Girish Gowli385be612014-09-18 11:17:20 +05301794
1795#ifdef WLAN_SOFTAP_VSTA_FEATURE
1796 if (pHddCtx->cfg_ini->fEnableVSTASupport)
1797 {
1798 if (*value > VSTA_NUM_ASSOC_STA)
1799 {
1800 *value = VSTA_NUM_ASSOC_STA;
1801 }
1802 if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) &&
1803 (*value > (VSTA_NUM_ASSOC_STA -
1804 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA))))
1805 {
1806 *value = (VSTA_NUM_ASSOC_STA -
1807 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA));
1808 }
1809 }
1810 else
1811#endif
1812 {
1813 if (*value > NUM_ASSOC_STA)
1814 {
1815 *value = NUM_ASSOC_STA;
1816 }
1817 if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) &&
1818 (*value > (NUM_ASSOC_STA -
1819 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA))))
1820 {
1821 *value = (NUM_ASSOC_STA -
1822 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA));
1823 }
1824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 break;
1826
1827 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001828 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001829 {
c_hpothuffdb5272013-10-02 16:42:35 +05301830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1831 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001832 ret = -EIO;
1833 }
1834 *value = 0;
1835 break;
1836
Jeff Johnson43971f52012-07-17 12:26:56 -07001837 case QCSAP_PARAM_GET_WLAN_DBG:
1838 {
1839 vos_trace_display();
1840 *value = 0;
1841 break;
1842 }
1843
1844 case QCSAP_PARAM_AUTO_CHANNEL:
1845 {
1846 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1847 break;
1848 }
1849
Jeff Johnson295189b2012-06-20 16:38:30 -07001850 default:
1851 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1852 ret = -EINVAL;
1853 break;
1854
1855 }
1856
1857 return ret;
1858}
1859
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301860int
1861static iw_softap_getparam(struct net_device *dev,
1862 struct iw_request_info *info,
1863 union iwreq_data *wrqu, char *extra)
1864{
1865 int ret;
1866
1867 vos_ssr_protect(__func__);
1868 ret = __iw_softap_getparam(dev, info, wrqu, extra);
1869 vos_ssr_unprotect(__func__);
1870
1871 return ret;
1872}
Jeff Johnson295189b2012-06-20 16:38:30 -07001873/* Usage:
1874 BLACK_LIST = 0
1875 WHITE_LIST = 1
1876 ADD MAC = 0
1877 REMOVE MAC = 1
1878
1879 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1880 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1881 while using this ioctl
1882
1883 Syntax:
1884 iwpriv softap.0 modify_acl
1885 <6 octet mac addr> <list type> <cmd type>
1886
1887 Examples:
1888 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1889 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1890 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1891 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1892*/
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301893int __iw_softap_modify_acl(struct net_device *dev,
1894 struct iw_request_info *info,
1895 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001896{
1897 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1898 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1899 v_BYTE_t *value = (v_BYTE_t*)extra;
1900 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1901 int listType, cmd, i;
1902 int ret = 0; /* success */
1903
1904 ENTER();
1905 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1906 {
1907 pPeerStaMac[i] = *(value+i);
1908 }
1909 listType = (int)(*(value+i));
1910 i++;
1911 cmd = (int)(*(value+i));
1912
Arif Hussain24bafea2013-11-15 15:10:03 -08001913 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1914 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001915
1916 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1917 != VOS_STATUS_SUCCESS)
1918 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001919 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001920 ret = -EIO;
1921 }
1922 EXIT();
1923 return ret;
1924}
1925
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301926int iw_softap_modify_acl(struct net_device *dev,
1927 struct iw_request_info *info,
1928 union iwreq_data *wrqu, char *extra)
1929{
1930 int ret;
1931
1932 vos_ssr_protect(__func__);
1933 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
1934 vos_ssr_unprotect(__func__);
1935
1936 return ret;
1937}
1938
Jeff Johnson295189b2012-06-20 16:38:30 -07001939int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301940static __iw_softap_getchannel(struct net_device *dev,
1941 struct iw_request_info *info,
1942 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001943{
1944 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1945
Jeff Johnson43971f52012-07-17 12:26:56 -07001946 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001947
Jeff Johnson43971f52012-07-17 12:26:56 -07001948 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 return 0;
1950}
1951
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301952
Jeff Johnsone7245742012-09-05 17:12:55 -07001953int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301954static iw_softap_getchannel(struct net_device *dev,
1955 struct iw_request_info *info,
1956 union iwreq_data *wrqu, char *extra)
1957{
1958 int ret;
1959
1960 vos_ssr_protect(__func__);
1961 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
1962 vos_ssr_unprotect(__func__);
1963
1964 return ret;
1965}
1966
1967int
1968static __iw_softap_set_max_tx_power(struct net_device *dev,
1969 struct iw_request_info *info,
1970 union iwreq_data *wrqu, char *extra)
Jeff Johnsone7245742012-09-05 17:12:55 -07001971{
1972 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1973 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001974 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001975 int set_value;
1976 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1977 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1978
schang86c22c42013-03-13 18:41:24 -07001979 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001980 return -ENOMEM;
1981
Leo Changd37675a2013-08-01 13:19:45 -07001982 /* Assign correct slef MAC address */
1983 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1984 VOS_MAC_ADDR_SIZE);
1985 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1986 VOS_MAC_ADDR_SIZE);
1987
schang86c22c42013-03-13 18:41:24 -07001988 set_value = value[0];
1989 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1990 {
1991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001992 __func__);
schang86c22c42013-03-13 18:41:24 -07001993 return -EIO;
1994 }
1995
1996 return 0;
1997}
1998
1999int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302000static iw_softap_set_max_tx_power(struct net_device *dev,
2001 struct iw_request_info *info,
2002 union iwreq_data *wrqu, char *extra)
2003{
2004 int ret;
2005
2006 vos_ssr_protect(__func__);
2007 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
2008 vos_ssr_unprotect(__func__);
2009
2010 return ret;
2011}
2012
2013
2014int
2015static __iw_display_data_path_snapshot(struct net_device *dev,
2016 struct iw_request_info *info,
2017 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05302018{
2019
2020 /* Function intitiating dumping states of
2021 * HDD(WMM Tx Queues)
2022 * TL State (with Per Client infor)
2023 * DXE Snapshot (Called at the end of TL Snapshot)
2024 */
2025 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2026 hddLog(LOGE, "%s: called for SAP",__func__);
2027 hdd_wmm_tx_snapshot(pHostapdAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +05302028 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05302029 return 0;
2030}
2031
2032int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302033static iw_display_data_path_snapshot(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_display_data_path_snapshot(dev, info, wrqu, extra);
2041 vos_ssr_unprotect(__func__);
2042
2043 return ret;
2044}
2045
2046int
2047static __iw_softap_set_tx_power(struct net_device *dev,
2048 struct iw_request_info *info,
2049 union iwreq_data *wrqu, char *extra)
schang86c22c42013-03-13 18:41:24 -07002050{
2051 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2052 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2053 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2054 int *value = (int *)extra;
2055 int set_value;
2056 ptSapContext pSapCtx = NULL;
2057
2058 if (NULL == value)
2059 return -ENOMEM;
2060
2061 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2062 if (NULL == pSapCtx)
2063 {
2064 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2065 "%s: Invalid SAP pointer from pvosGCtx", __func__);
2066 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07002067 }
2068
2069 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07002070 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07002071 {
schang86c22c42013-03-13 18:41:24 -07002072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07002073 __func__);
2074 return -EIO;
2075 }
2076
2077 return 0;
2078}
2079
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302080int
2081static iw_softap_set_tx_power(struct net_device *dev,
2082 struct iw_request_info *info,
2083 union iwreq_data *wrqu, char *extra)
2084{
2085 int ret;
2086
2087 vos_ssr_protect(__func__);
2088 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
2089 vos_ssr_unprotect(__func__);
2090
2091 return ret;
2092}
2093
Kiet Lambcf38522013-10-26 18:28:27 +05302094/**---------------------------------------------------------------------------
2095
2096 \brief iw_softap_set_trafficmonitor() -
2097 This function dynamically enable/disable traffic monitor functonality
2098 the command iwpriv wlanX setTrafficMon <value>.
2099
2100 \param - dev - Pointer to the net device.
2101 - addr - Pointer to the sockaddr.
2102 \return - 0 for success, non zero for failure
2103
2104 --------------------------------------------------------------------------*/
2105
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302106static int __iw_softap_set_trafficmonitor(struct net_device *dev,
2107 struct iw_request_info *info,
2108 union iwreq_data *wrqu, char *extra)
Kiet Lambcf38522013-10-26 18:28:27 +05302109{
2110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik128a0bb2014-08-07 20:24:54 +05302111 int *isSetTrafficMon = (int *)extra;
Kiet Lambcf38522013-10-26 18:28:27 +05302112 hdd_context_t *pHddCtx;
2113 int status;
2114
2115 if (NULL == pAdapter)
2116 {
2117 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2118 "%s: HDD adapter is Null", __func__);
2119 return -ENODEV;
2120 }
2121
2122 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2123
2124 status = wlan_hdd_validate_context(pHddCtx);
2125
2126 if (0 != status)
2127 {
2128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2129 "%s: HDD context is not valid", __func__);
2130 return status;
2131 }
2132
2133 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
2134
2135 if (NULL == isSetTrafficMon)
2136 {
2137 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2138 "%s: Invalid SAP pointer from extra", __func__);
2139 return -ENOMEM;
2140 }
2141
2142 if (TRUE == *isSetTrafficMon)
2143 {
2144 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
2145 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
2146 {
2147 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2148 "%s: failed to Start Traffic Monitor timer ", __func__ );
2149 return -EIO;
2150 }
2151 }
2152 else if (FALSE == *isSetTrafficMon)
2153 {
2154 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
2155 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
2156 {
2157 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2158 "%s: failed to Stop Traffic Monitor timer ", __func__ );
2159 return -EIO;
2160 }
2161
2162 }
2163 return 0;
2164}
2165
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302166static int iw_softap_set_trafficmonitor(struct net_device *dev,
2167 struct iw_request_info *info,
2168 union iwreq_data *wrqu, char *extra)
2169{
2170 int ret;
2171
2172 vos_ssr_protect(__func__);
2173 ret = __iw_softap_set_trafficmonitor(dev, info, wrqu, extra);
2174 vos_ssr_unprotect(__func__);
2175
2176 return ret;
2177}
2178
Jeff Johnson295189b2012-06-20 16:38:30 -07002179#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
2180
2181int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302182static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
2183 struct iw_request_info *info,
2184 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002185{
2186 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302187 hdd_station_info_t *pStaInfo = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002188 char *buf;
2189 int cnt = 0;
2190 int left;
2191 int ret = 0;
2192 /* maclist_index must be u32 to match userspace */
2193 u32 maclist_index;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302194 v_CONTEXT_t pVosContext = NULL;
2195 ptSapContext pSapCtx = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002196 /*
2197 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
2198 * number, and even numbered iocts are supposed to have "set"
2199 * semantics. Hence the wireless extensions support in the kernel
2200 * won't correctly copy the result to userspace, so the ioctl
2201 * handler itself must copy the data. Output format is 32-bit
2202 * record length, followed by 0 or more 6-byte STA MAC addresses.
2203 *
2204 * Further note that due to the incorrect semantics, the "iwpriv"
2205 * userspace application is unable to correctly invoke this API,
2206 * hence it is not registered in the hostapd_private_args. This
2207 * API can only be invoked by directly invoking the ioctl() system
2208 * call.
2209 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002210
Jeff Johnson224f3702014-03-26 11:09:47 -07002211 /* make sure userspace allocated a reasonable buffer size */
2212 if (wrqu->data.length < sizeof(maclist_index)) {
2213 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
2214 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07002215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002216
Jeff Johnson224f3702014-03-26 11:09:47 -07002217 /* allocate local buffer to build the response */
2218 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
2219 if (!buf) {
2220 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
2221 return -ENOMEM;
2222 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302223 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2224 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2225 if(pSapCtx == NULL){
2226 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2227 FL("psapCtx is NULL"));
2228 return -EFAULT;
2229 }
2230 pStaInfo = pSapCtx->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07002231 /* start indexing beyond where the record count will be written */
2232 maclist_index = sizeof(maclist_index);
2233 left = wrqu->data.length - maclist_index;
2234
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302235 spin_lock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002236 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
2237 if ((pStaInfo[cnt].isUsed) &&
2238 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
2239 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
2240 VOS_MAC_ADDR_SIZE);
2241 maclist_index += VOS_MAC_ADDR_SIZE;
2242 left -= VOS_MAC_ADDR_SIZE;
2243 }
2244 cnt++;
2245 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302246 spin_unlock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002247
2248 *((u32 *)buf) = maclist_index;
2249 wrqu->data.length = maclist_index;
2250 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
2251 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
2252 ret = -EFAULT;
2253 }
2254 kfree(buf);
2255 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002256}
2257
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302258int
2259static iw_softap_getassoc_stamacaddr(struct net_device *dev,
2260 struct iw_request_info *info,
2261 union iwreq_data *wrqu, char *extra)
2262{
2263 int ret;
2264
2265 vos_ssr_protect(__func__);
2266 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
2267 vos_ssr_unprotect(__func__);
2268
2269 return ret;
2270}
2271
Jeff Johnson295189b2012-06-20 16:38:30 -07002272/* Usage:
2273 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
2274 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
2275 while using this ioctl
2276
2277 Syntax:
2278 iwpriv softap.0 disassoc_sta <6 octet mac address>
2279
2280 e.g.
2281 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
2282 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
2283*/
2284
2285int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302286static __iw_softap_disassoc_sta(struct net_device *dev,
2287 struct iw_request_info *info,
2288 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002289{
2290 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2291 v_U8_t *peerMacAddr;
2292
2293 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302294 /* iwpriv tool or framework calls this ioctl with
2295 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07002296 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302297 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
Arif Hussain24bafea2013-11-15 15:10:03 -08002299 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
2300 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002301 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
2302 EXIT();
2303 return 0;
2304}
2305
2306int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302307static iw_softap_disassoc_sta(struct net_device *dev,
2308 struct iw_request_info *info,
2309 union iwreq_data *wrqu, char *extra)
2310{
2311 int ret;
2312
2313 vos_ssr_protect(__func__);
2314 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
2315 vos_ssr_unprotect(__func__);
2316
2317 return ret;
2318}
2319
2320int
2321static __iw_softap_ap_stats(struct net_device *dev,
2322 struct iw_request_info *info,
2323 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002324{
2325 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2326 WLANTL_TRANSFER_STA_TYPE statBuffer;
2327 char *pstatbuf;
Girish Gowlif3769802014-06-16 21:17:16 +05302328 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07002329
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002330 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07002331 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
2332 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002333
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302334 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07002335 if(NULL == pstatbuf) {
2336 hddLog(LOG1, "unable to allocate memory");
2337 return -ENOMEM;
2338 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302339
2340 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07002341 "RUF=%d RMF=%d RBF=%d "
2342 "RUB=%d RMB=%d RBB=%d "
2343 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302344 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002345 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2346 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2347 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2348 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2349 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2350 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002351
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302352 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002353 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2354 kfree(pstatbuf);
2355 return -EFAULT;
2356 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302357
2358 strlcpy(extra, pstatbuf, len);
2359 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002360 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 return 0;
2362}
2363
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302364int
2365static iw_softap_ap_stats(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 struct iw_request_info *info,
2367 union iwreq_data *wrqu, char *extra)
2368{
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302369 int ret;
2370
2371 vos_ssr_protect(__func__);
2372 ret = __iw_softap_ap_stats(dev, info, wrqu, extra);
2373 vos_ssr_unprotect(__func__);
2374
2375 return ret;
2376}
2377
2378static int __iw_softap_set_channel_range(struct net_device *dev,
2379 struct iw_request_info *info,
2380 union iwreq_data *wrqu, char *extra)
2381{
Jeff Johnson295189b2012-06-20 16:38:30 -07002382 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2383 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002384 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002385
2386 int *value = (int *)extra;
2387 int startChannel = value[0];
2388 int endChannel = value[1];
2389 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002390 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002391 int ret = 0; /* success */
2392
2393 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2394 if(status != VOS_STATUS_SUCCESS)
2395 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002396 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002397 startChannel,endChannel, band);
2398 ret = -EINVAL;
2399 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002400
2401 pHddCtx->is_dynamic_channel_range_set = 1;
2402
Jeff Johnson295189b2012-06-20 16:38:30 -07002403 return ret;
2404}
2405
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302406static int iw_softap_set_channel_range(struct net_device *dev,
2407 struct iw_request_info *info,
2408 union iwreq_data *wrqu, char *extra)
2409{
2410 int ret;
2411
2412 vos_ssr_protect(__func__);
2413 ret = __iw_softap_set_channel_range(dev, info, wrqu, extra);
2414 vos_ssr_unprotect(__func__);
2415
2416 return ret;
2417}
2418
2419
2420int __iw_softap_get_channel_list(struct net_device *dev,
2421 struct iw_request_info *info,
2422 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002423{
2424 v_U32_t num_channels = 0;
2425 v_U8_t i = 0;
2426 v_U8_t bandStartChannel = RF_CHAN_1;
2427 v_U8_t bandEndChannel = RF_CHAN_165;
2428 v_U32_t temp_num_channels = 0;
2429 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2430 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2431 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002432 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002433 eCsrBand curBand = eCSR_BAND_ALL;
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302434 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002435
2436 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2437 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002438 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002439 return -EIO;
2440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002441 wrqu->data.length = sizeof(tChannelListInfo);
2442 ENTER();
2443
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002444 if (eCSR_BAND_24 == curBand)
2445 {
2446 bandStartChannel = RF_CHAN_1;
2447 bandEndChannel = RF_CHAN_14;
2448 }
2449 else if (eCSR_BAND_5G == curBand)
2450 {
2451 bandStartChannel = RF_CHAN_36;
2452 bandEndChannel = RF_CHAN_165;
2453 }
2454
Arif Hussain6d2a3322013-11-17 19:50:10 -08002455 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302456 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002457 bandStartChannel, bandEndChannel );
2458
Jeff Johnson295189b2012-06-20 16:38:30 -07002459 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2460 {
2461 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2462 {
2463 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2464 num_channels++;
2465 }
2466 }
2467
2468 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2469
2470 temp_num_channels = num_channels;
2471
2472 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2473 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302474 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002475 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002476 }
2477
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302478 if(REGDOMAIN_FCC == domainIdCurrentSoftap &&
2479 pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC )
Jeff Johnson295189b2012-06-20 16:38:30 -07002480 {
2481 for(i = 0; i < temp_num_channels; i++)
2482 {
2483
2484 if((channel_list->channels[i] > 35) &&
2485 (channel_list->channels[i] < 49))
2486 {
2487 vos_mem_move(&channel_list->channels[i],
2488 &channel_list->channels[i+1],
2489 temp_num_channels - (i-1));
2490 num_channels--;
2491 temp_num_channels--;
2492 i--;
2493 }
2494 }
2495 }
2496
Arif Hussain6d2a3322013-11-17 19:50:10 -08002497 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002498
2499 if (num_channels > IW_MAX_FREQUENCIES)
2500 {
2501 num_channels = IW_MAX_FREQUENCIES;
2502 }
2503
2504 channel_list->num_channels = num_channels;
2505 EXIT();
2506
2507 return 0;
2508}
2509
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302510int iw_softap_get_channel_list(struct net_device *dev,
2511 struct iw_request_info *info,
2512 union iwreq_data *wrqu, char *extra)
2513{
2514 int ret;
2515
2516 vos_ssr_protect(__func__);
2517 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
2518 vos_ssr_unprotect(__func__);
2519
2520 return ret;
2521}
2522
2523static
2524int __iw_get_genie(struct net_device *dev,
2525 struct iw_request_info *info,
2526 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002527{
2528 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2529 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2530 eHalStatus status;
2531 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2532 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2533 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002534 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002535 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2536 status = WLANSap_getstationIE_information(pVosContext,
2537 &length,
2538 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002539 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2540 if (wrqu->data.length < length ||
2541 copy_to_user(wrqu->data.pointer,
2542 (v_VOID_t*)genIeBytes, length))
2543 {
2544 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2545 return -EFAULT;
2546 }
2547 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002548
Arif Hussain6d2a3322013-11-17 19:50:10 -08002549 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002550
2551
2552 EXIT();
2553 return 0;
2554}
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302555
2556static
2557int iw_get_genie(struct net_device *dev,
2558 struct iw_request_info *info,
2559 union iwreq_data *wrqu, char *extra)
2560{
2561 int ret;
2562
2563 vos_ssr_protect(__func__);
2564 ret = __iw_get_genie(dev, info, wrqu, extra);
2565 vos_ssr_unprotect(__func__);
2566
2567 return ret;
2568}
2569
2570static
2571int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2572 struct iw_request_info *info,
2573 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002574{
2575 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002576 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002577 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2578 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002579
Arif Hussain6d2a3322013-11-17 19:50:10 -08002580 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002581 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2582
2583 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2584 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2585 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2586 WPSPBCProbeReqIEs.probeReqIELen);
2587 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2588 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2589 sizeof(v_MACADDR_t));
2590 if (copy_to_user(wrqu->data.pointer,
2591 (void *)&WPSPBCProbeReqIEs,
2592 sizeof(WPSPBCProbeReqIEs)))
2593 {
2594 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2595 return -EFAULT;
2596 }
2597 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002598 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002599 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002600 up(&pHddApCtx->semWpsPBCOverlapInd);
2601 EXIT();
2602 return 0;
2603}
2604
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302605static
2606int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2607 struct iw_request_info *info,
2608 union iwreq_data *wrqu, char *extra)
2609{
2610 int ret;
2611
2612 vos_ssr_protect(__func__);
2613 ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra);
2614 vos_ssr_unprotect(__func__);
2615
2616 return ret;
2617}
2618
Jeff Johnson295189b2012-06-20 16:38:30 -07002619/**---------------------------------------------------------------------------
2620
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302621 \brief __iw_set_auth_hostap() -
Jeff Johnson295189b2012-06-20 16:38:30 -07002622 This function sets the auth type received from the wpa_supplicant.
2623
2624 \param - dev - Pointer to the net device.
2625 - info - Pointer to the iw_request_info.
2626 - wrqu - Pointer to the iwreq_data.
2627 - extra - Pointer to the data.
2628 \return - 0 for success, non zero for failure
2629
2630 --------------------------------------------------------------------------*/
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302631int __iw_set_auth_hostap(struct net_device *dev,
2632 struct iw_request_info *info,
2633 union iwreq_data *wrqu,char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002634{
2635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2636 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2637
2638 ENTER();
2639 switch(wrqu->param.flags & IW_AUTH_INDEX)
2640 {
2641 case IW_AUTH_TKIP_COUNTERMEASURES:
2642 {
2643 if(wrqu->param.value) {
2644 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2645 "Counter Measure started %d", wrqu->param.value);
2646 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2647 }
2648 else {
2649 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2650 "Counter Measure stopped=%d", wrqu->param.value);
2651 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2652 }
2653
2654 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2655 wrqu->param.value);
2656 }
2657 break;
2658
2659 default:
2660
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002661 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002662 wrqu->param.flags & IW_AUTH_INDEX);
2663 break;
2664 }
2665
2666 EXIT();
2667 return 0;
2668}
2669
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302670int iw_set_auth_hostap(struct net_device *dev,
2671 struct iw_request_info *info,
2672 union iwreq_data *wrqu,char *extra)
2673{
2674 int ret;
2675
2676 vos_ssr_protect(__func__);
2677 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
2678 vos_ssr_unprotect(__func__);
2679
2680 return ret;
2681}
2682
2683static int __iw_set_ap_encodeext(struct net_device *dev,
2684 struct iw_request_info *info,
2685 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002686{
2687 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2688 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2689 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002690 int retval = 0;
2691 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002692 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2693 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2694 int key_index;
2695 struct iw_point *encoding = &wrqu->encoding;
2696 tCsrRoamSetKey setKey;
2697// tCsrRoamRemoveKey RemoveKey;
2698 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002699
Jeff Johnson295189b2012-06-20 16:38:30 -07002700 ENTER();
2701
2702 key_index = encoding->flags & IW_ENCODE_INDEX;
2703
2704 if(key_index > 0) {
2705
2706 /*Convert from 1-based to 0-based keying*/
2707 key_index--;
2708 }
2709 if(!ext->key_len) {
2710#if 0
2711 /*Set the encrytion type to NONE*/
2712#if 0
2713 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2714#endif
2715
2716 RemoveKey.keyId = key_index;
2717 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2718 /*Key direction for group is RX only*/
2719 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2720 }
2721 else {
2722 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2723 }
2724 switch(ext->alg)
2725 {
2726 case IW_ENCODE_ALG_NONE:
2727 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2728 break;
2729 case IW_ENCODE_ALG_WEP:
2730 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2731 break;
2732 case IW_ENCODE_ALG_TKIP:
2733 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002734 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002735 case IW_ENCODE_ALG_CCMP:
2736 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2737 break;
2738 default:
2739 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2740 break;
2741 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002742 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 -07002743 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002745 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002746 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002747 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2748 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 {
2750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002751 __LINE__, vstatus );
2752 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002754#endif
2755 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002756
Jeff Johnson43971f52012-07-17 12:26:56 -07002757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002758
2759 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2760
2761 setKey.keyId = key_index;
2762 setKey.keyLength = ext->key_len;
2763
2764 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2765 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2766 }
2767
2768 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2769 /*Key direction for group is RX only*/
2770 setKey.keyDirection = eSIR_RX_ONLY;
2771 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2772 }
2773 else {
2774
2775 setKey.keyDirection = eSIR_TX_RX;
2776 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2777 }
2778 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2779 {
2780 setKey.keyDirection = eSIR_TX_DEFAULT;
2781 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2782 }
2783
2784 /*For supplicant pae role is zero*/
2785 setKey.paeRole = 0;
2786
2787 switch(ext->alg)
2788 {
2789 case IW_ENCODE_ALG_NONE:
2790 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2791 break;
2792
2793 case IW_ENCODE_ALG_WEP:
2794 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2795 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002796 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 break;
2798
2799 case IW_ENCODE_ALG_TKIP:
2800 {
2801 v_U8_t *pKey = &setKey.Key[0];
2802
2803 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2804
2805 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2806
2807 /*Supplicant sends the 32bytes key in this order
2808
2809 |--------------|----------|----------|
2810 | Tk1 |TX-MIC | RX Mic |
2811 |--------------|----------|----------|
2812 <---16bytes---><--8bytes--><--8bytes-->
2813
2814 */
2815 /*Sme expects the 32 bytes key to be in the below order
2816
2817 |--------------|----------|----------|
2818 | Tk1 |RX-MIC | TX Mic |
2819 |--------------|----------|----------|
2820 <---16bytes---><--8bytes--><--8bytes-->
2821 */
2822 /* Copy the Temporal Key 1 (TK1) */
2823 vos_mem_copy(pKey,ext->key,16);
2824
2825 /*Copy the rx mic first*/
2826 vos_mem_copy(&pKey[16],&ext->key[24],8);
2827
2828 /*Copy the tx mic */
2829 vos_mem_copy(&pKey[24],&ext->key[16],8);
2830
2831 }
2832 break;
2833
2834 case IW_ENCODE_ALG_CCMP:
2835 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2836 break;
2837
2838 default:
2839 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2840 break;
2841 }
2842
2843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302844 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002845 setKey.keyId);
2846 for(i=0; i< ext->key_len; i++)
2847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2848 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002849
2850 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2851 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002854 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2855 retval = -EINVAL;
2856 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002857
Jeff Johnson43971f52012-07-17 12:26:56 -07002858 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002859}
Jeff Johnson43971f52012-07-17 12:26:56 -07002860
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302861static int iw_set_ap_encodeext(struct net_device *dev,
2862 struct iw_request_info *info,
2863 union iwreq_data *wrqu, char *extra)
2864{
2865 int ret;
2866
2867 vos_ssr_protect(__func__);
2868 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
2869 vos_ssr_unprotect(__func__);
2870
2871 return ret;
2872}
Jeff Johnson43971f52012-07-17 12:26:56 -07002873
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05302874static int __iw_set_ap_mlme(struct net_device *dev,
2875 struct iw_request_info *info,
2876 union iwreq_data *wrqu,
2877 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002878{
2879#if 0
2880 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2881 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2882
2883 ENTER();
2884
2885 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2886 switch (mlme->cmd) {
2887 case IW_MLME_DISASSOC:
2888 case IW_MLME_DEAUTH:
2889 hddLog(LOG1, "Station disassociate");
2890 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2891 {
2892 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2893
2894 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2895 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2896
2897 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2898
2899 //clear all the reason codes
2900 if (status != 0)
2901 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002902 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002903 }
2904
2905 netif_stop_queue(dev);
2906 netif_carrier_off(dev);
2907 }
2908 else
2909 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002910 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 -07002911 }
2912 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002913 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002914 return -EINVAL;
2915 }//end of switch
2916 EXIT();
2917#endif
2918 return 0;
2919// return status;
2920}
2921
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05302922static int iw_set_ap_mlme(struct net_device *dev,
2923 struct iw_request_info *info,
2924 union iwreq_data *wrqu,
2925 char *extra)
2926{
2927 int ret;
2928
2929 vos_ssr_protect(__func__);
2930 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
2931 vos_ssr_unprotect(__func__);
2932
2933 return ret;
2934}
2935
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302936static int __iw_get_ap_rts_threshold(struct net_device *dev,
2937 struct iw_request_info *info,
2938 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002939{
2940 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2941 v_U32_t status = 0;
2942
2943 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2944
2945 return status;
2946}
2947
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302948static int iw_get_ap_rts_threshold(struct net_device *dev,
2949 struct iw_request_info *info,
2950 union iwreq_data *wrqu, char *extra)
2951{
2952 int ret;
2953
2954 vos_ssr_protect(__func__);
2955 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
2956 vos_ssr_unprotect(__func__);
2957
2958 return ret;
2959}
2960
2961static int __iw_get_ap_frag_threshold(struct net_device *dev,
2962 struct iw_request_info *info,
2963 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002964{
2965 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2966 v_U32_t status = 0;
2967
2968 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2969
2970 return status;
2971}
2972
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302973static int iw_get_ap_frag_threshold(struct net_device *dev,
2974 struct iw_request_info *info,
2975 union iwreq_data *wrqu, char *extra)
2976{
2977 int ret;
2978
2979 vos_ssr_protect(__func__);
2980 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
2981 vos_ssr_unprotect(__func__);
2982
2983 return ret;
2984}
2985
2986static int __iw_get_ap_freq(struct net_device *dev,
2987 struct iw_request_info *info,
2988 struct iw_freq *fwrq, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002989{
Jeff Johnsone7245742012-09-05 17:12:55 -07002990 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2992 tHalHandle hHal;
2993 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002994 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002995
2996 ENTER();
2997
2998 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3000 "%s:LOGP in Progress. Ignore!!!",__func__);
3001 return status;
3002 }
3003
3004 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3005 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3006
3007 if(pHostapdState->bssState == BSS_STOP )
3008 {
3009 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
3010 != eHAL_STATUS_SUCCESS)
3011 {
c_hpothuffdb5272013-10-02 16:42:35 +05303012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3013 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003014 return -EIO;
3015 }
3016 else
3017 {
3018 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07003019 if( TRUE == status)
3020 {
3021 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
3022 * iwlist & iwconfig command shows frequency into proper
3023 * format (2.412 GHz instead of 246.2 MHz)*/
3024 fwrq->m = freq;
3025 fwrq->e = MHZ;
3026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003027 }
3028 }
3029 else
3030 {
3031 channel = pHddApCtx->operatingChannel;
3032 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07003033 if( TRUE == status)
3034 {
3035 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
3036 * iwlist & iwconfig command shows frequency into proper
3037 * format (2.412 GHz instead of 246.2 MHz)*/
3038 fwrq->m = freq;
3039 fwrq->e = MHZ;
3040 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003041 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003042 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003043}
3044
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303045static int iw_get_ap_freq(struct net_device *dev,
3046 struct iw_request_info *info,
3047 struct iw_freq *fwrq, char *extra)
3048{
3049 int ret;
3050
3051 vos_ssr_protect(__func__);
3052 ret = __iw_get_ap_freq(dev, info, fwrq, extra);
3053 vos_ssr_unprotect(__func__);
3054
3055 return ret;
3056}
3057
3058static int __iw_get_mode(struct net_device *dev,
3059 struct iw_request_info *info,
3060 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303061{
3062 int status = 0;
3063
3064 wrqu->mode = IW_MODE_MASTER;
3065
3066 return status;
3067}
3068
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303069static int iw_get_mode(struct net_device *dev,
3070 struct iw_request_info *info,
3071 union iwreq_data *wrqu, char *extra)
3072{
3073 int ret;
3074
3075 vos_ssr_protect(__func__);
3076 ret = __iw_get_mode(dev, info, wrqu, extra);
3077 vos_ssr_unprotect(__func__);
3078
3079 return ret;
3080}
3081
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303082static int __iw_softap_setwpsie(struct net_device *dev,
3083 struct iw_request_info *info,
3084 union iwreq_data *wrqu,
3085 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003086{
3087 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3088 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3089 hdd_hostapd_state_t *pHostapdState;
3090 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003091 u_int8_t *wps_genie;
3092 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07003093 u_int8_t *pos;
3094 tpSap_WPSIE pSap_WPSIe;
3095 u_int8_t WPSIeType;
3096 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05303097 struct iw_point s_priv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003098 ENTER();
3099
Girish Gowli07c05ec2014-06-17 20:47:03 +05303100 /* helper function to get iwreq_data with compat handling. */
3101 if (hdd_priv_get_data(&s_priv_data, wrqu))
3102 {
3103 return -EINVAL;
3104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003105
Girish Gowli07c05ec2014-06-17 20:47:03 +05303106 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
3107 {
3108 return -EINVAL;
3109 }
3110
3111 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
3112 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07003113
Girish Gowli86c471e2014-06-17 19:28:05 +05303114 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07003115 {
Girish Gowli86c471e2014-06-17 19:28:05 +05303116 hddLog(LOG1, "%s: failed to alloc memory "
3117 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07003118 return -EFAULT;
3119 }
3120
Girish Gowli86c471e2014-06-17 19:28:05 +05303121 fwps_genie = wps_genie;
3122
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
3124 if (NULL == pSap_WPSIe)
3125 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003126 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07003127 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003128 return -ENOMEM;
3129 }
3130 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
3131
Arif Hussain6d2a3322013-11-17 19:50:10 -08003132 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 -07003133 WPSIeType = wps_genie[0];
3134 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
3135 {
3136 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
3137 wps_genie = wps_genie + 1;
3138 switch ( wps_genie[0] )
3139 {
3140 case DOT11F_EID_WPA:
3141 if (wps_genie[1] < 2 + 4)
3142 {
3143 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003144 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003145 return -EINVAL;
3146 }
3147 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3148 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003149 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003150 pos = &wps_genie[6];
3151 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3152 {
3153 switch((u_int16_t)(*pos<<8) | *(pos+1))
3154 {
3155 case HDD_WPS_ELEM_VERSION:
3156 pos += 4;
3157 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003158 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
3160 pos += 1;
3161 break;
3162
3163 case HDD_WPS_ELEM_WPS_STATE:
3164 pos +=4;
3165 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003166 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
3168 pos += 1;
3169 break;
3170 case HDD_WPS_ELEM_APSETUPLOCK:
3171 pos += 4;
3172 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003173 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003174 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
3175 pos += 1;
3176 break;
3177 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3178 pos += 4;
3179 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003180 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003181 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
3182 pos += 1;
3183 break;
3184 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3185 pos += 4;
3186 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003187 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003188 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
3189 pos += 2;
3190 break;
3191 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3192 pos += 4;
3193 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003194 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003195 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
3196 pos += 2;
3197 break;
3198
3199 case HDD_WPS_ELEM_UUID_E:
3200 pos += 2;
3201 length = *pos<<8 | *(pos+1);
3202 pos += 2;
3203 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
3204 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
3205 pos += length;
3206 break;
3207 case HDD_WPS_ELEM_RF_BANDS:
3208 pos += 4;
3209 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003210 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003211 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
3212 pos += 1;
3213 break;
3214
3215 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08003216 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003218 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003219 return -EINVAL;
3220 }
3221 }
3222 }
3223 else {
3224 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003225 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003226 }
3227 break;
3228
3229 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003230 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003231 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003232 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003233 return 0;
3234 }
3235 }
3236 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
3237 {
3238 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
3239 wps_genie = wps_genie + 1;
3240 switch ( wps_genie[0] )
3241 {
3242 case DOT11F_EID_WPA:
3243 if (wps_genie[1] < 2 + 4)
3244 {
3245 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003246 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003247 return -EINVAL;
3248 }
3249 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3250 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003251 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003252 pos = &wps_genie[6];
3253 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3254 {
3255 switch((u_int16_t)(*pos<<8) | *(pos+1))
3256 {
3257 case HDD_WPS_ELEM_VERSION:
3258 pos += 4;
3259 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003260 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003261 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
3262 pos += 1;
3263 break;
3264
3265 case HDD_WPS_ELEM_WPS_STATE:
3266 pos +=4;
3267 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003268 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003269 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
3270 pos += 1;
3271 break;
3272 case HDD_WPS_ELEM_APSETUPLOCK:
3273 pos += 4;
3274 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003275 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003276 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
3277 pos += 1;
3278 break;
3279 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3280 pos += 4;
3281 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003282 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003283 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
3284 pos += 1;
3285 break;
3286 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3287 pos += 4;
3288 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003289 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003290 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
3291 pos += 2;
3292 break;
3293 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3294 pos += 4;
3295 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003296 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003297 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
3298 pos += 2;
3299 break;
3300 case HDD_WPS_ELEM_RSP_TYPE:
3301 pos += 4;
3302 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003303 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07003304 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
3305 pos += 1;
3306 break;
3307 case HDD_WPS_ELEM_UUID_E:
3308 pos += 2;
3309 length = *pos<<8 | *(pos+1);
3310 pos += 2;
3311 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
3312 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
3313 pos += length;
3314 break;
3315
3316 case HDD_WPS_ELEM_MANUFACTURER:
3317 pos += 2;
3318 length = *pos<<8 | *(pos+1);
3319 pos += 2;
3320 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
3321 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
3322 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
3323 pos += length;
3324 break;
3325
3326 case HDD_WPS_ELEM_MODEL_NAME:
3327 pos += 2;
3328 length = *pos<<8 | *(pos+1);
3329 pos += 2;
3330 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
3331 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
3332 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
3333 pos += length;
3334 break;
3335 case HDD_WPS_ELEM_MODEL_NUM:
3336 pos += 2;
3337 length = *pos<<8 | *(pos+1);
3338 pos += 2;
3339 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
3340 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
3341 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
3342 pos += length;
3343 break;
3344 case HDD_WPS_ELEM_SERIAL_NUM:
3345 pos += 2;
3346 length = *pos<<8 | *(pos+1);
3347 pos += 2;
3348 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
3349 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
3350 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
3351 pos += length;
3352 break;
3353 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
3354 pos += 4;
3355 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003356 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003357 pos += 2;
3358
3359 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003360 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003361 pos += 4;
3362 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003363 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003364 pos += 2;
3365 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
3366 break;
3367 case HDD_WPS_ELEM_DEVICE_NAME:
3368 pos += 2;
3369 length = *pos<<8 | *(pos+1);
3370 pos += 2;
3371 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
3372 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
3373 pos += length;
3374 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
3375 break;
3376 case HDD_WPS_ELEM_CONFIG_METHODS:
3377 pos += 4;
3378 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003379 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 pos += 2;
3381 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
3382 break;
3383
3384 case HDD_WPS_ELEM_RF_BANDS:
3385 pos += 4;
3386 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003387 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 pos += 1;
3389 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
3390 break;
3391 } // switch
3392 }
3393 }
3394 else
3395 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003396 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003397 }
3398
3399 } // switch
3400 }
3401 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
3402 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3403 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3404 {
3405 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3406 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3407 WLANSAP_Update_WpsIe ( pVosContext );
3408 }
3409
3410 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003411 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 EXIT();
3413 return halStatus;
3414}
3415
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303416static int iw_softap_setwpsie(struct net_device *dev,
3417 struct iw_request_info *info,
3418 union iwreq_data *wrqu,
3419 char *extra)
3420{
3421 int ret;
3422
3423 vos_ssr_protect(__func__);
3424 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
3425 vos_ssr_unprotect(__func__);
3426
3427 return ret;
3428}
3429
3430static int __iw_softap_stopbss(struct net_device *dev,
3431 struct iw_request_info *info,
3432 union iwreq_data *wrqu,
3433 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003434{
3435 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3436 VOS_STATUS status = VOS_STATUS_SUCCESS;
Agarwal Ashish51325b52014-06-16 16:50:49 +05303437 hdd_context_t *pHddCtx = NULL;
3438
Jeff Johnson295189b2012-06-20 16:38:30 -07003439 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +05303440
3441 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3442 status = wlan_hdd_validate_context(pHddCtx);
3443
3444 if (0 != status) {
3445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
3446 return status;
3447 }
3448
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3450 {
3451 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
3452 {
3453 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3454
3455 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
3456
3457 if (!VOS_IS_STATUS_SUCCESS(status))
3458 {
3459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003460 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003461 VOS_ASSERT(0);
3462 }
3463 }
3464 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05303465 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003466 }
3467 EXIT();
3468 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
3469}
3470
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303471static int iw_softap_stopbss(struct net_device *dev,
3472 struct iw_request_info *info,
3473 union iwreq_data *wrqu,
3474 char *extra)
3475{
3476 int ret;
3477
3478 vos_ssr_protect(__func__);
3479 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
3480 vos_ssr_unprotect(__func__);
3481
3482 return ret;
3483}
3484
3485static int __iw_softap_version(struct net_device *dev,
3486 struct iw_request_info *info,
3487 union iwreq_data *wrqu,
3488 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003489{
Jeff Johnson295189b2012-06-20 16:38:30 -07003490 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003491
Jeff Johnson295189b2012-06-20 16:38:30 -07003492 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003493 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003494 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003495 return 0;
3496}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003497
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303498static int iw_softap_version(struct net_device *dev,
3499 struct iw_request_info *info,
3500 union iwreq_data *wrqu,
3501 char *extra)
3502{
3503 int ret;
3504
3505 vos_ssr_protect(__func__);
3506 ret = __iw_softap_version(dev, info, wrqu, extra);
3507 vos_ssr_unprotect(__func__);
3508
3509 return ret;
3510}
3511
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003512VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003513{
3514 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003515 int len = 0;
3516 const char sta_info_header[] = "staId staAddress\n";
3517
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303518 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3519 ptSapContext pSapCtx = NULL;
3520 pSapCtx = VOS_GET_SAP_CB(pVosContext);
3521 if(pSapCtx == NULL){
3522 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
3523 FL("psapCtx is NULL"));
3524 return VOS_STATUS_E_FAULT;
3525 }
3526
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003527 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003528 pBuf += len;
3529 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003530
3531 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
3532 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303533 if(pSapCtx->aStaInfo[i].isUsed)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003534 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003535 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303536 pSapCtx->aStaInfo[i].ucSTAId,
3537 pSapCtx->aStaInfo[i].macAddrSTA.bytes[0],
3538 pSapCtx->aStaInfo[i].macAddrSTA.bytes[1],
3539 pSapCtx->aStaInfo[i].macAddrSTA.bytes[2],
3540 pSapCtx->aStaInfo[i].macAddrSTA.bytes[3],
3541 pSapCtx->aStaInfo[i].macAddrSTA.bytes[4],
3542 pSapCtx->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003543 pBuf += len;
3544 buf_len -= len;
3545 }
3546 if(WE_GET_STA_INFO_SIZE > buf_len)
3547 {
3548 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003549 }
3550 }
3551 return VOS_STATUS_SUCCESS;
3552}
3553
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05303554static int __iw_softap_get_sta_info(struct net_device *dev,
3555 struct iw_request_info *info,
3556 union iwreq_data *wrqu,
3557 char *extra)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003558{
3559 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3560 VOS_STATUS status;
3561 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003562 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003563 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003565 return -EINVAL;
3566 }
3567 wrqu->data.length = strlen(extra);
3568 EXIT();
3569 return 0;
3570}
3571
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05303572static int iw_softap_get_sta_info(struct net_device *dev,
3573 struct iw_request_info *info,
3574 union iwreq_data *wrqu,
3575 char *extra)
3576{
3577 int ret;
3578
3579 vos_ssr_protect(__func__);
3580 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
3581 vos_ssr_unprotect(__func__);
3582
3583 return ret;
3584}
3585
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303586static int __iw_set_ap_genie(struct net_device *dev,
3587 struct iw_request_info *info,
3588 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003589{
3590
3591 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3592 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3593 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003594 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003595
3596 ENTER();
3597
3598 if(!wrqu->data.length)
3599 {
3600 EXIT();
3601 return 0;
3602 }
Arif Hussained667642013-10-27 23:01:14 -07003603
Jeff Johnson295189b2012-06-20 16:38:30 -07003604 switch (genie[0])
3605 {
3606 case DOT11F_EID_WPA:
3607 case DOT11F_EID_RSN:
3608 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3609 {
3610 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3611 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3612 }
3613 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003614 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003615 break;
3616
3617 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003618 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003619 halStatus = 0;
3620 }
3621
3622 EXIT();
3623 return halStatus;
3624}
3625
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303626static int iw_set_ap_genie(struct net_device *dev,
3627 struct iw_request_info *info,
3628 union iwreq_data *wrqu, char *extra)
3629{
3630 int ret;
3631
3632 vos_ssr_protect(__func__);
3633 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
3634 vos_ssr_unprotect(__func__);
3635
3636 return ret;
3637}
3638
Jeff Johnson295189b2012-06-20 16:38:30 -07003639static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3640{
3641 eHalStatus hstatus;
3642 long lrc;
3643 struct statsContext context;
3644
3645 if (NULL == pAdapter)
3646 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303647 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003648 return VOS_STATUS_E_FAULT;
3649 }
3650
3651 init_completion(&context.completion);
3652 context.pAdapter = pAdapter;
3653 context.magic = STATS_CONTEXT_MAGIC;
3654 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3655 eCSR_HDD,
3656 SME_GLOBAL_CLASSA_STATS,
3657 hdd_GetClassA_statisticsCB,
3658 0, // not periodic
3659 FALSE, //non-cached results
3660 staid,
3661 &context);
3662 if (eHAL_STATUS_SUCCESS != hstatus)
3663 {
3664 hddLog(VOS_TRACE_LEVEL_ERROR,
3665 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003666 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003667 }
3668 else
3669 {
3670 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3671 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 if (lrc <= 0)
3673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR,
3675 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003676 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 }
3678 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003679
3680 /* either we never sent a request, we sent a request and received a
3681 response or we sent a request and timed out. if we never sent a
3682 request or if we sent a request and got a response, we want to
3683 clear the magic out of paranoia. if we timed out there is a
3684 race condition such that the callback function could be
3685 executing at the same time we are. of primary concern is if the
3686 callback function had already verified the "magic" but had not
3687 yet set the completion variable when a timeout occurred. we
3688 serialize these activities by invalidating the magic while
3689 holding a shared spinlock which will cause us to block if the
3690 callback is currently executing */
3691 spin_lock(&hdd_context_lock);
3692 context.magic = 0;
3693 spin_unlock(&hdd_context_lock);
3694
Jeff Johnson295189b2012-06-20 16:38:30 -07003695 return VOS_STATUS_SUCCESS;
3696}
3697
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303698int __iw_get_softap_linkspeed(struct net_device *dev,
3699 struct iw_request_info *info,
3700 union iwreq_data *wrqu,
3701 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003702
3703{
3704 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303705 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003707 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303708 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003709 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303710 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003711 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003712 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303713 int rc, valid;
3714
3715 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3716
3717 valid = wlan_hdd_validate_context(pHddCtx);
3718
3719 if (0 != valid)
3720 {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3722 return valid;
3723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003724
Arif Hussain6d2a3322013-11-17 19:50:10 -08003725 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003726
3727 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003728 {
Arif Hussaina9571842014-01-15 16:43:41 -08003729 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3730 if (NULL == pmacAddress) {
3731 hddLog(LOG1, "unable to allocate memory");
3732 return -ENOMEM;
3733 }
3734 if (copy_from_user((void *)pmacAddress,
3735 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3736 {
3737 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3738 kfree(pmacAddress);
3739 return -EFAULT;
3740 }
3741 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3742
3743 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003744 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003745
3746 if (!VOS_IS_STATUS_SUCCESS(status ))
3747 {
3748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3749 }
Arif Hussained667642013-10-27 23:01:14 -07003750 }
Kiet Lam61589852013-09-19 17:10:58 +05303751 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303752 * link speed for first connected client will be returned.
3753 */
Arif Hussaina9571842014-01-15 16:43:41 -08003754 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303755 {
3756 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3757 }
3758 else
3759 {
3760 status = hdd_softap_GetStaId(pHostapdAdapter,
3761 (v_MACADDR_t *)macAddress, (void *)(&staId));
3762 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003763
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303764 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003765 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003767 link_speed = 0;
3768 }
3769 else
3770 {
3771 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303772
Jeff Johnson295189b2012-06-20 16:38:30 -07003773 if (!VOS_IS_STATUS_SUCCESS(status ))
3774 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003776 return -EINVAL;
3777 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303778
3779 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3780 staId, &link_speed);
3781
3782 link_speed = link_speed / 10;
3783
3784 if (0 == link_speed)
3785 {
3786 /* The linkspeed returned by HAL is in units of 500kbps.
3787 * converting it to mbps.
3788 * This is required to support legacy firmware which does
3789 * not return link capacity.
3790 */
3791 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003793 }
3794
3795 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003796 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303797
Jeff Johnson295189b2012-06-20 16:38:30 -07003798 if ((rc < 0) || (rc >= len))
3799 {
3800 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303801 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003802 return -EIO;
3803 }
3804
3805 return 0;
3806}
3807
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303808int iw_get_softap_linkspeed(struct net_device *dev,
3809 struct iw_request_info *info,
3810 union iwreq_data *wrqu,
3811 char *extra)
3812{
3813 int ret;
3814
3815 vos_ssr_protect(__func__);
3816 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
3817 vos_ssr_unprotect(__func__);
3818
3819 return ret;
3820}
3821
3822
Jeff Johnson295189b2012-06-20 16:38:30 -07003823static const iw_handler hostapd_handler[] =
3824{
3825 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3826 (iw_handler) NULL, /* SIOCGIWNAME */
3827 (iw_handler) NULL, /* SIOCSIWNWID */
3828 (iw_handler) NULL, /* SIOCGIWNWID */
3829 (iw_handler) NULL, /* SIOCSIWFREQ */
3830 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3831 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303832 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003833 (iw_handler) NULL, /* SIOCSIWSENS */
3834 (iw_handler) NULL, /* SIOCGIWSENS */
3835 (iw_handler) NULL, /* SIOCSIWRANGE */
3836 (iw_handler) NULL, /* SIOCGIWRANGE */
3837 (iw_handler) NULL, /* SIOCSIWPRIV */
3838 (iw_handler) NULL, /* SIOCGIWPRIV */
3839 (iw_handler) NULL, /* SIOCSIWSTATS */
3840 (iw_handler) NULL, /* SIOCGIWSTATS */
3841 (iw_handler) NULL, /* SIOCSIWSPY */
3842 (iw_handler) NULL, /* SIOCGIWSPY */
3843 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3844 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3845 (iw_handler) NULL, /* SIOCSIWAP */
3846 (iw_handler) NULL, /* SIOCGIWAP */
3847 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3848 (iw_handler) NULL, /* SIOCGIWAPLIST */
3849 (iw_handler) NULL, /* SIOCSIWSCAN */
3850 (iw_handler) NULL, /* SIOCGIWSCAN */
3851 (iw_handler) NULL, /* SIOCSIWESSID */
3852 (iw_handler) NULL, /* SIOCGIWESSID */
3853 (iw_handler) NULL, /* SIOCSIWNICKN */
3854 (iw_handler) NULL, /* SIOCGIWNICKN */
3855 (iw_handler) NULL, /* -- hole -- */
3856 (iw_handler) NULL, /* -- hole -- */
3857 (iw_handler) NULL, /* SIOCSIWRATE */
3858 (iw_handler) NULL, /* SIOCGIWRATE */
3859 (iw_handler) NULL, /* SIOCSIWRTS */
3860 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3861 (iw_handler) NULL, /* SIOCSIWFRAG */
3862 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3863 (iw_handler) NULL, /* SIOCSIWTXPOW */
3864 (iw_handler) NULL, /* SIOCGIWTXPOW */
3865 (iw_handler) NULL, /* SIOCSIWRETRY */
3866 (iw_handler) NULL, /* SIOCGIWRETRY */
3867 (iw_handler) NULL, /* SIOCSIWENCODE */
3868 (iw_handler) NULL, /* SIOCGIWENCODE */
3869 (iw_handler) NULL, /* SIOCSIWPOWER */
3870 (iw_handler) NULL, /* SIOCGIWPOWER */
3871 (iw_handler) NULL, /* -- hole -- */
3872 (iw_handler) NULL, /* -- hole -- */
3873 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3874 (iw_handler) NULL, /* SIOCGIWGENIE */
3875 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3876 (iw_handler) NULL, /* SIOCGIWAUTH */
3877 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3878 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3879 (iw_handler) NULL, /* SIOCSIWPMKSA */
3880};
3881
Jeff Johnson224f3702014-03-26 11:09:47 -07003882/*
3883 * Note that the following ioctls were defined with semantics which
3884 * cannot be handled by the "iwpriv" userspace application and hence
3885 * they are not included in the hostapd_private_args array
3886 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3887 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003888
3889static const struct iw_priv_args hostapd_private_args[] = {
3890 { QCSAP_IOCTL_SETPARAM,
3891 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3892 { QCSAP_IOCTL_SETPARAM,
3893 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3894 { QCSAP_PARAM_MAX_ASSOC,
3895 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3896 { QCSAP_PARAM_HIDE_SSID,
3897 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003898 { QCSAP_PARAM_SET_MC_RATE,
3899 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003900 { QCSAP_IOCTL_GETPARAM,
3901 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3902 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3903 { QCSAP_IOCTL_GETPARAM, 0,
3904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3905 { QCSAP_PARAM_MAX_ASSOC, 0,
3906 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003907 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3908 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3909 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3910 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303911 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3912 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003913 { QCSAP_PARAM_CLR_ACL, 0,
3914 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3915 { QCSAP_PARAM_ACL_MODE,
3916 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003917 { QCSAP_IOCTL_GET_STAWPAIE,
3918 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3919 { QCSAP_IOCTL_SETWPAIE,
3920 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3921 { QCSAP_IOCTL_STOPBSS,
3922 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3923 { QCSAP_IOCTL_VERSION, 0,
3924 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003925 { QCSAP_IOCTL_GET_STA_INFO, 0,
3926 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003927 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003928 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003929 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003930 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003931 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05303933 { QCSAP_IOCTL_AP_STATS, 0,
3934 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003935 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3936 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303937 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003938
3939 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3940 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3941 /* handlers for sub-ioctl */
3942 { WE_SET_WLAN_DBG,
3943 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3944 0,
3945 "setwlandbg" },
3946
3947 /* handlers for main ioctl */
3948 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3949 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3950 0,
3951 "" },
3952
3953 /* handlers for sub-ioctl */
3954 { WE_LOG_DUMP_CMD,
3955 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3956 0,
3957 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 { WE_P2P_NOA_CMD,
3959 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3960 0,
3961 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003962 /* handlers for sub ioctl */
3963 {
3964 WE_MCC_CONFIG_CREDENTIAL,
3965 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3966 0,
3967 "setMccCrdnl" },
3968
3969 /* handlers for sub ioctl */
3970 {
3971 WE_MCC_CONFIG_PARAMS,
3972 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3973 0,
3974 "setMccConfig" },
3975
Jeff Johnson295189b2012-06-20 16:38:30 -07003976 /* handlers for main ioctl */
3977 { QCSAP_IOCTL_MODIFY_ACL,
3978 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3979 0,
3980 "modify_acl" },
3981
3982 /* handlers for main ioctl */
3983 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3984 0,
3985 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3986 "getChannelList" },
3987
Jeff Johnsone7245742012-09-05 17:12:55 -07003988 /* handlers for main ioctl */
3989 { QCSAP_IOCTL_SET_TX_POWER,
3990 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3991 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303992 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003993
3994 /* handlers for main ioctl */
3995 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3996 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3997 0,
3998 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303999
4000 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
4001 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
4002 0,
4003 "dataSnapshot" },
4004
4005 /* handlers for main ioctl */
4006 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
4007 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
4008 0,
4009 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004010};
Jeff Johnsone7245742012-09-05 17:12:55 -07004011
Jeff Johnson295189b2012-06-20 16:38:30 -07004012static const iw_handler hostapd_private[] = {
4013 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
4014 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07004015 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
4016 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
4017 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
4018 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
4019 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
4020 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
4021 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
4022 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
4023 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05304024 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
4026 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
4027 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
4028 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004029 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07004030 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
4031 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07004032 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05304033 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05304034 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07004035};
4036const struct iw_handler_def hostapd_handler_def = {
4037 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
4038 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
4039 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
4040 .standard = (iw_handler *)hostapd_handler,
4041 .private = (iw_handler *)hostapd_private,
4042 .private_args = hostapd_private_args,
4043 .get_wireless_stats = NULL,
4044};
4045#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4046struct net_device_ops net_ops_struct = {
4047 .ndo_open = hdd_hostapd_open,
4048 .ndo_stop = hdd_hostapd_stop,
4049 .ndo_uninit = hdd_hostapd_uninit,
4050 .ndo_start_xmit = hdd_softap_hard_start_xmit,
4051 .ndo_tx_timeout = hdd_softap_tx_timeout,
4052 .ndo_get_stats = hdd_softap_stats,
4053 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
4054 .ndo_do_ioctl = hdd_hostapd_ioctl,
4055 .ndo_change_mtu = hdd_hostapd_change_mtu,
4056 .ndo_select_queue = hdd_hostapd_select_queue,
4057 };
4058#endif
4059
4060int hdd_set_hostapd(hdd_adapter_t *pAdapter)
4061{
4062 return VOS_STATUS_SUCCESS;
4063}
4064
4065void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
4066{
4067#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4068 pWlanHostapdDev->netdev_ops = &net_ops_struct;
4069#else
4070 pWlanHostapdDev->open = hdd_hostapd_open;
4071 pWlanHostapdDev->stop = hdd_hostapd_stop;
4072 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
4073 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
4074 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
4075 pWlanHostapdDev->get_stats = hdd_softap_stats;
4076 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
4077 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
4078#endif
4079}
4080
4081VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
4082{
4083 hdd_hostapd_state_t * phostapdBuf;
4084 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004085 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004086 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08004087#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08004088 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
4089 v_U16_t unsafeChannelCount;
4090#endif /* FEATURE_WLAN_CH_AVOID */
4091
Anand N Sunkad26d71b92014-12-24 18:08:22 +05304092 if (pHddCtx->isLogpInProgress) {
4093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4094 "%s:LOGP in Progress. Ignore!!!",__func__);
4095 status = VOS_STATUS_E_FAILURE;
4096 }
4097
Jeff Johnson295189b2012-06-20 16:38:30 -07004098 ENTER();
4099 // Allocate the Wireless Extensions state structure
4100 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
4101
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004102 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
4103
Leo Chang0b0e45a2013-12-15 15:18:55 -08004104#ifdef FEATURE_WLAN_CH_AVOID
4105 /* Get unsafe cahnnel list from cached location */
4106 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
4107 sizeof(unsafeChannelList),
4108 &unsafeChannelCount);
4109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4110 "%s : Unsafe Channel count %d",
4111 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05304112 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08004113 unsafeChannelList,
4114 unsafeChannelCount);
4115#endif /* FEATURE_WLAN_CH_AVOID */
4116
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 // Zero the memory. This zeros the profile structure.
4118 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
4119
4120 // Set up the pointer to the Wireless Extensions state structure
4121 // NOP
4122 status = hdd_set_hostapd(pAdapter);
4123 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004125 return status;
4126 }
4127
4128 status = vos_event_init(&phostapdBuf->vosEvent);
4129 if (!VOS_IS_STATUS_SUCCESS(status))
4130 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 return status;
4133 }
4134
4135 init_completion(&pAdapter->session_close_comp_var);
4136 init_completion(&pAdapter->session_open_comp_var);
4137
4138 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
4139
4140 // Register as a wireless device
4141 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
4142
4143 //Initialize the data path module
4144 status = hdd_softap_init_tx_rx(pAdapter);
4145 if ( !VOS_IS_STATUS_SUCCESS( status ))
4146 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004147 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004148 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304149
4150 status = hdd_wmm_adapter_init( pAdapter );
4151 if (!VOS_IS_STATUS_SUCCESS(status))
4152 {
4153 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004154 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304155 status, status );
4156 goto error_wmm_init;
4157 }
4158
4159 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
4160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304162
4163 return status;
4164
4165error_wmm_init:
4166 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 EXIT();
4168 return status;
4169}
4170
4171hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
4172{
4173 struct net_device *pWlanHostapdDev = NULL;
4174 hdd_adapter_t *pHostapdAdapter = NULL;
4175 v_CONTEXT_t pVosContext= NULL;
4176
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07004178
4179 if (pWlanHostapdDev != NULL)
4180 {
4181 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
4182
4183 //Init the net_device structure
4184 ether_setup(pWlanHostapdDev);
4185
4186 //Initialize the adapter context to zeros.
4187 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
4188 pHostapdAdapter->dev = pWlanHostapdDev;
4189 pHostapdAdapter->pHddCtx = pHddCtx;
4190 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
4191
4192 //Get the Global VOSS context.
4193 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4194 //Save the adapter context in global context for future.
4195 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
4196
4197 //Init the net_device structure
4198 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
4199
4200 hdd_set_ap_ops( pHostapdAdapter->dev );
4201
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
4203 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
4204
4205 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
4206 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
4207
4208 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
4210 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
4211 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
4212 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
4214 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05304215 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07004216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4217 init_completion(&pHostapdAdapter->offchannel_tx_event);
4218#endif
4219
Jeff Johnson295189b2012-06-20 16:38:30 -07004220 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
4221 }
4222 return pHostapdAdapter;
4223}
4224
4225VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
4226{
4227 struct net_device *dev = pAdapter->dev;
4228 VOS_STATUS status = VOS_STATUS_SUCCESS;
4229
4230 ENTER();
4231
4232 if( rtnl_lock_held )
4233 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08004234 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 if( dev_alloc_name(dev, dev->name) < 0 )
4236 {
4237 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
4238 return VOS_STATUS_E_FAILURE;
4239 }
4240 }
4241 if (register_netdevice(dev))
4242 {
4243 hddLog(VOS_TRACE_LEVEL_FATAL,
4244 "%s:Failed:register_netdevice", __func__);
4245 return VOS_STATUS_E_FAILURE;
4246 }
4247 }
4248 else
4249 {
4250 if (register_netdev(dev))
4251 {
4252 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
4253 return VOS_STATUS_E_FAILURE;
4254 }
4255 }
4256 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
4257
4258 EXIT();
4259 return status;
4260}
4261
4262VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
4263{
4264 ENTER();
4265
4266 hdd_softap_deinit_tx_rx(pAdapter);
4267
4268 /* if we are being called during driver unload, then the dev has already
4269 been invalidated. if we are being called at other times, then we can
4270 detatch the wireless device handlers */
4271 if (pAdapter->dev)
4272 {
4273 pAdapter->dev->wireless_handlers = NULL;
4274 }
4275 EXIT();
4276 return 0;
4277}