blob: fda0237804bbc82a8bf75d21f3fe446ccd8bafe0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
Jeff Johnson295189b2012-06-20 16:38:30 -070027
28/**========================================================================
29
30 \file wlan_hdd_hostapd.c
31 \brief WLAN Host Device Driver implementation
32
33 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
34
35 Qualcomm Confidential and Proprietary.
36
37 ========================================================================*/
38/**=========================================================================
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45 $Header:$ $DateTime: $ $Author: $
46
47
48 when who what, where, why
49 -------- --- --------------------------------------------------------
50 04/5/09 Shailender Created module.
51 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
52 ==========================================================================*/
53/*--------------------------------------------------------------------------
54 Include Files
55 ------------------------------------------------------------------------*/
56
57#include <linux/version.h>
58#include <linux/module.h>
59#include <linux/kernel.h>
60#include <linux/init.h>
61#include <linux/wireless.h>
62#include <linux/semaphore.h>
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -070063#include <linux/compat.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
66#include <linux/etherdevice.h>
67#include <wlan_hdd_includes.h>
68#include <qc_sap_ioctl.h>
69#include <wlan_hdd_hostapd.h>
70#include <sapApi.h>
71#include <sapInternal.h>
72#include <wlan_qct_tl.h>
73#include <wlan_hdd_softap_tx_rx.h>
74#include <wlan_hdd_main.h>
75#include <linux/netdevice.h>
76#include <linux/mmc/sdio_func.h>
77#include "wlan_nlink_common.h"
78#include "wlan_btc_svc.h"
79#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070080#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070081#include "cfgApi.h"
82#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070083
Leo Chang0b0e45a2013-12-15 15:18:55 -080084#ifdef FEATURE_WLAN_CH_AVOID
85#include "wcnss_wlan.h"
86#endif /* FEATURE_WLAN_CH_AVOID */
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Leo Chang0b0e45a2013-12-15 15:18:55 -080090
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define IS_UP(_dev) \
92 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
93#define IS_UP_AUTO(_ic) \
94 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
95#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -070096#define WE_GET_STA_INFO_SIZE 30
97/* WEXT limition: MAX allowed buf len for any *
98 * IW_PRIV_TYPE_CHAR is 2Kbytes *
99 */
100#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530102#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700103
Leo Chang0b0e45a2013-12-15 15:18:55 -0800104#ifdef FEATURE_WLAN_CH_AVOID
105/* Channle/Freqency table */
106extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
107safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
108{
109 /*CH , SAFE, default safe */
110 {1 , VOS_TRUE}, //RF_CHAN_1,
111 {2 , VOS_TRUE}, //RF_CHAN_2,
112 {3 , VOS_TRUE}, //RF_CHAN_3,
113 {4 , VOS_TRUE}, //RF_CHAN_4,
114 {5 , VOS_TRUE}, //RF_CHAN_5,
115 {6 , VOS_TRUE}, //RF_CHAN_6,
116 {7 , VOS_TRUE}, //RF_CHAN_7,
117 {8 , VOS_TRUE}, //RF_CHAN_8,
118 {9 , VOS_TRUE}, //RF_CHAN_9,
119 {10 , VOS_TRUE}, //RF_CHAN_10,
120 {11 , VOS_TRUE}, //RF_CHAN_11,
121 {12 , VOS_TRUE}, //RF_CHAN_12,
122 {13 , VOS_TRUE}, //RF_CHAN_13,
123 {14 , VOS_TRUE}, //RF_CHAN_14,
124 {240, VOS_TRUE}, //RF_CHAN_240,
125 {244, VOS_TRUE}, //RF_CHAN_244,
126 {248, VOS_TRUE}, //RF_CHAN_248,
127 {252, VOS_TRUE}, //RF_CHAN_252,
128 {208, VOS_TRUE}, //RF_CHAN_208,
129 {212, VOS_TRUE}, //RF_CHAN_212,
130 {216, VOS_TRUE}, //RF_CHAN_216,
131 {36 , VOS_TRUE}, //RF_CHAN_36,
132 {40 , VOS_TRUE}, //RF_CHAN_40,
133 {44 , VOS_TRUE}, //RF_CHAN_44,
134 {48 , VOS_TRUE}, //RF_CHAN_48,
135 {52 , VOS_TRUE}, //RF_CHAN_52,
136 {56 , VOS_TRUE}, //RF_CHAN_56,
137 {60 , VOS_TRUE}, //RF_CHAN_60,
138 {64 , VOS_TRUE}, //RF_CHAN_64,
139 {100, VOS_TRUE}, //RF_CHAN_100,
140 {104, VOS_TRUE}, //RF_CHAN_104,
141 {108, VOS_TRUE}, //RF_CHAN_108,
142 {112, VOS_TRUE}, //RF_CHAN_112,
143 {116, VOS_TRUE}, //RF_CHAN_116,
144 {120, VOS_TRUE}, //RF_CHAN_120,
145 {124, VOS_TRUE}, //RF_CHAN_124,
146 {128, VOS_TRUE}, //RF_CHAN_128,
147 {132, VOS_TRUE}, //RF_CHAN_132,
148 {136, VOS_TRUE}, //RF_CHAN_136,
149 {140, VOS_TRUE}, //RF_CHAN_140,
150 {149, VOS_TRUE}, //RF_CHAN_149,
151 {153, VOS_TRUE}, //RF_CHAN_153,
152 {157, VOS_TRUE}, //RF_CHAN_157,
153 {161, VOS_TRUE}, //RF_CHAN_161,
154 {165, VOS_TRUE}, //RF_CHAN_165,
155};
156#endif /* FEATURE_WLAN_CH_AVOID */
157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530158/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 * Function definitions
160 *-------------------------------------------------------------------------*/
161/**---------------------------------------------------------------------------
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530162
Jeff Johnson295189b2012-06-20 16:38:30 -0700163 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530164
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 This is called in response to ifconfig up
166
167 \param - dev Pointer to net_device structure
168
169 \return - 0 for success non-zero for failure
170
171 --------------------------------------------------------------------------*/
172int hdd_hostapd_open (struct net_device *dev)
173{
Siddharth Bhaldeff5f22014-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 Bhaldeff5f22014-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
191 netif_tx_start_all_queues(dev);
192
193 EXIT();
194 return 0;
195}
196/**---------------------------------------------------------------------------
197
198 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
199
200 This is called in response to ifconfig down
201
202 \param - dev Pointer to net_device structure
203
204 \return - 0 for success non-zero for failure
205
206 --------------------------------------------------------------------------*/
207int hdd_hostapd_stop (struct net_device *dev)
208{
209 ENTER();
210
Kanchanapally, Vidyullatha7af0be12014-12-10 13:54:38 +0530211 if(NULL != dev) {
212 //Stop all tx queues
213 netif_tx_disable(dev);
214
215 //Turn OFF carrier state
216 netif_carrier_off(dev);
217 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219 EXIT();
220 return 0;
221}
222/**---------------------------------------------------------------------------
223
224 \brief hdd_hostapd_uninit() - HDD uninit function
225
226 This is called during the netdev unregister to uninitialize all data
227associated with the device
228
229 \param - dev Pointer to net_device structure
230
231 \return - void
232
233 --------------------------------------------------------------------------*/
234static void hdd_hostapd_uninit (struct net_device *dev)
235{
236 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
237
238 ENTER();
239
240 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
241 {
242 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
243
244 /* after uninit our adapter structure will no longer be valid */
245 pHostapdAdapter->dev = NULL;
246 }
247
248 EXIT();
249}
250
251
252/**============================================================================
253 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
254 transmitting packets. There are 2 versions of this function. One that uses
255 locked queue and other that uses lockless queues. Both have been retained to
256 do some performance testing
257 @param skb : [in] pointer to OS packet (sk_buff)
258 @param dev : [in] pointer to Libra network device
259
260 @return : NET_XMIT_DROP if packets are dropped
261 : NET_XMIT_SUCCESS if packet is enqueued succesfully
262 ===========================================================================*/
263int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
264{
265 return 0;
266}
267int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
268{
269 return 0;
270}
271
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700272static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
273 hdd_priv_data_t *priv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -0700274{
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700275 tANI_U8 *command = NULL;
Kaushik, Sushant7efe3502014-10-21 16:40:18 +0530276 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
277 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700278 int ret = 0;
Kaushik, Sushant7efe3502014-10-21 16:40:18 +0530279 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700280 /*
281 * Note that valid pointers are provided by caller
282 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700284 if (priv_data->total_len <= 0 ||
285 priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
286 {
287 /* below we allocate one more byte for command buffer.
288 * To avoid addition overflow total_len should be
289 * smaller than INT_MAX. */
290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
291 __func__, priv_data->total_len);
292 ret = -EFAULT;
293 goto exit;
294 }
Kaushik, Sushant7efe3502014-10-21 16:40:18 +0530295 status = wlan_hdd_validate_context(pHddCtx);
296
297 if (0 != status)
298 {
299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
300 "%s: HDD context is not valid", __func__);
301 return status;
302 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700303
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700304 /* Allocate +1 for '\0' */
305 command = kmalloc((priv_data->total_len + 1), GFP_KERNEL);
306 if (!command)
307 {
308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__);
309 ret = -ENOMEM;
310 goto exit;
311 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700312
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700313 if (copy_from_user(command, priv_data->buf, priv_data->total_len))
314 {
315 ret = -EFAULT;
316 goto exit;
317 }
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800318
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700319 /* Make sure the command is NUL-terminated */
320 command[priv_data->total_len] = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -0700321
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700322 hddLog(VOS_TRACE_LEVEL_INFO,
323 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700324
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700325 if (strncmp(command, "P2P_SET_NOA", 11) == 0)
326 {
327 hdd_setP2pNoa(pAdapter->dev, command);
328 }
329 else if (strncmp(command, "P2P_SET_PS", 10) == 0)
330 {
331 hdd_setP2pOpps(pAdapter->dev, command);
332 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800333#ifdef FEATURE_WLAN_BATCH_SCAN
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700334 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
335 {
336 ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command);
337 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800338#endif
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700339 else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
340 {
341 /*
342 * command should be a string having format
343 * SET_SAP_CHANNEL_LIST <num channels> <channels seperated by spaces>
344 */
345 hddLog(VOS_TRACE_LEVEL_INFO,
346 "%s: Received Command to Set Preferred Channels for SAP",
347 __func__);
Rajeev Kumar8b373292014-01-08 20:36:55 -0800348
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700349 ret = sapSetPreferredChannel(command);
350 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530351 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
352 {
353 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
354 tANI_U8 filterType = 0;
355 tANI_U8 *value;
356 value = command + 9;
357
358 /* Convert the value from ascii to integer */
359 ret = kstrtou8(value, 10, &filterType);
360 if (ret < 0)
361 {
362 /* If the input value is greater than max value of datatype,
363 * then also kstrtou8 fails
364 */
365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
366 "%s: kstrtou8 failed range ", __func__);
367 ret = -EINVAL;
368 goto exit;
369 }
370 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
371 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
374 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
375 " 2-Sink ", __func__);
376 ret = -EINVAL;
377 goto exit;
378 }
379 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
380 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant7efe3502014-10-21 16:40:18 +0530381 pScanInfo = &pHddCtx->scan_info;
382 if (filterType && pScanInfo != NULL &&
383 pHddCtx->scan_info.mScanPending)
384 {
385 /*Miracast Session started. Abort Scan */
386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
387 "%s, Aborting Scan For Miracast",__func__);
388 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
389 eCSR_SCAN_ABORT_DEFAULT);
390 }
Ganesh Kondabattini2d7c7f02014-09-04 22:21:39 +0530391 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
392 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
393 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700394
Jeff Johnson295189b2012-06-20 16:38:30 -0700395exit:
396 if (command)
397 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700398 kfree(command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700399 }
400 return ret;
401}
402
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700403#ifdef CONFIG_COMPAT
404static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
405 struct ifreq *ifr)
406{
407 struct {
408 compat_uptr_t buf;
409 int used_len;
410 int total_len;
411 } compat_priv_data;
412 hdd_priv_data_t priv_data;
413 int ret = 0;
414
415 /*
416 * Note that pAdapter and ifr have already been verified by caller,
417 * and HDD context has also been validated
418 */
419 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
420 sizeof(compat_priv_data))) {
421 ret = -EFAULT;
422 goto exit;
423 }
424 priv_data.buf = compat_ptr(compat_priv_data.buf);
425 priv_data.used_len = compat_priv_data.used_len;
426 priv_data.total_len = compat_priv_data.total_len;
427 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
428 exit:
429 return ret;
430}
431#else /* CONFIG_COMPAT */
432static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
433 struct ifreq *ifr)
434{
435 /* will never be invoked */
436 return 0;
437}
438#endif /* CONFIG_COMPAT */
439
440static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
441{
442 hdd_priv_data_t priv_data;
443 int ret = 0;
444
445 /*
446 * Note that pAdapter and ifr have already been verified by caller,
447 * and HDD context has also been validated
448 */
449 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
450 ret = -EFAULT;
451 } else {
452 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
453 }
454 return ret;
455}
456
457static int hdd_hostapd_ioctl(struct net_device *dev,
458 struct ifreq *ifr, int cmd)
459{
460 hdd_adapter_t *pAdapter;
461 hdd_context_t *pHddCtx;
462 int ret;
463
464 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
465 if (NULL == pAdapter) {
466 hddLog(VOS_TRACE_LEVEL_ERROR,
467 "%s: HDD adapter context is Null", __func__);
468 ret = -ENODEV;
469 goto exit;
470 }
471 if (dev != pAdapter->dev) {
472 hddLog(VOS_TRACE_LEVEL_ERROR,
473 "%s: HDD adapter/dev inconsistency", __func__);
474 ret = -ENODEV;
475 goto exit;
476 }
477
478 if ((!ifr) || (!ifr->ifr_data)) {
479 ret = -EINVAL;
480 goto exit;
481 }
482
483 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
484 ret = wlan_hdd_validate_context(pHddCtx);
485 if (ret) {
486 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__);
487 ret = -EBUSY;
488 goto exit;
489 }
490
491 switch (cmd) {
492 case (SIOCDEVPRIVATE + 1):
493 if (is_compat_task())
494 ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
495 else
496 ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
497 break;
498 default:
499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
500 __func__, cmd);
501 ret = -EINVAL;
502 break;
503 }
504 exit:
505 return ret;
506}
507
Jeff Johnson295189b2012-06-20 16:38:30 -0700508/**---------------------------------------------------------------------------
509
510 \brief hdd_hostapd_set_mac_address() -
511 This function sets the user specified mac address using
512 the command ifconfig wlanX hw ether <mac adress>.
513
514 \param - dev - Pointer to the net device.
515 - addr - Pointer to the sockaddr.
516 \return - 0 for success, non zero for failure
517
518 --------------------------------------------------------------------------*/
519
520static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
521{
522 struct sockaddr *psta_mac_addr = addr;
523 ENTER();
524 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
525 EXIT();
526 return 0;
527}
528void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
529{
530 struct net_device *dev = (struct net_device *)usrDataForCallback;
531 v_BYTE_t we_custom_event[64];
532 union iwreq_data wrqu;
533#ifdef DISABLE_CONCURRENCY_AUTOSAVE
534 VOS_STATUS vos_status;
535 hdd_adapter_t *pHostapdAdapter;
536 hdd_ap_ctx_t *pHddApCtx;
537#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
538
539 /* event_name space-delimiter driver_module_name */
540 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
541 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
542 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
543
544 ENTER();
545
Agarwal Ashish51325b52014-06-16 16:50:49 +0530546#ifdef DISABLE_CONCURRENCY_AUTOSAVE
547 if (vos_concurrent_open_sessions_running())
Jeff Johnson295189b2012-06-20 16:38:30 -0700548 {
549 /*
550 This timer routine is going to be called only when AP
551 persona is up.
552 If there are concurrent sessions running we do not want
553 to shut down the Bss.Instead we run the timer again so
554 that if Autosave is enabled next time and other session
555 was down only then we bring down AP
556 */
557 pHostapdAdapter = netdev_priv(dev);
558 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
559 vos_status = vos_timer_start(
560 &pHddApCtx->hdd_ap_inactivity_timer,
561 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
562 * 1000);
563 if (!VOS_IS_STATUS_SUCCESS(vos_status))
564 {
565 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
566 }
567 EXIT();
568 return;
569 }
570#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
571 memset(&we_custom_event, '\0', sizeof(we_custom_event));
572 memcpy(&we_custom_event, autoShutEvent, event_len);
573
574 memset(&wrqu, 0, sizeof(wrqu));
575 wrqu.data.length = event_len;
576
577 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
578 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
579
580 EXIT();
581}
582
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800583VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
584{
585 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
586 ptSapContext pSapCtx = NULL;
587 eHalStatus halStatus = eHAL_STATUS_FAILURE;
588 v_PVOID_t hHal = NULL;
589
590 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
591 "%s: UPDATE Beacon Params", __func__);
592
593 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
594 pSapCtx = VOS_GET_SAP_CB(pVosContext);
595 if ( NULL == pSapCtx )
596 {
597 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
598 "%s: Invalid SAP pointer from pvosGCtx", __func__);
599 return VOS_STATUS_E_FAULT;
600 }
601
602 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
603 if ( NULL == hHal ){
604 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
605 "%s: Invalid HAL pointer from pvosGCtx", __func__);
606 return VOS_STATUS_E_FAULT;
607 }
608 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
609 if(halStatus == eHAL_STATUS_FAILURE ){
610 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
611 "%s: Failed to update Beacon Params", __func__);
612 return VOS_STATUS_E_FAILURE;
613 }
614 }
615 return VOS_STATUS_SUCCESS;
616}
617
618void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
619{
620 v_U8_t staId = 0;
621 struct net_device *dev;
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530622 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
623 ptSapContext pSapCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800624
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530625 dev = (struct net_device *)usrDataForCallback;
626 pSapCtx = VOS_GET_SAP_CB(pVosContext);
627 if(pSapCtx == NULL){
628 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
629 FL("psapCtx is NULL"));
630 return;
631 }
Arif Hussain6d2a3322013-11-17 19:50:10 -0800632 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800633 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
634 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530635 if ( pSapCtx->aStaInfo[staId].isUsed &&
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800636 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
637 {
638 //Disconnect all the stations
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530639 hdd_softap_sta_disassoc(pHostapdAdapter, &pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800640 }
641 }
642}
643
644static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
645{
646 struct net_device *dev;
Agarwal Ashish51325b52014-06-16 16:50:49 +0530647 hdd_context_t *pHddCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800648 VOS_STATUS status = VOS_STATUS_SUCCESS;
649 dev = (struct net_device *)usrDataForCallback;
650 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +0530651
652 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
653 status = wlan_hdd_validate_context(pHddCtx);
654
655 if (0 != status) {
656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
657 return status;
658 }
659
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800660 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
661 {
662 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
663 {
664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
665 }
666 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +0530667 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800668 }
669 EXIT();
670 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
671}
Jeff Johnson295189b2012-06-20 16:38:30 -0700672
673VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
674{
675 hdd_adapter_t *pHostapdAdapter;
676 hdd_ap_ctx_t *pHddApCtx;
677 hdd_hostapd_state_t *pHostapdState;
678 struct net_device *dev;
679 eSapHddEvent sapEvent;
680 union iwreq_data wrqu;
681 v_BYTE_t *we_custom_event_generic = NULL;
682 int we_event = 0;
683 int i = 0;
684 v_U8_t staId;
685 VOS_STATUS vos_status;
686 v_BOOL_t bWPSState;
687 v_BOOL_t bApActive = FALSE;
688 v_BOOL_t bAuthRequired = TRUE;
689 tpSap_AssocMacAddr pAssocStasArray = NULL;
690 char unknownSTAEvent[IW_CUSTOM_MAX+1];
691 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
692 v_BYTE_t we_custom_start_event[64];
693 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800694 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800695 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700696 struct iw_michaelmicfailure msg;
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530697 v_CONTEXT_t pVosContext = NULL;
698 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700699
700 dev = (struct net_device *)usrDataForCallback;
701 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530702
703 if ((NULL == pHostapdAdapter) ||
704 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
705 {
706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
707 "invalid adapter or adapter has invalid magic");
708 return eHAL_STATUS_FAILURE;
709 }
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530710 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
711 pSapCtx = VOS_GET_SAP_CB(pVosContext);
712 if(pSapCtx == NULL){
713 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
714 FL("psapCtx is NULL"));
715 return eHAL_STATUS_FAILURE;
716 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700717 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
718 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
719 sapEvent = pSapEvent->sapHddEventCode;
720 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800721 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700722
723 switch(sapEvent)
724 {
725 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800726 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700727 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
728 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
729 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
730
731 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
732 vos_status = vos_event_set(&pHostapdState->vosEvent);
733
734 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
735 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700737 goto stopbss;
738 }
739 else
740 {
741 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
742 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530743 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
744 if (!VOS_IS_STATUS_SUCCESS(vos_status))
745 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 }
747
748 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
749 {
750 // AP Inactivity timer init and start
751 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
752 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
753 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800754 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700755
756 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
757 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800758 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700759
760 }
761 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
762 pHostapdState->bssState = BSS_START;
763
764 // Send current operating channel of SoftAP to BTC-ES
765 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
766
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 //Check if there is any group key pending to set.
768 if( pHddApCtx->groupKey.keyLength )
769 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700770 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700771 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
772 &pHddApCtx->groupKey ) )
773 {
774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
775 "%s: WLANSAP_SetKeySta failed", __func__);
776 }
777 pHddApCtx->groupKey.keyLength = 0;
778 }
779 else if ( pHddApCtx->wepKey[0].keyLength )
780 {
781 int i=0;
782 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
783 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700784 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
786 &pHddApCtx->wepKey[i] ) )
787 {
788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
789 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
790 }
791 pHddApCtx->wepKey[i].keyLength = 0;
792 }
793 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700794 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
795 startBssEvent = "SOFTAP.enabled";
796 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
797 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
798 memset(&wrqu, 0, sizeof(wrqu));
799 wrqu.data.length = strlen(startBssEvent);
800 we_event = IWEVCUSTOM;
801 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700802 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700803 break; //Event will be sent after Switch-Case stmt
804
805 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800806 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
808
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700809 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700810 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700811
Jeff Johnson295189b2012-06-20 16:38:30 -0700812 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 goto stopbss;
814 case eSAP_STA_SET_KEY_EVENT:
815 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800816 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700817 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
818 return VOS_STATUS_SUCCESS;
819 case eSAP_STA_DEL_KEY_EVENT:
820 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800821 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 return VOS_STATUS_SUCCESS;
823 case eSAP_STA_MIC_FAILURE_EVENT:
824 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 memset(&msg, '\0', sizeof(msg));
826 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800827 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800828 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700829 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700830 msg.flags = IW_MICFAILURE_GROUP;
831 else
832 msg.flags = IW_MICFAILURE_PAIRWISE;
833 memset(&wrqu, 0, sizeof(wrqu));
834 wrqu.data.length = sizeof(msg);
835 we_event = IWEVMICHAELMICFAILURE;
836 we_custom_event_generic = (v_BYTE_t *)&msg;
837 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700838 /* inform mic failure to nl80211 */
839 cfg80211_michael_mic_failure(dev,
840 pSapEvent->sapevt.
841 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700842 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700843 NL80211_KEYTYPE_GROUP :
844 NL80211_KEYTYPE_PAIRWISE),
845 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
846 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
847 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 break;
849
850 case eSAP_STA_ASSOC_EVENT:
851 case eSAP_STA_REASSOC_EVENT:
852 wrqu.addr.sa_family = ARPHRD_ETHER;
853 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800854 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800855 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700856 we_event = IWEVREGISTERED;
857
858 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
859
860 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
861 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
862 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
863 {
864 bAuthRequired = FALSE;
865 }
866
867 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
868 {
c_hpothuffdb5272013-10-02 16:42:35 +0530869 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700870 TRUE,
871 pHddApCtx->uPrivacy,
872 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
873 0,
874 0,
875 (v_MACADDR_t *)wrqu.addr.sa_data,
876 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530877
878 if (!VOS_IS_STATUS_SUCCESS(vos_status))
879 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
880 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 }
882 else
883 {
c_hpothuffdb5272013-10-02 16:42:35 +0530884 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700885 FALSE,
886 pHddApCtx->uPrivacy,
887 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
888 0,
889 0,
890 (v_MACADDR_t *)wrqu.addr.sa_data,
891 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530892 if (!VOS_IS_STATUS_SUCCESS(vos_status))
893 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
894 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Amar Singhal6144c002013-05-03 16:11:42 -0700895 }
896
Jeff Johnson295189b2012-06-20 16:38:30 -0700897 // Stop AP inactivity timer
898 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
899 {
900 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
901 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800902 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800904#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800905 if (wake_lock_active(&pHddCtx->sap_wake_lock))
906 {
907 wake_unlock(&pHddCtx->sap_wake_lock);
908 }
Amar Singhal6144c002013-05-03 16:11:42 -0700909 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
912 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700913 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
914
Jeff Johnson295189b2012-06-20 16:38:30 -0700915 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
916 {
kaliu1a48b522016-12-12 15:58:36 +0800917 struct station_info *stainfo;
918 stainfo = vos_mem_malloc(sizeof(*stainfo));
919 if (stainfo == NULL) {
920 hddLog(LOGE, FL("alloc station_info failed"));
921 return VOS_STATUS_E_NOMEM;
922 }
923 memset(stainfo, 0, sizeof(*stainfo));
924 stainfo->assoc_req_ies =
Jeff Johnson295189b2012-06-20 16:38:30 -0700925 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
kaliu1a48b522016-12-12 15:58:36 +0800926 stainfo->assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
kaliu1a48b522016-12-12 15:58:36 +0800928 stainfo->filled |= STATION_INFO_ASSOC_REQ_IES;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700929#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700930 cfg80211_new_sta(dev,
931 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
kaliu1a48b522016-12-12 15:58:36 +0800932 stainfo, GFP_KERNEL);
933 vos_mem_free(stainfo);
934
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 }
936 else
937 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800938 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700939 }
940 }
941#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800942 pScanInfo = &pHddCtx->scan_info;
943 // Lets do abort scan to ensure smooth authentication for client
944 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
945 {
Kaushik, Sushant86ac0a52014-10-21 16:07:48 +0530946 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530947 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800948 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700949
950 break;
951 case eSAP_STA_DISASSOC_EVENT:
952 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800953 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800954 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
956 hddLog(LOG1," User initiated disassociation");
957 else
958 hddLog(LOG1," MAC initiated disassociation");
959 we_event = IWEVEXPIRED;
960 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
961 if (!VOS_IS_STATUS_SUCCESS(vos_status))
962 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700963 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 -0700964 return VOS_STATUS_E_FAILURE;
965 }
966 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
967
968 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
969 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530970 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 // Start AP inactivity timer if no stations associated with it
972 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
973 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530974 if (pSapCtx->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700975 {
976 bApActive = TRUE;
977 break;
978 }
979 }
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +0530980 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700981
982 if (bApActive == FALSE)
983 {
984 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
985 {
986 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
987 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800988 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 }
990 else
991 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
992 }
993 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
995 cfg80211_del_sta(dev,
996 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
997 GFP_KERNEL);
998#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800999 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +05301000 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
1001 if (VOS_STATUS_SUCCESS != vos_status)
1002 {
1003 hddLog(LOGE, "%s: failed to update Beacon interval %d",
1004 __func__, vos_status);
1005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 break;
1007 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1008 {
1009 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
1010 union iwreq_data wreq;
1011
1012 down(&pHddApCtx->semWpsPBCOverlapInd);
1013 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
1014
1015 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
1016 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1017
1018 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -08001019 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 memset(&wreq, 0, sizeof(wreq));
1021 wreq.data.length = strlen(message); // This is length of message
1022 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
1023
1024 return VOS_STATUS_SUCCESS;
1025 }
1026 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1027 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1028 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
1029 { // List of associated stations
1030 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
1031 {
1032 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
1033 i+1,
1034 pAssocStasArray->assocId,
1035 pAssocStasArray->staId,
1036 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
1037 pAssocStasArray++;
1038 }
1039 }
1040 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001041 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 case eSAP_INDICATE_MGMT_FRAME:
1044 hdd_indicateMgmtFrame( pHostapdAdapter,
1045 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
1046 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
1047 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05301048 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07001049 return VOS_STATUS_SUCCESS;
1050 case eSAP_REMAIN_CHAN_READY:
1051 hdd_remainChanReadyHandler( pHostapdAdapter );
1052 return VOS_STATUS_SUCCESS;
1053 case eSAP_SEND_ACTION_CNF:
1054 hdd_sendActionCnf( pHostapdAdapter,
1055 ( eSAP_STATUS_SUCCESS ==
1056 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
1057 TRUE : FALSE );
1058 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 case eSAP_UNKNOWN_STA_JOIN:
1060 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1061 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1062 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1063 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1064 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1065 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1066 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1067 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1068 wrqu.data.pointer = unknownSTAEvent;
1069 wrqu.data.length = strlen(unknownSTAEvent);
1070 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +05301071 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 break;
1073
1074 case eSAP_MAX_ASSOC_EXCEEDED:
1075 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1076 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1077 " one or more devices to enable the new device connection",
1078 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1079 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1080 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1081 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1082 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1083 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
1084 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1085 wrqu.data.pointer = maxAssocExceededEvent;
1086 wrqu.data.length = strlen(maxAssocExceededEvent);
1087 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001088 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 break;
1090 case eSAP_STA_ASSOC_IND:
1091 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001092
1093 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001094 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001095 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
1096 return VOS_STATUS_SUCCESS;
1097
1098 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
c_hpothuffdb5272013-10-02 16:42:35 +05301099 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1100 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1101 {
1102 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1103 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001104 return VOS_STATUS_SUCCESS;
1105
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001107 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 goto stopbss;
1109 return VOS_STATUS_SUCCESS;
1110 }
1111 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1112 return VOS_STATUS_SUCCESS;
1113
1114stopbss :
1115 {
1116 v_BYTE_t we_custom_event[64];
1117 char *stopBssEvent = "STOP-BSS.response";//17
1118 int event_len = strlen(stopBssEvent);
1119
1120 hddLog(LOG1, FL("BSS stop status = %s"),
1121 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1122 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1123
1124 /* Change the BSS state now since, as we are shutting things down,
1125 * we don't want interfaces to become re-enabled */
1126 pHostapdState->bssState = BSS_STOP;
1127
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301128 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1129 {
1130 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1131 {
1132 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1133 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1134 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1135 }
1136
1137 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1138 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1139 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1140 }
1141
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 /* Stop the pkts from n/w stack as we are going to free all of
1143 * the TX WMM queues for all STAID's */
1144 hdd_hostapd_stop(dev);
1145
1146 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301147 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1148 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1149 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001150
Amar Singhal37e6f052013-03-05 16:16:54 -08001151 /* once the event is set, structure dev/pHostapdAdapter should
1152 * not be touched since they are now subject to being deleted
1153 * by another thread */
1154 if (eSAP_STOP_BSS_EVENT == sapEvent)
1155 vos_event_set(&pHostapdState->vosEvent);
1156
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 /* notify userspace that the BSS has stopped */
1158 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1159 memcpy(&we_custom_event, stopBssEvent, event_len);
1160 memset(&wrqu, 0, sizeof(wrqu));
1161 wrqu.data.length = event_len;
1162 we_event = IWEVCUSTOM;
1163 we_custom_event_generic = we_custom_event;
1164 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001165 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 }
1167 return VOS_STATUS_SUCCESS;
1168}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001169
1170int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001172 eCsrEncryptionType *pEncryptType,
1173 eCsrEncryptionType *mcEncryptType,
1174 eCsrAuthType *pAuthType,
1175 v_BOOL_t *pMFPCapable,
1176 v_BOOL_t *pMFPRequired,
1177 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 u_int8_t *gen_ie )
1179{
1180 tDot11fIERSN dot11RSNIE;
1181 tDot11fIEWPA dot11WPAIE;
1182
1183 tANI_U8 *pRsnIe;
1184 tANI_U16 RSNIeLen;
1185
1186 if (NULL == halHandle)
1187 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001188 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001189 return -EINVAL;
1190 }
1191
1192 // Validity checks
1193 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1194 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1195 return -EINVAL;
1196 // Type check
1197 if ( gen_ie[0] == DOT11F_EID_RSN)
1198 {
1199 // Validity checks
1200 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1201 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1202 {
1203 return VOS_STATUS_E_FAILURE;
1204 }
1205 // Skip past the EID byte and length byte
1206 pRsnIe = gen_ie + 2;
1207 RSNIeLen = gen_ie_len - 2;
1208 // Unpack the RSN IE
1209 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1210 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1211 pRsnIe,
1212 RSNIeLen,
1213 &dot11RSNIE);
1214 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001215 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001216 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001217 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001218 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 /*Here we have followed the apple base code,
1220 but probably I suspect we can do something different*/
1221 //dot11RSNIE.akm_suite_count
1222 // Just translate the FIRST one
1223 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1224 //dot11RSNIE.pwise_cipher_suite_count
1225 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1226 //dot11RSNIE.gp_cipher_suite_count
1227 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1228 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001229 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1230 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001231
1232 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1233 } else
1234 if (gen_ie[0] == DOT11F_EID_WPA)
1235 {
1236 // Validity checks
1237 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1238 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1239 {
1240 return VOS_STATUS_E_FAILURE;
1241 }
1242 // Skip past the EID byte and length byte - and four byte WiFi OUI
1243 pRsnIe = gen_ie + 2 + 4;
1244 RSNIeLen = gen_ie_len - (2 + 4);
1245 // Unpack the WPA IE
1246 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1247 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1248 pRsnIe,
1249 RSNIeLen,
1250 &dot11WPAIE);
1251 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001252 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001253 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001254 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001255 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001256 //dot11WPAIE.auth_suite_count
1257 // Just translate the FIRST one
1258 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1259 //dot11WPAIE.unicast_cipher_count
1260 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1261 //dot11WPAIE.unicast_cipher_count
1262 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001263 *pMFPCapable = VOS_FALSE;
1264 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 }
1266 else
1267 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001268 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001269 return VOS_STATUS_E_FAILURE;
1270 }
1271 return VOS_STATUS_SUCCESS;
1272}
Leo Chang614d2072013-08-22 14:59:44 -07001273
Leo Chang0b0e45a2013-12-15 15:18:55 -08001274#ifdef FEATURE_WLAN_CH_AVOID
1275/**---------------------------------------------------------------------------
1276
1277 \brief hdd_hostapd_freq_to_chn() -
1278
1279 Input frequency translated into channel number
1280
1281 \param - freq input frequency with order of kHz
1282
1283 \return - corresponding channel number.
1284 incannot find correct channel number, return 0
1285
1286 --------------------------------------------------------------------------*/
1287v_U16_t hdd_hostapd_freq_to_chn
1288(
1289 v_U16_t freq
1290)
1291{
1292 int loop;
1293
1294 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1295 {
1296 if (rfChannels[loop].targetFreq == freq)
1297 {
1298 return rfChannels[loop].channelNum;
1299 }
1300 }
1301
1302 return (0);
1303}
1304
1305/*==========================================================================
1306 FUNCTION sapUpdateUnsafeChannelList
1307
1308 DESCRIPTION
1309 Function Undate unsafe channel list table
1310
1311 DEPENDENCIES
1312 NA.
1313
1314 PARAMETERS
1315
1316 IN
1317 pSapCtx : SAP context pointer, include unsafe channel list
1318
1319 RETURN VALUE
1320 NONE
1321============================================================================*/
1322void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1323 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1324{
1325 v_U16_t i, j;
1326
1327 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1328 sizeof(pHddCtx->unsafeChannelList));
1329 if (0 == unsafeChannelCount)
1330 {
1331 pHddCtx->unsafeChannelCount = 0;
1332 }
1333 else
1334 {
c_hpothu8de53e42014-08-22 15:00:37 +05301335 if (unsafeChannelCount > NUM_20MHZ_RF_CHANNELS)
1336 {
1337 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1338 FL("unsafeChannelCount%hd greater than %d"),
1339 unsafeChannelCount, NUM_20MHZ_RF_CHANNELS);
1340 unsafeChannelCount = NUM_20MHZ_RF_CHANNELS;
1341 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001342 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1343 unsafeChannelList,
1344 unsafeChannelCount * sizeof(tANI_U16));
1345 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1346 }
1347
1348 /* Flush, default set all channel safe */
1349 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1350 {
1351 safeChannels[i].isSafe = VOS_TRUE;
1352 }
1353
1354 /* Try to find unsafe channel */
1355 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1356 {
1357 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1358 {
1359 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1360 {
1361 /* Found unsafe channel, update it */
1362 safeChannels[j].isSafe = VOS_FALSE;
1363 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1364 "%s : CH %d is not safe",
1365 __func__, pHddCtx->unsafeChannelList[i]);
1366 break;
1367 }
1368 }
1369 }
1370
1371 return;
1372}
1373
1374/**---------------------------------------------------------------------------
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301375 \brief hdd_restart_softap() -
1376 Restart SAP on STA channel to support
1377 STA + SAP concurrency.
1378
1379 --------------------------------------------------------------------------*/
1380void hdd_restart_softap
1381(
1382 hdd_context_t *pHddCtx,
1383 hdd_adapter_t *pHostapdAdapter
1384)
1385{
1386 tSirChAvoidIndType *chAvoidInd;
1387
1388 chAvoidInd =
1389 (tSirChAvoidIndType *)vos_mem_malloc(sizeof(tSirChAvoidIndType));
1390 if (NULL == chAvoidInd)
1391 {
1392 hddLog(VOS_TRACE_LEVEL_INFO, FL("CH_AVOID IND buffer alloc Fail"));
1393 return ;
1394 }
1395 chAvoidInd->avoidRangeCount = 1;
1396 chAvoidInd->avoidFreqRange[0].startFreq =
1397 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1398 chAvoidInd->avoidFreqRange[0].endFreq =
1399 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1400 hdd_hostapd_ch_avoid_cb((void *)pHddCtx, (void *)chAvoidInd);
Girish Gowlic1725582014-07-31 20:37:35 +05301401 vos_mem_free(chAvoidInd);
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301402}
1403/**---------------------------------------------------------------------------
Leo Chang0b0e45a2013-12-15 15:18:55 -08001404
1405 \brief hdd_hostapd_ch_avoid_cb() -
1406
1407 Avoid channel notification from FW handler.
1408 FW will send un-safe channle list to avoid overwrapping.
1409 hostapd should not use notified channel
1410
1411 \param - pAdapter HDD adapter pointer
1412 indParam channel avoid notification parameter
1413
1414 \return - None
1415
1416 --------------------------------------------------------------------------*/
1417void hdd_hostapd_ch_avoid_cb
1418(
1419 void *pAdapter,
1420 void *indParam
1421)
1422{
1423 hdd_adapter_t *pHostapdAdapter = NULL;
1424 hdd_context_t *hddCtxt;
1425 tSirChAvoidIndType *chAvoidInd;
1426 v_U8_t rangeLoop;
1427 v_U16_t channelLoop;
1428 v_U16_t dupCheck;
1429 v_U16_t startChannel;
1430 v_U16_t endChannel;
1431 v_U16_t unsafeChannelCount = 0;
1432 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1433 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001434 tHddAvoidFreqList hddAvoidFreqList;
1435 tANI_U32 i;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001436
1437 /* Basic sanity */
1438 if ((NULL == pAdapter) || (NULL == indParam))
1439 {
1440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1441 "%s : Invalid arguments", __func__);
1442 return;
1443 }
1444
1445 hddCtxt = (hdd_context_t *)pAdapter;
1446 chAvoidInd = (tSirChAvoidIndType *)indParam;
1447 pVosContext = hddCtxt->pvosContext;
1448
1449 /* Make unsafe channel list */
1450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1451 "%s : band count %d",
1452 __func__, chAvoidInd->avoidRangeCount);
1453 vos_mem_zero((void *)unsafeChannelList,
1454 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1455 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1456 {
1457 startChannel = hdd_hostapd_freq_to_chn(
1458 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1459 endChannel = hdd_hostapd_freq_to_chn(
1460 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1462 "%s : start %d : %d, end %d : %d",
1463 __func__,
1464 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1465 startChannel,
1466 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1467 endChannel);
1468 for (channelLoop = startChannel;
1469 channelLoop < (endChannel + 1);
1470 channelLoop++)
1471 {
1472 /* Channel duplicate check routine */
1473 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1474 {
1475 if (unsafeChannelList[dupCheck] == channelLoop)
1476 {
1477 /* This channel is duplicated */
1478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1479 "%s : found duplicated channel %d",
1480 __func__, channelLoop);
1481 break;
1482 }
1483 }
1484 if (dupCheck == unsafeChannelCount)
1485 {
c_hpothu8de53e42014-08-22 15:00:37 +05301486 int ii;
1487 for(ii=0; ii<NUM_20MHZ_RF_CHANNELS; ii++)
1488 {
1489 if (channelLoop == safeChannels[ii].channelNumber)
1490 {
1491 unsafeChannelList[unsafeChannelCount] = channelLoop;
1492 unsafeChannelCount++;
1493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1494 "%s : unsafe channel %d, count %d",
1495 __func__,
1496 channelLoop, unsafeChannelCount);
1497 }
1498 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001499 }
1500 else
1501 {
1502 /* DUP, do nothing */
1503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1504 "%s : duplicated channel %d",
1505 __func__, channelLoop);
1506 }
1507 }
1508 }
1509 /* Update unsafe channel cache
1510 * WCN Platform Driver cache */
1511 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1512 unsafeChannelCount);
1513
1514 /* Store into local cache
1515 * Start with STA and later start SAP
1516 * in this scenario, local cache will be used */
1517 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1518 unsafeChannelList,
1519 unsafeChannelCount);
1520
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001521 /* generate vendor specific event */
1522 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1523 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1524 {
1525 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1526 chAvoidInd->avoidFreqRange[i].startFreq;
1527 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1528 chAvoidInd->avoidFreqRange[i].endFreq;
1529 }
1530 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1531
1532 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1533
Leo Chang0b0e45a2013-12-15 15:18:55 -08001534 /* Get SAP context first
1535 * SAP and P2PGO would not concurrent */
1536 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
Kanchanapally, Vidyullatha7af0be12014-12-10 13:54:38 +05301537 if ((pHostapdAdapter) &&
1538 (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) &&
1539 (unsafeChannelCount))
Leo Chang0b0e45a2013-12-15 15:18:55 -08001540 {
1541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1542 "%s : Current operation channel %d",
1543 __func__,
1544 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1545 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1546 {
1547 if (((unsafeChannelList[channelLoop] ==
1548 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1549 (AUTO_CHANNEL_SELECT ==
1550 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1551 {
1552 /* current operating channel is un-safe channel
1553 * restart driver */
1554 hdd_hostapd_stop(pHostapdAdapter->dev);
Neelansh Mittaledafed22014-09-04 18:54:39 +05301555 /* On LE, this event is handled by wlan-services to restart SAP.
1556 On android, this event would be ignored. */
1557 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND, NULL, 0);
Leo Chang0b0e45a2013-12-15 15:18:55 -08001558 break;
1559 }
1560 }
1561 }
1562
1563 return;
1564}
1565
1566#endif /* FEATURE_WLAN_CH_AVOID */
1567
Jeff Johnson295189b2012-06-20 16:38:30 -07001568int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301569static __iw_softap_setparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 struct iw_request_info *info,
1571 union iwreq_data *wrqu, char *extra)
1572{
1573 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001574 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 int *value = (int *)extra;
1576 int sub_cmd = value[0];
1577 int set_value = value[1];
1578 eHalStatus status;
1579 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001580 v_CONTEXT_t pVosContext;
1581
1582 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1583 {
1584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1585 "%s: either hostapd Adapter is null or HDD ctx is null",
1586 __func__);
1587 return -1;
1588 }
1589
1590 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1591 if (!hHal)
1592 {
1593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1594 "%s: Hal ctx is null", __func__);
1595 return -1;
1596 }
1597
1598 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1599 if (!pVosContext)
1600 {
1601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1602 "%s: Vos ctx is null", __func__);
1603 return -1;
1604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001605
1606 switch(sub_cmd)
1607 {
1608
1609 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001610 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 {
1612 ret = -EIO;
1613 }
1614 break;
1615
1616 case QCSAP_PARAM_ACL_MODE:
1617 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1618 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1619 {
1620 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1621 ret = -EINVAL;
1622 }
1623 else
1624 {
1625 WLANSAP_SetMode(pVosContext, set_value);
1626 }
1627 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301628
1629 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1630 if ((0 != set_value) && (1 != set_value))
1631 {
1632 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1633 ret = -EINVAL;
1634 }
1635 else
1636 {
1637 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1638 }
1639 break;
1640
Jeff Johnson295189b2012-06-20 16:38:30 -07001641 case QCSAP_PARAM_MAX_ASSOC:
1642 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1643 {
1644 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1645 ret = -EINVAL;
1646 }
1647 else
1648 {
1649 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1650 {
1651 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1652 "Setting it to max allowed and continuing"),
1653 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1654 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1655 }
1656 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1657 set_value, NULL, eANI_BOOLEAN_FALSE);
1658 if ( status != eHAL_STATUS_SUCCESS )
1659 {
1660 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1661 status);
1662 ret = -EIO;
1663 }
1664 }
1665 break;
1666
1667 case QCSAP_PARAM_HIDE_SSID:
1668 {
1669 eHalStatus status = eHAL_STATUS_SUCCESS;
1670 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1671 if(eHAL_STATUS_SUCCESS != status)
1672 {
1673 hddLog(VOS_TRACE_LEVEL_ERROR,
1674 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001675 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 return status;
1677 }
1678 break;
1679 }
1680
Leo Chang614d2072013-08-22 14:59:44 -07001681 case QCSAP_PARAM_SET_MC_RATE:
1682 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001683 tSirRateUpdateInd *rateUpdate;
1684
1685 rateUpdate = (tSirRateUpdateInd *)
1686 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1687 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001688 {
1689 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001690 "%s: SET_MC_RATE indication alloc fail", __func__);
1691 ret = -1;
1692 break;
1693 }
1694 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1695
1696 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1697 /* Ignore unicast */
1698 rateUpdate->ucastDataRate = -1;
1699 rateUpdate->mcastDataRate24GHz = set_value;
1700 rateUpdate->mcastDataRate5GHz = set_value;
1701 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1702 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1703 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1704 if (eHAL_STATUS_SUCCESS != status)
1705 {
1706 hddLog(VOS_TRACE_LEVEL_ERROR,
1707 "%s: SET_MC_RATE failed", __func__);
1708 vos_mem_free(rateUpdate);
1709 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001710 }
1711 break;
1712 }
1713
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 default:
1715 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1716 sub_cmd, set_value);
1717 ret = -EINVAL;
1718 break;
1719 }
1720
1721 return ret;
1722}
1723
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301724int
1725static iw_softap_setparam(struct net_device *dev,
1726 struct iw_request_info *info,
1727 union iwreq_data *wrqu, char *extra)
1728{
1729 int ret;
1730
1731 vos_ssr_protect(__func__);
1732 ret = __iw_softap_setparam(dev, info, wrqu, extra);
1733 vos_ssr_unprotect(__func__);
1734
1735 return ret;
1736}
Jeff Johnson295189b2012-06-20 16:38:30 -07001737
1738int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301739static __iw_softap_getparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001740 struct iw_request_info *info,
1741 union iwreq_data *wrqu, char *extra)
1742{
1743 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1744 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Girish Gowliaf15a982014-09-18 11:17:20 +05301745 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 int *value = (int *)extra;
1747 int sub_cmd = value[0];
1748 eHalStatus status;
1749 int ret = 0; /* success */
1750 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1751
1752 switch (sub_cmd)
1753 {
1754 case QCSAP_PARAM_MAX_ASSOC:
1755 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1756 if (eHAL_STATUS_SUCCESS != status)
1757 {
c_hpothuffdb5272013-10-02 16:42:35 +05301758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1759 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001760 ret = -EIO;
1761 }
Girish Gowliaf15a982014-09-18 11:17:20 +05301762
1763#ifdef WLAN_SOFTAP_VSTA_FEATURE
1764 if (pHddCtx->cfg_ini->fEnableVSTASupport)
1765 {
1766 if (*value > VSTA_NUM_ASSOC_STA)
1767 {
1768 *value = VSTA_NUM_ASSOC_STA;
1769 }
1770 if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) &&
1771 (*value > (VSTA_NUM_ASSOC_STA -
1772 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA))))
1773 {
1774 *value = (VSTA_NUM_ASSOC_STA -
1775 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA));
1776 }
1777 }
1778 else
1779#endif
1780 {
1781 if (*value > NUM_ASSOC_STA)
1782 {
1783 *value = NUM_ASSOC_STA;
1784 }
1785 if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) &&
1786 (*value > (NUM_ASSOC_STA -
1787 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA))))
1788 {
1789 *value = (NUM_ASSOC_STA -
1790 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA));
1791 }
1792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 break;
1794
1795 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001796 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 {
c_hpothuffdb5272013-10-02 16:42:35 +05301798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 ret = -EIO;
1801 }
1802 *value = 0;
1803 break;
1804
Jeff Johnson43971f52012-07-17 12:26:56 -07001805 case QCSAP_PARAM_GET_WLAN_DBG:
1806 {
1807 vos_trace_display();
1808 *value = 0;
1809 break;
1810 }
1811
1812 case QCSAP_PARAM_AUTO_CHANNEL:
1813 {
1814 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1815 break;
1816 }
1817
Jeff Johnson295189b2012-06-20 16:38:30 -07001818 default:
1819 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1820 ret = -EINVAL;
1821 break;
1822
1823 }
1824
1825 return ret;
1826}
1827
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301828int
1829static iw_softap_getparam(struct net_device *dev,
1830 struct iw_request_info *info,
1831 union iwreq_data *wrqu, char *extra)
1832{
1833 int ret;
1834
1835 vos_ssr_protect(__func__);
1836 ret = __iw_softap_getparam(dev, info, wrqu, extra);
1837 vos_ssr_unprotect(__func__);
1838
1839 return ret;
1840}
Jeff Johnson295189b2012-06-20 16:38:30 -07001841/* Usage:
1842 BLACK_LIST = 0
1843 WHITE_LIST = 1
1844 ADD MAC = 0
1845 REMOVE MAC = 1
1846
1847 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1848 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1849 while using this ioctl
1850
1851 Syntax:
1852 iwpriv softap.0 modify_acl
1853 <6 octet mac addr> <list type> <cmd type>
1854
1855 Examples:
1856 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1857 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1858 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1859 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1860*/
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301861int __iw_softap_modify_acl(struct net_device *dev,
1862 struct iw_request_info *info,
1863 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001864{
1865 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1866 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1867 v_BYTE_t *value = (v_BYTE_t*)extra;
1868 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1869 int listType, cmd, i;
1870 int ret = 0; /* success */
1871
1872 ENTER();
1873 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1874 {
1875 pPeerStaMac[i] = *(value+i);
1876 }
1877 listType = (int)(*(value+i));
1878 i++;
1879 cmd = (int)(*(value+i));
1880
Arif Hussain24bafea2013-11-15 15:10:03 -08001881 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1882 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001883
1884 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1885 != VOS_STATUS_SUCCESS)
1886 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001887 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 ret = -EIO;
1889 }
1890 EXIT();
1891 return ret;
1892}
1893
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301894int iw_softap_modify_acl(struct net_device *dev,
1895 struct iw_request_info *info,
1896 union iwreq_data *wrqu, char *extra)
1897{
1898 int ret;
1899
1900 vos_ssr_protect(__func__);
1901 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
1902 vos_ssr_unprotect(__func__);
1903
1904 return ret;
1905}
1906
Jeff Johnson295189b2012-06-20 16:38:30 -07001907int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301908static __iw_softap_getchannel(struct net_device *dev,
1909 struct iw_request_info *info,
1910 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001911{
1912 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1913
Jeff Johnson43971f52012-07-17 12:26:56 -07001914 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001915
Jeff Johnson43971f52012-07-17 12:26:56 -07001916 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001917 return 0;
1918}
1919
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301920
Jeff Johnsone7245742012-09-05 17:12:55 -07001921int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301922static iw_softap_getchannel(struct net_device *dev,
1923 struct iw_request_info *info,
1924 union iwreq_data *wrqu, char *extra)
1925{
1926 int ret;
1927
1928 vos_ssr_protect(__func__);
1929 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
1930 vos_ssr_unprotect(__func__);
1931
1932 return ret;
1933}
1934
1935int
1936static __iw_softap_set_max_tx_power(struct net_device *dev,
1937 struct iw_request_info *info,
1938 union iwreq_data *wrqu, char *extra)
Jeff Johnsone7245742012-09-05 17:12:55 -07001939{
1940 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1941 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001942 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001943 int set_value;
1944 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1945 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1946
schang86c22c42013-03-13 18:41:24 -07001947 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001948 return -ENOMEM;
1949
Leo Changd37675a2013-08-01 13:19:45 -07001950 /* Assign correct slef MAC address */
1951 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1952 VOS_MAC_ADDR_SIZE);
1953 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1954 VOS_MAC_ADDR_SIZE);
1955
schang86c22c42013-03-13 18:41:24 -07001956 set_value = value[0];
1957 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1958 {
1959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001960 __func__);
schang86c22c42013-03-13 18:41:24 -07001961 return -EIO;
1962 }
1963
1964 return 0;
1965}
1966
1967int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301968static iw_softap_set_max_tx_power(struct net_device *dev,
1969 struct iw_request_info *info,
1970 union iwreq_data *wrqu, char *extra)
1971{
1972 int ret;
1973
1974 vos_ssr_protect(__func__);
1975 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
1976 vos_ssr_unprotect(__func__);
1977
1978 return ret;
1979}
1980
1981
1982int
1983static __iw_display_data_path_snapshot(struct net_device *dev,
1984 struct iw_request_info *info,
1985 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301986{
1987
1988 /* Function intitiating dumping states of
1989 * HDD(WMM Tx Queues)
1990 * TL State (with Per Client infor)
1991 * DXE Snapshot (Called at the end of TL Snapshot)
1992 */
1993 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1994 hddLog(LOGE, "%s: called for SAP",__func__);
1995 hdd_wmm_tx_snapshot(pHostapdAdapter);
Mihir Shete186171a2014-11-13 15:17:02 +05301996 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301997 return 0;
1998}
1999
2000int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302001static iw_display_data_path_snapshot(struct net_device *dev,
2002 struct iw_request_info *info,
2003 union iwreq_data *wrqu, char *extra)
2004{
2005 int ret;
2006
2007 vos_ssr_protect(__func__);
2008 ret = __iw_display_data_path_snapshot(dev, info, wrqu, extra);
2009 vos_ssr_unprotect(__func__);
2010
2011 return ret;
2012}
2013
2014int
2015static __iw_softap_set_tx_power(struct net_device *dev,
2016 struct iw_request_info *info,
2017 union iwreq_data *wrqu, char *extra)
schang86c22c42013-03-13 18:41:24 -07002018{
2019 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2020 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2021 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2022 int *value = (int *)extra;
2023 int set_value;
2024 ptSapContext pSapCtx = NULL;
2025
2026 if (NULL == value)
2027 return -ENOMEM;
2028
2029 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2030 if (NULL == pSapCtx)
2031 {
2032 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2033 "%s: Invalid SAP pointer from pvosGCtx", __func__);
2034 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07002035 }
2036
2037 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07002038 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07002039 {
schang86c22c42013-03-13 18:41:24 -07002040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07002041 __func__);
2042 return -EIO;
2043 }
2044
2045 return 0;
2046}
2047
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302048int
2049static iw_softap_set_tx_power(struct net_device *dev,
2050 struct iw_request_info *info,
2051 union iwreq_data *wrqu, char *extra)
2052{
2053 int ret;
2054
2055 vos_ssr_protect(__func__);
2056 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
2057 vos_ssr_unprotect(__func__);
2058
2059 return ret;
2060}
2061
Kiet Lambcf38522013-10-26 18:28:27 +05302062/**---------------------------------------------------------------------------
2063
2064 \brief iw_softap_set_trafficmonitor() -
2065 This function dynamically enable/disable traffic monitor functonality
2066 the command iwpriv wlanX setTrafficMon <value>.
2067
2068 \param - dev - Pointer to the net device.
2069 - addr - Pointer to the sockaddr.
2070 \return - 0 for success, non zero for failure
2071
2072 --------------------------------------------------------------------------*/
2073
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302074static int __iw_softap_set_trafficmonitor(struct net_device *dev,
2075 struct iw_request_info *info,
2076 union iwreq_data *wrqu, char *extra)
Kiet Lambcf38522013-10-26 18:28:27 +05302077{
2078 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik128a0bb2014-08-07 20:24:54 +05302079 int *isSetTrafficMon = (int *)extra;
Kiet Lambcf38522013-10-26 18:28:27 +05302080 hdd_context_t *pHddCtx;
2081 int status;
2082
2083 if (NULL == pAdapter)
2084 {
2085 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2086 "%s: HDD adapter is Null", __func__);
2087 return -ENODEV;
2088 }
2089
2090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2091
2092 status = wlan_hdd_validate_context(pHddCtx);
2093
2094 if (0 != status)
2095 {
2096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2097 "%s: HDD context is not valid", __func__);
2098 return status;
2099 }
2100
2101 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
2102
2103 if (NULL == isSetTrafficMon)
2104 {
2105 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2106 "%s: Invalid SAP pointer from extra", __func__);
2107 return -ENOMEM;
2108 }
2109
2110 if (TRUE == *isSetTrafficMon)
2111 {
2112 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
2113 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2116 "%s: failed to Start Traffic Monitor timer ", __func__ );
2117 return -EIO;
2118 }
2119 }
2120 else if (FALSE == *isSetTrafficMon)
2121 {
2122 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
2123 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
2124 {
2125 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2126 "%s: failed to Stop Traffic Monitor timer ", __func__ );
2127 return -EIO;
2128 }
2129
2130 }
2131 return 0;
2132}
2133
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302134static int iw_softap_set_trafficmonitor(struct net_device *dev,
2135 struct iw_request_info *info,
2136 union iwreq_data *wrqu, char *extra)
2137{
2138 int ret;
2139
2140 vos_ssr_protect(__func__);
2141 ret = __iw_softap_set_trafficmonitor(dev, info, wrqu, extra);
2142 vos_ssr_unprotect(__func__);
2143
2144 return ret;
2145}
2146
Jeff Johnson295189b2012-06-20 16:38:30 -07002147#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
2148
2149int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302150static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
2151 struct iw_request_info *info,
2152 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002153{
2154 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05302155 hdd_station_info_t *pStaInfo = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002156 char *buf;
2157 int cnt = 0;
2158 int left;
2159 int ret = 0;
2160 /* maclist_index must be u32 to match userspace */
2161 u32 maclist_index;
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05302162 v_CONTEXT_t pVosContext = NULL;
2163 ptSapContext pSapCtx = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002164 /*
2165 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
2166 * number, and even numbered iocts are supposed to have "set"
2167 * semantics. Hence the wireless extensions support in the kernel
2168 * won't correctly copy the result to userspace, so the ioctl
2169 * handler itself must copy the data. Output format is 32-bit
2170 * record length, followed by 0 or more 6-byte STA MAC addresses.
2171 *
2172 * Further note that due to the incorrect semantics, the "iwpriv"
2173 * userspace application is unable to correctly invoke this API,
2174 * hence it is not registered in the hostapd_private_args. This
2175 * API can only be invoked by directly invoking the ioctl() system
2176 * call.
2177 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002178
Jeff Johnson224f3702014-03-26 11:09:47 -07002179 /* make sure userspace allocated a reasonable buffer size */
2180 if (wrqu->data.length < sizeof(maclist_index)) {
2181 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
2182 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07002183 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002184
Jeff Johnson224f3702014-03-26 11:09:47 -07002185 /* allocate local buffer to build the response */
2186 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
2187 if (!buf) {
2188 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
2189 return -ENOMEM;
2190 }
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05302191 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2192 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2193 if(pSapCtx == NULL){
2194 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2195 FL("psapCtx is NULL"));
2196 return -EFAULT;
2197 }
2198 pStaInfo = pSapCtx->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07002199 /* start indexing beyond where the record count will be written */
2200 maclist_index = sizeof(maclist_index);
2201 left = wrqu->data.length - maclist_index;
2202
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05302203 spin_lock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002204 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
2205 if ((pStaInfo[cnt].isUsed) &&
2206 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
2207 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
2208 VOS_MAC_ADDR_SIZE);
2209 maclist_index += VOS_MAC_ADDR_SIZE;
2210 left -= VOS_MAC_ADDR_SIZE;
2211 }
2212 cnt++;
2213 }
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05302214 spin_unlock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002215
2216 *((u32 *)buf) = maclist_index;
2217 wrqu->data.length = maclist_index;
2218 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
2219 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
2220 ret = -EFAULT;
2221 }
2222 kfree(buf);
2223 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002224}
2225
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302226int
2227static iw_softap_getassoc_stamacaddr(struct net_device *dev,
2228 struct iw_request_info *info,
2229 union iwreq_data *wrqu, char *extra)
2230{
2231 int ret;
2232
2233 vos_ssr_protect(__func__);
2234 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
2235 vos_ssr_unprotect(__func__);
2236
2237 return ret;
2238}
2239
Jeff Johnson295189b2012-06-20 16:38:30 -07002240/* Usage:
2241 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
2242 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
2243 while using this ioctl
2244
2245 Syntax:
2246 iwpriv softap.0 disassoc_sta <6 octet mac address>
2247
2248 e.g.
2249 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
2250 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
2251*/
2252
2253int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302254static __iw_softap_disassoc_sta(struct net_device *dev,
2255 struct iw_request_info *info,
2256 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002257{
2258 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2259 v_U8_t *peerMacAddr;
2260
2261 ENTER();
c.wang2074a422016-04-13 11:24:16 +08002262
2263 if (!capable(CAP_NET_ADMIN)) {
2264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2265 FL("permission check failed"));
2266 return -EPERM;
2267 }
2268
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302269 /* iwpriv tool or framework calls this ioctl with
2270 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302272 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002273
Arif Hussain24bafea2013-11-15 15:10:03 -08002274 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
2275 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002276 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
2277 EXIT();
2278 return 0;
2279}
2280
2281int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302282static iw_softap_disassoc_sta(struct net_device *dev,
2283 struct iw_request_info *info,
2284 union iwreq_data *wrqu, char *extra)
2285{
2286 int ret;
2287
2288 vos_ssr_protect(__func__);
2289 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
2290 vos_ssr_unprotect(__func__);
2291
2292 return ret;
2293}
2294
2295int
2296static __iw_softap_ap_stats(struct net_device *dev,
2297 struct iw_request_info *info,
2298 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002299{
2300 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2301 WLANTL_TRANSFER_STA_TYPE statBuffer;
2302 char *pstatbuf;
Girish Gowlif3769802014-06-16 21:17:16 +05302303 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07002304
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002305 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07002306 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
2307 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002308
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302309 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07002310 if(NULL == pstatbuf) {
2311 hddLog(LOG1, "unable to allocate memory");
2312 return -ENOMEM;
2313 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302314
2315 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07002316 "RUF=%d RMF=%d RBF=%d "
2317 "RUB=%d RMB=%d RBB=%d "
2318 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302319 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002320 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2321 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2322 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2323 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2324 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2325 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002326
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302327 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002328 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2329 kfree(pstatbuf);
2330 return -EFAULT;
2331 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302332
2333 strlcpy(extra, pstatbuf, len);
2334 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002335 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 return 0;
2337}
2338
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302339int
2340static iw_softap_ap_stats(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002341 struct iw_request_info *info,
2342 union iwreq_data *wrqu, char *extra)
2343{
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302344 int ret;
2345
2346 vos_ssr_protect(__func__);
2347 ret = __iw_softap_ap_stats(dev, info, wrqu, extra);
2348 vos_ssr_unprotect(__func__);
2349
2350 return ret;
2351}
2352
2353static int __iw_softap_set_channel_range(struct net_device *dev,
2354 struct iw_request_info *info,
2355 union iwreq_data *wrqu, char *extra)
2356{
Jeff Johnson295189b2012-06-20 16:38:30 -07002357 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2358 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002359 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002360
2361 int *value = (int *)extra;
2362 int startChannel = value[0];
2363 int endChannel = value[1];
2364 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002365 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 int ret = 0; /* success */
2367
Hanumantha Reddy Pothula7a3bd782015-10-28 16:14:02 -07002368 if (!capable(CAP_NET_ADMIN))
2369 {
2370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2371 FL("permission check failed"));
2372 return -EPERM;
2373 }
2374
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2376 if(status != VOS_STATUS_SUCCESS)
2377 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002378 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 startChannel,endChannel, band);
2380 ret = -EINVAL;
2381 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002382
2383 pHddCtx->is_dynamic_channel_range_set = 1;
2384
Jeff Johnson295189b2012-06-20 16:38:30 -07002385 return ret;
2386}
2387
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302388static int iw_softap_set_channel_range(struct net_device *dev,
2389 struct iw_request_info *info,
2390 union iwreq_data *wrqu, char *extra)
2391{
2392 int ret;
2393
2394 vos_ssr_protect(__func__);
2395 ret = __iw_softap_set_channel_range(dev, info, wrqu, extra);
2396 vos_ssr_unprotect(__func__);
2397
2398 return ret;
2399}
2400
2401
2402int __iw_softap_get_channel_list(struct net_device *dev,
2403 struct iw_request_info *info,
2404 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002405{
2406 v_U32_t num_channels = 0;
2407 v_U8_t i = 0;
2408 v_U8_t bandStartChannel = RF_CHAN_1;
2409 v_U8_t bandEndChannel = RF_CHAN_165;
2410 v_U32_t temp_num_channels = 0;
2411 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2412 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2413 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002415 eCsrBand curBand = eCSR_BAND_ALL;
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002417
2418 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2419 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002420 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002421 return -EIO;
2422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 wrqu->data.length = sizeof(tChannelListInfo);
2424 ENTER();
2425
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002426 if (eCSR_BAND_24 == curBand)
2427 {
2428 bandStartChannel = RF_CHAN_1;
2429 bandEndChannel = RF_CHAN_14;
2430 }
2431 else if (eCSR_BAND_5G == curBand)
2432 {
2433 bandStartChannel = RF_CHAN_36;
2434 bandEndChannel = RF_CHAN_165;
2435 }
2436
Arif Hussain6d2a3322013-11-17 19:50:10 -08002437 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302438 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002439 bandStartChannel, bandEndChannel );
2440
Jeff Johnson295189b2012-06-20 16:38:30 -07002441 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2442 {
2443 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2444 {
2445 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2446 num_channels++;
2447 }
2448 }
2449
2450 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2451
2452 temp_num_channels = num_channels;
2453
2454 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2455 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302456 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002457 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002458 }
2459
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302460 if(REGDOMAIN_FCC == domainIdCurrentSoftap &&
2461 pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC )
Jeff Johnson295189b2012-06-20 16:38:30 -07002462 {
2463 for(i = 0; i < temp_num_channels; i++)
2464 {
2465
2466 if((channel_list->channels[i] > 35) &&
2467 (channel_list->channels[i] < 49))
2468 {
2469 vos_mem_move(&channel_list->channels[i],
2470 &channel_list->channels[i+1],
2471 temp_num_channels - (i-1));
2472 num_channels--;
2473 temp_num_channels--;
2474 i--;
2475 }
2476 }
2477 }
2478
Arif Hussain6d2a3322013-11-17 19:50:10 -08002479 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002480
2481 if (num_channels > IW_MAX_FREQUENCIES)
2482 {
2483 num_channels = IW_MAX_FREQUENCIES;
2484 }
2485
2486 channel_list->num_channels = num_channels;
2487 EXIT();
2488
2489 return 0;
2490}
2491
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302492int iw_softap_get_channel_list(struct net_device *dev,
2493 struct iw_request_info *info,
2494 union iwreq_data *wrqu, char *extra)
2495{
2496 int ret;
2497
2498 vos_ssr_protect(__func__);
2499 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
2500 vos_ssr_unprotect(__func__);
2501
2502 return ret;
2503}
2504
2505static
2506int __iw_get_genie(struct net_device *dev,
2507 struct iw_request_info *info,
2508 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002509{
2510 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2511 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2512 eHalStatus status;
2513 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2514 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2515 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002516 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2518 status = WLANSap_getstationIE_information(pVosContext,
2519 &length,
2520 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002521 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2522 if (wrqu->data.length < length ||
2523 copy_to_user(wrqu->data.pointer,
2524 (v_VOID_t*)genIeBytes, length))
2525 {
2526 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2527 return -EFAULT;
2528 }
2529 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002530
Arif Hussain6d2a3322013-11-17 19:50:10 -08002531 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002532
2533
2534 EXIT();
2535 return 0;
2536}
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302537
2538static
2539int iw_get_genie(struct net_device *dev,
2540 struct iw_request_info *info,
2541 union iwreq_data *wrqu, char *extra)
2542{
2543 int ret;
2544
2545 vos_ssr_protect(__func__);
2546 ret = __iw_get_genie(dev, info, wrqu, extra);
2547 vos_ssr_unprotect(__func__);
2548
2549 return ret;
2550}
2551
2552static
2553int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2554 struct iw_request_info *info,
2555 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002556{
2557 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002558 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002559 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2560 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002561
Arif Hussain6d2a3322013-11-17 19:50:10 -08002562 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002563 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2564
2565 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2566 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2567 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2568 WPSPBCProbeReqIEs.probeReqIELen);
2569 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2570 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2571 sizeof(v_MACADDR_t));
2572 if (copy_to_user(wrqu->data.pointer,
2573 (void *)&WPSPBCProbeReqIEs,
2574 sizeof(WPSPBCProbeReqIEs)))
2575 {
2576 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2577 return -EFAULT;
2578 }
2579 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002580 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002581 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002582 up(&pHddApCtx->semWpsPBCOverlapInd);
2583 EXIT();
2584 return 0;
2585}
2586
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302587static
2588int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2589 struct iw_request_info *info,
2590 union iwreq_data *wrqu, char *extra)
2591{
2592 int ret;
2593
2594 vos_ssr_protect(__func__);
2595 ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra);
2596 vos_ssr_unprotect(__func__);
2597
2598 return ret;
2599}
2600
Jeff Johnson295189b2012-06-20 16:38:30 -07002601/**---------------------------------------------------------------------------
2602
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302603 \brief __iw_set_auth_hostap() -
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 This function sets the auth type received from the wpa_supplicant.
2605
2606 \param - dev - Pointer to the net device.
2607 - info - Pointer to the iw_request_info.
2608 - wrqu - Pointer to the iwreq_data.
2609 - extra - Pointer to the data.
2610 \return - 0 for success, non zero for failure
2611
2612 --------------------------------------------------------------------------*/
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302613int __iw_set_auth_hostap(struct net_device *dev,
2614 struct iw_request_info *info,
2615 union iwreq_data *wrqu,char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002616{
2617 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2618 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2619
2620 ENTER();
2621 switch(wrqu->param.flags & IW_AUTH_INDEX)
2622 {
2623 case IW_AUTH_TKIP_COUNTERMEASURES:
2624 {
2625 if(wrqu->param.value) {
2626 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2627 "Counter Measure started %d", wrqu->param.value);
2628 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2629 }
2630 else {
2631 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2632 "Counter Measure stopped=%d", wrqu->param.value);
2633 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2634 }
2635
2636 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2637 wrqu->param.value);
2638 }
2639 break;
2640
2641 default:
2642
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002643 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002644 wrqu->param.flags & IW_AUTH_INDEX);
2645 break;
2646 }
2647
2648 EXIT();
2649 return 0;
2650}
2651
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302652int iw_set_auth_hostap(struct net_device *dev,
2653 struct iw_request_info *info,
2654 union iwreq_data *wrqu,char *extra)
2655{
2656 int ret;
2657
2658 vos_ssr_protect(__func__);
2659 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
2660 vos_ssr_unprotect(__func__);
2661
2662 return ret;
2663}
2664
2665static int __iw_set_ap_encodeext(struct net_device *dev,
2666 struct iw_request_info *info,
2667 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002668{
2669 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2670 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2671 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002672 int retval = 0;
2673 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002674 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2675 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2676 int key_index;
2677 struct iw_point *encoding = &wrqu->encoding;
2678 tCsrRoamSetKey setKey;
2679// tCsrRoamRemoveKey RemoveKey;
2680 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002681
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 ENTER();
2683
2684 key_index = encoding->flags & IW_ENCODE_INDEX;
2685
2686 if(key_index > 0) {
2687
2688 /*Convert from 1-based to 0-based keying*/
2689 key_index--;
2690 }
2691 if(!ext->key_len) {
2692#if 0
2693 /*Set the encrytion type to NONE*/
2694#if 0
2695 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2696#endif
2697
2698 RemoveKey.keyId = key_index;
2699 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2700 /*Key direction for group is RX only*/
2701 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2702 }
2703 else {
2704 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2705 }
2706 switch(ext->alg)
2707 {
2708 case IW_ENCODE_ALG_NONE:
2709 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2710 break;
2711 case IW_ENCODE_ALG_WEP:
2712 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2713 break;
2714 case IW_ENCODE_ALG_TKIP:
2715 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002716 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002717 case IW_ENCODE_ALG_CCMP:
2718 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2719 break;
2720 default:
2721 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2722 break;
2723 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002724 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 -07002725 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002727 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002728 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002729 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2730 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002731 {
2732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002733 __LINE__, vstatus );
2734 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002735 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002736#endif
2737 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002738
Jeff Johnson43971f52012-07-17 12:26:56 -07002739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002740
2741 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2742
2743 setKey.keyId = key_index;
2744 setKey.keyLength = ext->key_len;
2745
2746 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2747 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2748 }
2749
2750 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2751 /*Key direction for group is RX only*/
2752 setKey.keyDirection = eSIR_RX_ONLY;
2753 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2754 }
2755 else {
2756
2757 setKey.keyDirection = eSIR_TX_RX;
2758 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2759 }
2760 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2761 {
2762 setKey.keyDirection = eSIR_TX_DEFAULT;
2763 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2764 }
2765
2766 /*For supplicant pae role is zero*/
2767 setKey.paeRole = 0;
2768
2769 switch(ext->alg)
2770 {
2771 case IW_ENCODE_ALG_NONE:
2772 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2773 break;
2774
2775 case IW_ENCODE_ALG_WEP:
2776 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2777 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002778 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002779 break;
2780
2781 case IW_ENCODE_ALG_TKIP:
2782 {
2783 v_U8_t *pKey = &setKey.Key[0];
2784
2785 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2786
2787 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2788
2789 /*Supplicant sends the 32bytes key in this order
2790
2791 |--------------|----------|----------|
2792 | Tk1 |TX-MIC | RX Mic |
2793 |--------------|----------|----------|
2794 <---16bytes---><--8bytes--><--8bytes-->
2795
2796 */
2797 /*Sme expects the 32 bytes key to be in the below order
2798
2799 |--------------|----------|----------|
2800 | Tk1 |RX-MIC | TX Mic |
2801 |--------------|----------|----------|
2802 <---16bytes---><--8bytes--><--8bytes-->
2803 */
2804 /* Copy the Temporal Key 1 (TK1) */
2805 vos_mem_copy(pKey,ext->key,16);
2806
2807 /*Copy the rx mic first*/
2808 vos_mem_copy(&pKey[16],&ext->key[24],8);
2809
2810 /*Copy the tx mic */
2811 vos_mem_copy(&pKey[24],&ext->key[16],8);
2812
2813 }
2814 break;
2815
2816 case IW_ENCODE_ALG_CCMP:
2817 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2818 break;
2819
2820 default:
2821 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2822 break;
2823 }
2824
2825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302826 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002827 setKey.keyId);
2828 for(i=0; i< ext->key_len; i++)
2829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2830 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002831
2832 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2833 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002834 {
2835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002836 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2837 retval = -EINVAL;
2838 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002839
Jeff Johnson43971f52012-07-17 12:26:56 -07002840 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002841}
Jeff Johnson43971f52012-07-17 12:26:56 -07002842
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302843static int iw_set_ap_encodeext(struct net_device *dev,
2844 struct iw_request_info *info,
2845 union iwreq_data *wrqu, char *extra)
2846{
2847 int ret;
2848
2849 vos_ssr_protect(__func__);
2850 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
2851 vos_ssr_unprotect(__func__);
2852
2853 return ret;
2854}
Jeff Johnson43971f52012-07-17 12:26:56 -07002855
Jeff Johnson295189b2012-06-20 16:38:30 -07002856static int iw_set_ap_mlme(struct net_device *dev,
2857 struct iw_request_info *info,
2858 union iwreq_data *wrqu,
2859 char *extra)
2860{
2861#if 0
2862 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2863 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2864
2865 ENTER();
2866
2867 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2868 switch (mlme->cmd) {
2869 case IW_MLME_DISASSOC:
2870 case IW_MLME_DEAUTH:
2871 hddLog(LOG1, "Station disassociate");
2872 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2873 {
2874 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2875
2876 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2877 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2878
2879 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2880
2881 //clear all the reason codes
2882 if (status != 0)
2883 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002884 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002885 }
2886
2887 netif_stop_queue(dev);
2888 netif_carrier_off(dev);
2889 }
2890 else
2891 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002892 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 -07002893 }
2894 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002895 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002896 return -EINVAL;
2897 }//end of switch
2898 EXIT();
2899#endif
2900 return 0;
2901// return status;
2902}
2903
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302904static int __iw_get_ap_rts_threshold(struct net_device *dev,
2905 struct iw_request_info *info,
2906 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002907{
2908 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2909 v_U32_t status = 0;
2910
2911 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2912
2913 return status;
2914}
2915
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302916static int iw_get_ap_rts_threshold(struct net_device *dev,
2917 struct iw_request_info *info,
2918 union iwreq_data *wrqu, char *extra)
2919{
2920 int ret;
2921
2922 vos_ssr_protect(__func__);
2923 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
2924 vos_ssr_unprotect(__func__);
2925
2926 return ret;
2927}
2928
2929static int __iw_get_ap_frag_threshold(struct net_device *dev,
2930 struct iw_request_info *info,
2931 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002932{
2933 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2934 v_U32_t status = 0;
2935
2936 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2937
2938 return status;
2939}
2940
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302941static int iw_get_ap_frag_threshold(struct net_device *dev,
2942 struct iw_request_info *info,
2943 union iwreq_data *wrqu, char *extra)
2944{
2945 int ret;
2946
2947 vos_ssr_protect(__func__);
2948 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
2949 vos_ssr_unprotect(__func__);
2950
2951 return ret;
2952}
2953
2954static int __iw_get_ap_freq(struct net_device *dev,
2955 struct iw_request_info *info,
2956 struct iw_freq *fwrq, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002957{
Jeff Johnsone7245742012-09-05 17:12:55 -07002958 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002959 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2960 tHalHandle hHal;
2961 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002962 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002963
2964 ENTER();
2965
2966 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2968 "%s:LOGP in Progress. Ignore!!!",__func__);
2969 return status;
2970 }
2971
2972 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2973 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2974
2975 if(pHostapdState->bssState == BSS_STOP )
2976 {
2977 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2978 != eHAL_STATUS_SUCCESS)
2979 {
c_hpothuffdb5272013-10-02 16:42:35 +05302980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2981 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 return -EIO;
2983 }
2984 else
2985 {
2986 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002987 if( TRUE == status)
2988 {
2989 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2990 * iwlist & iwconfig command shows frequency into proper
2991 * format (2.412 GHz instead of 246.2 MHz)*/
2992 fwrq->m = freq;
2993 fwrq->e = MHZ;
2994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002995 }
2996 }
2997 else
2998 {
2999 channel = pHddApCtx->operatingChannel;
3000 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07003001 if( TRUE == status)
3002 {
3003 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
3004 * iwlist & iwconfig command shows frequency into proper
3005 * format (2.412 GHz instead of 246.2 MHz)*/
3006 fwrq->m = freq;
3007 fwrq->e = MHZ;
3008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003009 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003010 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003011}
3012
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303013static int iw_get_ap_freq(struct net_device *dev,
3014 struct iw_request_info *info,
3015 struct iw_freq *fwrq, char *extra)
3016{
3017 int ret;
3018
3019 vos_ssr_protect(__func__);
3020 ret = __iw_get_ap_freq(dev, info, fwrq, extra);
3021 vos_ssr_unprotect(__func__);
3022
3023 return ret;
3024}
3025
3026static int __iw_get_mode(struct net_device *dev,
3027 struct iw_request_info *info,
3028 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303029{
3030 int status = 0;
3031
3032 wrqu->mode = IW_MODE_MASTER;
3033
3034 return status;
3035}
3036
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303037static int iw_get_mode(struct net_device *dev,
3038 struct iw_request_info *info,
3039 union iwreq_data *wrqu, char *extra)
3040{
3041 int ret;
3042
3043 vos_ssr_protect(__func__);
3044 ret = __iw_get_mode(dev, info, wrqu, extra);
3045 vos_ssr_unprotect(__func__);
3046
3047 return ret;
3048}
3049
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303050static int __iw_softap_setwpsie(struct net_device *dev,
3051 struct iw_request_info *info,
3052 union iwreq_data *wrqu,
3053 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003054{
3055 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3056 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3057 hdd_hostapd_state_t *pHostapdState;
3058 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003059 u_int8_t *wps_genie;
3060 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07003061 u_int8_t *pos;
3062 tpSap_WPSIE pSap_WPSIe;
3063 u_int8_t WPSIeType;
3064 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05303065 struct iw_point s_priv_data;
Linux Build Service Account63485362015-04-02 04:07:29 -07003066 int ret = 0;
3067
Jeff Johnson295189b2012-06-20 16:38:30 -07003068 ENTER();
3069
c.wang72f31ce2016-04-13 11:18:24 +08003070 if (!capable(CAP_NET_ADMIN)) {
3071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3072 FL("permission check failed"));
3073 return -EPERM;
3074 }
3075
Girish Gowli07c05ec2014-06-17 20:47:03 +05303076 /* helper function to get iwreq_data with compat handling. */
3077 if (hdd_priv_get_data(&s_priv_data, wrqu))
3078 {
3079 return -EINVAL;
3080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003081
Girish Gowli07c05ec2014-06-17 20:47:03 +05303082 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
3083 {
3084 return -EINVAL;
3085 }
3086
3087 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
3088 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07003089
Girish Gowli86c471e2014-06-17 19:28:05 +05303090 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07003091 {
Girish Gowli86c471e2014-06-17 19:28:05 +05303092 hddLog(LOG1, "%s: failed to alloc memory "
3093 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07003094 return -EFAULT;
3095 }
3096
Girish Gowli86c471e2014-06-17 19:28:05 +05303097 fwps_genie = wps_genie;
3098
Jeff Johnson295189b2012-06-20 16:38:30 -07003099 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
3100 if (NULL == pSap_WPSIe)
3101 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003102 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07003103 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003104 return -ENOMEM;
3105 }
3106 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
3107
Arif Hussain6d2a3322013-11-17 19:50:10 -08003108 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 -07003109 WPSIeType = wps_genie[0];
3110 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
3111 {
3112 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
3113 wps_genie = wps_genie + 1;
3114 switch ( wps_genie[0] )
3115 {
3116 case DOT11F_EID_WPA:
3117 if (wps_genie[1] < 2 + 4)
3118 {
Linux Build Service Account63485362015-04-02 04:07:29 -07003119 ret = -EINVAL;
3120 goto exit;
Jeff Johnson295189b2012-06-20 16:38:30 -07003121 }
3122 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3123 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003124 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003125 pos = &wps_genie[6];
3126 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3127 {
3128 switch((u_int16_t)(*pos<<8) | *(pos+1))
3129 {
3130 case HDD_WPS_ELEM_VERSION:
3131 pos += 4;
3132 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003133 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003134 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
3135 pos += 1;
3136 break;
3137
3138 case HDD_WPS_ELEM_WPS_STATE:
3139 pos +=4;
3140 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003141 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003142 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
3143 pos += 1;
3144 break;
3145 case HDD_WPS_ELEM_APSETUPLOCK:
3146 pos += 4;
3147 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003148 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003149 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
3150 pos += 1;
3151 break;
3152 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3153 pos += 4;
3154 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003155 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003156 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
3157 pos += 1;
3158 break;
3159 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3160 pos += 4;
3161 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003162 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003163 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
3164 pos += 2;
3165 break;
3166 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3167 pos += 4;
3168 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003169 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003170 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
3171 pos += 2;
3172 break;
3173
3174 case HDD_WPS_ELEM_UUID_E:
3175 pos += 2;
3176 length = *pos<<8 | *(pos+1);
3177 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003178 if (length > sizeof(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E))
3179 {
3180 ret = -EINVAL;
3181 goto exit;
3182 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003183 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
3184 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
3185 pos += length;
3186 break;
3187 case HDD_WPS_ELEM_RF_BANDS:
3188 pos += 4;
3189 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003190 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003191 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
3192 pos += 1;
3193 break;
3194
3195 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08003196 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Linux Build Service Account63485362015-04-02 04:07:29 -07003197 ret = -EINVAL;
3198 goto exit;
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 }
3200 }
3201 }
3202 else {
3203 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003204 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003205 }
3206 break;
3207
3208 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003209 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Linux Build Service Account63485362015-04-02 04:07:29 -07003210 ret = -EINVAL;
3211 goto exit;
3212 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003213 }
3214 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
3215 {
3216 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
3217 wps_genie = wps_genie + 1;
3218 switch ( wps_genie[0] )
3219 {
3220 case DOT11F_EID_WPA:
3221 if (wps_genie[1] < 2 + 4)
3222 {
Linux Build Service Account63485362015-04-02 04:07:29 -07003223 ret = -EINVAL;
3224 goto exit;
Jeff Johnson295189b2012-06-20 16:38:30 -07003225 }
3226 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3227 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003228 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 pos = &wps_genie[6];
3230 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3231 {
3232 switch((u_int16_t)(*pos<<8) | *(pos+1))
3233 {
3234 case HDD_WPS_ELEM_VERSION:
3235 pos += 4;
3236 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003237 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003238 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
3239 pos += 1;
3240 break;
3241
3242 case HDD_WPS_ELEM_WPS_STATE:
3243 pos +=4;
3244 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003245 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
3247 pos += 1;
3248 break;
3249 case HDD_WPS_ELEM_APSETUPLOCK:
3250 pos += 4;
3251 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003252 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003253 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
3254 pos += 1;
3255 break;
3256 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3257 pos += 4;
3258 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003259 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003260 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
3261 pos += 1;
3262 break;
3263 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3264 pos += 4;
3265 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003266 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003267 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
3268 pos += 2;
3269 break;
3270 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3271 pos += 4;
3272 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003273 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003274 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
3275 pos += 2;
3276 break;
3277 case HDD_WPS_ELEM_RSP_TYPE:
3278 pos += 4;
3279 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003280 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07003281 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
3282 pos += 1;
3283 break;
3284 case HDD_WPS_ELEM_UUID_E:
3285 pos += 2;
3286 length = *pos<<8 | *(pos+1);
3287 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003288 if (length > (sizeof(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E)))
3289 {
3290 ret = -EINVAL;
3291 goto exit;
3292 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003293 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
3294 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
3295 pos += length;
3296 break;
3297
3298 case HDD_WPS_ELEM_MANUFACTURER:
3299 pos += 2;
3300 length = *pos<<8 | *(pos+1);
3301 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003302 if (length > (sizeof(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name)))
3303 {
3304 ret = -EINVAL;
3305 goto exit;
3306 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003307 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
3308 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
3309 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
3310 pos += length;
3311 break;
3312
3313 case HDD_WPS_ELEM_MODEL_NAME:
3314 pos += 2;
3315 length = *pos<<8 | *(pos+1);
3316 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003317 if (length > (sizeof(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text)))
3318 {
3319 ret = -EINVAL;
3320 goto exit;
3321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
3323 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
3324 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
3325 pos += length;
3326 break;
3327 case HDD_WPS_ELEM_MODEL_NUM:
3328 pos += 2;
3329 length = *pos<<8 | *(pos+1);
3330 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003331 if (length > (sizeof(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text)))
3332 {
3333 ret = -EINVAL;
3334 goto exit;
3335 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003336 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
3337 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
3338 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
3339 pos += length;
3340 break;
3341 case HDD_WPS_ELEM_SERIAL_NUM:
3342 pos += 2;
3343 length = *pos<<8 | *(pos+1);
3344 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003345 if (length > (sizeof(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text)))
3346 {
3347 ret = -EINVAL;
3348 goto exit;
3349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003350 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
3351 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
3352 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
3353 pos += length;
3354 break;
3355 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
3356 pos += 4;
3357 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003358 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003359 pos += 2;
3360
3361 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003362 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003363 pos += 4;
3364 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003365 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003366 pos += 2;
3367 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
3368 break;
3369 case HDD_WPS_ELEM_DEVICE_NAME:
3370 pos += 2;
3371 length = *pos<<8 | *(pos+1);
3372 pos += 2;
Linux Build Service Account63485362015-04-02 04:07:29 -07003373 if (length > (sizeof(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text)))
3374 {
3375 ret = -EINVAL;
3376 goto exit;
3377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003378 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
3379 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
3380 pos += length;
3381 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
3382 break;
3383 case HDD_WPS_ELEM_CONFIG_METHODS:
3384 pos += 4;
3385 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003386 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003387 pos += 2;
3388 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
3389 break;
3390
3391 case HDD_WPS_ELEM_RF_BANDS:
3392 pos += 4;
3393 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003394 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 pos += 1;
3396 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
3397 break;
3398 } // switch
3399 }
3400 }
3401 else
3402 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003403 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003404 }
3405
3406 } // switch
3407 }
3408 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
Linux Build Service Account63485362015-04-02 04:07:29 -07003409 if (halStatus != eHAL_STATUS_SUCCESS)
3410 ret = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3412 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3413 {
3414 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3415 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3416 WLANSAP_Update_WpsIe ( pVosContext );
3417 }
3418
Linux Build Service Account63485362015-04-02 04:07:29 -07003419exit:
Jeff Johnson295189b2012-06-20 16:38:30 -07003420 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003421 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003422 EXIT();
Linux Build Service Account63485362015-04-02 04:07:29 -07003423 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07003424}
3425
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303426static int iw_softap_setwpsie(struct net_device *dev,
3427 struct iw_request_info *info,
3428 union iwreq_data *wrqu,
3429 char *extra)
3430{
3431 int ret;
3432
3433 vos_ssr_protect(__func__);
3434 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
3435 vos_ssr_unprotect(__func__);
3436
3437 return ret;
3438}
3439
3440static int __iw_softap_stopbss(struct net_device *dev,
3441 struct iw_request_info *info,
3442 union iwreq_data *wrqu,
3443 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003444{
3445 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3446 VOS_STATUS status = VOS_STATUS_SUCCESS;
Agarwal Ashish51325b52014-06-16 16:50:49 +05303447 hdd_context_t *pHddCtx = NULL;
3448
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +05303450
3451 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3452 status = wlan_hdd_validate_context(pHddCtx);
3453
3454 if (0 != status) {
3455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
3456 return status;
3457 }
3458
Jeff Johnson295189b2012-06-20 16:38:30 -07003459 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3460 {
3461 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
3462 {
3463 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3464
3465 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
3466
3467 if (!VOS_IS_STATUS_SUCCESS(status))
3468 {
3469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003470 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 VOS_ASSERT(0);
3472 }
3473 }
3474 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05303475 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003476 }
3477 EXIT();
3478 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
3479}
3480
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303481static int iw_softap_stopbss(struct net_device *dev,
3482 struct iw_request_info *info,
3483 union iwreq_data *wrqu,
3484 char *extra)
3485{
3486 int ret;
3487
3488 vos_ssr_protect(__func__);
3489 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
3490 vos_ssr_unprotect(__func__);
3491
3492 return ret;
3493}
3494
3495static int __iw_softap_version(struct net_device *dev,
3496 struct iw_request_info *info,
3497 union iwreq_data *wrqu,
3498 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003499{
Jeff Johnson295189b2012-06-20 16:38:30 -07003500 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003501
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003503 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003504 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003505 return 0;
3506}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003507
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303508static int iw_softap_version(struct net_device *dev,
3509 struct iw_request_info *info,
3510 union iwreq_data *wrqu,
3511 char *extra)
3512{
3513 int ret;
3514
3515 vos_ssr_protect(__func__);
3516 ret = __iw_softap_version(dev, info, wrqu, extra);
3517 vos_ssr_unprotect(__func__);
3518
3519 return ret;
3520}
3521
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003522VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003523{
3524 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003525 int len = 0;
3526 const char sta_info_header[] = "staId staAddress\n";
3527
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05303528 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3529 ptSapContext pSapCtx = NULL;
3530 pSapCtx = VOS_GET_SAP_CB(pVosContext);
3531 if(pSapCtx == NULL){
3532 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
3533 FL("psapCtx is NULL"));
3534 return VOS_STATUS_E_FAULT;
3535 }
3536
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003537 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003538 pBuf += len;
3539 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003540
3541 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
3542 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05303543 if(pSapCtx->aStaInfo[i].isUsed)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003544 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003545 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05303546 pSapCtx->aStaInfo[i].ucSTAId,
3547 pSapCtx->aStaInfo[i].macAddrSTA.bytes[0],
3548 pSapCtx->aStaInfo[i].macAddrSTA.bytes[1],
3549 pSapCtx->aStaInfo[i].macAddrSTA.bytes[2],
3550 pSapCtx->aStaInfo[i].macAddrSTA.bytes[3],
3551 pSapCtx->aStaInfo[i].macAddrSTA.bytes[4],
3552 pSapCtx->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003553 pBuf += len;
3554 buf_len -= len;
3555 }
3556 if(WE_GET_STA_INFO_SIZE > buf_len)
3557 {
3558 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003559 }
3560 }
3561 return VOS_STATUS_SUCCESS;
3562}
3563
3564static int iw_softap_get_sta_info(struct net_device *dev,
3565 struct iw_request_info *info,
3566 union iwreq_data *wrqu,
3567 char *extra)
3568{
3569 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3570 VOS_STATUS status;
3571 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003572 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003573 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003575 return -EINVAL;
3576 }
3577 wrqu->data.length = strlen(extra);
3578 EXIT();
3579 return 0;
3580}
3581
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303582static int __iw_set_ap_genie(struct net_device *dev,
3583 struct iw_request_info *info,
3584 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003585{
3586
3587 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3588 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3589 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003590 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003591
3592 ENTER();
3593
3594 if(!wrqu->data.length)
3595 {
3596 EXIT();
3597 return 0;
3598 }
Arif Hussained667642013-10-27 23:01:14 -07003599
Nishank Aggarwal7d6a1b52017-03-14 15:02:24 +08003600 if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN) {
3601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3602 "%s: WPARSN Ie input length is more than max[%d]", __func__,
3603 wrqu->data.length);
3604 return -EINVAL;
3605 }
3606
Jeff Johnson295189b2012-06-20 16:38:30 -07003607 switch (genie[0])
3608 {
3609 case DOT11F_EID_WPA:
3610 case DOT11F_EID_RSN:
3611 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3612 {
3613 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3614 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3615 }
3616 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003617 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003618 break;
3619
3620 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003621 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003622 halStatus = 0;
3623 }
3624
3625 EXIT();
3626 return halStatus;
3627}
3628
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303629static int iw_set_ap_genie(struct net_device *dev,
3630 struct iw_request_info *info,
3631 union iwreq_data *wrqu, char *extra)
3632{
3633 int ret;
3634
3635 vos_ssr_protect(__func__);
3636 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
3637 vos_ssr_unprotect(__func__);
3638
3639 return ret;
3640}
3641
Jeff Johnson295189b2012-06-20 16:38:30 -07003642static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3643{
3644 eHalStatus hstatus;
3645 long lrc;
3646 struct statsContext context;
3647
3648 if (NULL == pAdapter)
3649 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303650 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 return VOS_STATUS_E_FAULT;
3652 }
3653
3654 init_completion(&context.completion);
3655 context.pAdapter = pAdapter;
3656 context.magic = STATS_CONTEXT_MAGIC;
3657 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3658 eCSR_HDD,
3659 SME_GLOBAL_CLASSA_STATS,
3660 hdd_GetClassA_statisticsCB,
3661 0, // not periodic
3662 FALSE, //non-cached results
3663 staid,
3664 &context);
3665 if (eHAL_STATUS_SUCCESS != hstatus)
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR,
3668 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003669 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003670 }
3671 else
3672 {
3673 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3674 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 if (lrc <= 0)
3676 {
3677 hddLog(VOS_TRACE_LEVEL_ERROR,
3678 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003679 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 }
3681 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003682
3683 /* either we never sent a request, we sent a request and received a
3684 response or we sent a request and timed out. if we never sent a
3685 request or if we sent a request and got a response, we want to
3686 clear the magic out of paranoia. if we timed out there is a
3687 race condition such that the callback function could be
3688 executing at the same time we are. of primary concern is if the
3689 callback function had already verified the "magic" but had not
3690 yet set the completion variable when a timeout occurred. we
3691 serialize these activities by invalidating the magic while
3692 holding a shared spinlock which will cause us to block if the
3693 callback is currently executing */
3694 spin_lock(&hdd_context_lock);
3695 context.magic = 0;
3696 spin_unlock(&hdd_context_lock);
3697
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 return VOS_STATUS_SUCCESS;
3699}
3700
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303701int __iw_get_softap_linkspeed(struct net_device *dev,
3702 struct iw_request_info *info,
3703 union iwreq_data *wrqu,
3704 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003705
3706{
3707 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303708 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003709 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003710 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303711 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003712 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303713 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003714 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003715 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303716 int rc, valid;
3717
3718 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3719
3720 valid = wlan_hdd_validate_context(pHddCtx);
3721
3722 if (0 != valid)
3723 {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3725 return valid;
3726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003727
Arif Hussain6d2a3322013-11-17 19:50:10 -08003728 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003729
3730 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003731 {
Arif Hussaina9571842014-01-15 16:43:41 -08003732 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3733 if (NULL == pmacAddress) {
3734 hddLog(LOG1, "unable to allocate memory");
3735 return -ENOMEM;
3736 }
3737 if (copy_from_user((void *)pmacAddress,
3738 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3739 {
3740 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3741 kfree(pmacAddress);
3742 return -EFAULT;
3743 }
Teow Wan Yee85ba7c12016-09-19 14:34:54 +08003744 pmacAddress[MAC_ADDRESS_STR_LEN-1] = '\0';
Arif Hussaina9571842014-01-15 16:43:41 -08003745
3746 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003747 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003748
3749 if (!VOS_IS_STATUS_SUCCESS(status ))
3750 {
3751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3752 }
Arif Hussained667642013-10-27 23:01:14 -07003753 }
Kiet Lam61589852013-09-19 17:10:58 +05303754 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303755 * link speed for first connected client will be returned.
3756 */
Arif Hussaina9571842014-01-15 16:43:41 -08003757 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303758 {
3759 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3760 }
3761 else
3762 {
3763 status = hdd_softap_GetStaId(pHostapdAdapter,
3764 (v_MACADDR_t *)macAddress, (void *)(&staId));
3765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003766
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303767 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003768 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003770 link_speed = 0;
3771 }
3772 else
3773 {
3774 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303775
Jeff Johnson295189b2012-06-20 16:38:30 -07003776 if (!VOS_IS_STATUS_SUCCESS(status ))
3777 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003779 return -EINVAL;
3780 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303781
3782 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3783 staId, &link_speed);
3784
3785 link_speed = link_speed / 10;
3786
3787 if (0 == link_speed)
3788 {
3789 /* The linkspeed returned by HAL is in units of 500kbps.
3790 * converting it to mbps.
3791 * This is required to support legacy firmware which does
3792 * not return link capacity.
3793 */
3794 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003796 }
3797
3798 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003799 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303800
Jeff Johnson295189b2012-06-20 16:38:30 -07003801 if ((rc < 0) || (rc >= len))
3802 {
3803 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303804 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003805 return -EIO;
3806 }
3807
3808 return 0;
3809}
3810
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303811int iw_get_softap_linkspeed(struct net_device *dev,
3812 struct iw_request_info *info,
3813 union iwreq_data *wrqu,
3814 char *extra)
3815{
3816 int ret;
3817
3818 vos_ssr_protect(__func__);
3819 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
3820 vos_ssr_unprotect(__func__);
3821
3822 return ret;
3823}
3824
3825
Jeff Johnson295189b2012-06-20 16:38:30 -07003826static const iw_handler hostapd_handler[] =
3827{
3828 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3829 (iw_handler) NULL, /* SIOCGIWNAME */
3830 (iw_handler) NULL, /* SIOCSIWNWID */
3831 (iw_handler) NULL, /* SIOCGIWNWID */
3832 (iw_handler) NULL, /* SIOCSIWFREQ */
3833 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3834 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303835 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003836 (iw_handler) NULL, /* SIOCSIWSENS */
3837 (iw_handler) NULL, /* SIOCGIWSENS */
3838 (iw_handler) NULL, /* SIOCSIWRANGE */
3839 (iw_handler) NULL, /* SIOCGIWRANGE */
3840 (iw_handler) NULL, /* SIOCSIWPRIV */
3841 (iw_handler) NULL, /* SIOCGIWPRIV */
3842 (iw_handler) NULL, /* SIOCSIWSTATS */
3843 (iw_handler) NULL, /* SIOCGIWSTATS */
3844 (iw_handler) NULL, /* SIOCSIWSPY */
3845 (iw_handler) NULL, /* SIOCGIWSPY */
3846 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3847 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3848 (iw_handler) NULL, /* SIOCSIWAP */
3849 (iw_handler) NULL, /* SIOCGIWAP */
3850 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3851 (iw_handler) NULL, /* SIOCGIWAPLIST */
3852 (iw_handler) NULL, /* SIOCSIWSCAN */
3853 (iw_handler) NULL, /* SIOCGIWSCAN */
3854 (iw_handler) NULL, /* SIOCSIWESSID */
3855 (iw_handler) NULL, /* SIOCGIWESSID */
3856 (iw_handler) NULL, /* SIOCSIWNICKN */
3857 (iw_handler) NULL, /* SIOCGIWNICKN */
3858 (iw_handler) NULL, /* -- hole -- */
3859 (iw_handler) NULL, /* -- hole -- */
3860 (iw_handler) NULL, /* SIOCSIWRATE */
3861 (iw_handler) NULL, /* SIOCGIWRATE */
3862 (iw_handler) NULL, /* SIOCSIWRTS */
3863 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3864 (iw_handler) NULL, /* SIOCSIWFRAG */
3865 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3866 (iw_handler) NULL, /* SIOCSIWTXPOW */
3867 (iw_handler) NULL, /* SIOCGIWTXPOW */
3868 (iw_handler) NULL, /* SIOCSIWRETRY */
3869 (iw_handler) NULL, /* SIOCGIWRETRY */
3870 (iw_handler) NULL, /* SIOCSIWENCODE */
3871 (iw_handler) NULL, /* SIOCGIWENCODE */
3872 (iw_handler) NULL, /* SIOCSIWPOWER */
3873 (iw_handler) NULL, /* SIOCGIWPOWER */
3874 (iw_handler) NULL, /* -- hole -- */
3875 (iw_handler) NULL, /* -- hole -- */
3876 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3877 (iw_handler) NULL, /* SIOCGIWGENIE */
3878 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3879 (iw_handler) NULL, /* SIOCGIWAUTH */
3880 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3881 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3882 (iw_handler) NULL, /* SIOCSIWPMKSA */
3883};
3884
Jeff Johnson224f3702014-03-26 11:09:47 -07003885/*
3886 * Note that the following ioctls were defined with semantics which
3887 * cannot be handled by the "iwpriv" userspace application and hence
3888 * they are not included in the hostapd_private_args array
3889 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3890 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003891
3892static const struct iw_priv_args hostapd_private_args[] = {
3893 { QCSAP_IOCTL_SETPARAM,
3894 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3895 { QCSAP_IOCTL_SETPARAM,
3896 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3897 { QCSAP_PARAM_MAX_ASSOC,
3898 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3899 { QCSAP_PARAM_HIDE_SSID,
3900 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003901 { QCSAP_PARAM_SET_MC_RATE,
3902 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 { QCSAP_IOCTL_GETPARAM,
3904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3905 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3906 { QCSAP_IOCTL_GETPARAM, 0,
3907 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3908 { QCSAP_PARAM_MAX_ASSOC, 0,
3909 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003910 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3911 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3912 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3913 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303914 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3915 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 { QCSAP_PARAM_CLR_ACL, 0,
3917 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3918 { QCSAP_PARAM_ACL_MODE,
3919 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003920 { QCSAP_IOCTL_GET_STAWPAIE,
3921 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3922 { QCSAP_IOCTL_SETWPAIE,
3923 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3924 { QCSAP_IOCTL_STOPBSS,
3925 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3926 { QCSAP_IOCTL_VERSION, 0,
3927 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003928 { QCSAP_IOCTL_GET_STA_INFO, 0,
3929 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003931 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003933 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003934 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003935 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05303936 { QCSAP_IOCTL_AP_STATS, 0,
3937 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3939 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303940 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003941
3942 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3943 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3944 /* handlers for sub-ioctl */
3945 { WE_SET_WLAN_DBG,
3946 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3947 0,
3948 "setwlandbg" },
3949
3950 /* handlers for main ioctl */
3951 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3952 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3953 0,
3954 "" },
3955
3956 /* handlers for sub-ioctl */
3957 { WE_LOG_DUMP_CMD,
3958 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3959 0,
3960 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 { WE_P2P_NOA_CMD,
3962 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3963 0,
3964 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003965 /* handlers for sub ioctl */
3966 {
3967 WE_MCC_CONFIG_CREDENTIAL,
3968 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3969 0,
3970 "setMccCrdnl" },
3971
3972 /* handlers for sub ioctl */
3973 {
3974 WE_MCC_CONFIG_PARAMS,
3975 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3976 0,
3977 "setMccConfig" },
3978
Jeff Johnson295189b2012-06-20 16:38:30 -07003979 /* handlers for main ioctl */
3980 { QCSAP_IOCTL_MODIFY_ACL,
3981 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3982 0,
3983 "modify_acl" },
3984
3985 /* handlers for main ioctl */
3986 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3987 0,
3988 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3989 "getChannelList" },
3990
Jeff Johnsone7245742012-09-05 17:12:55 -07003991 /* handlers for main ioctl */
3992 { QCSAP_IOCTL_SET_TX_POWER,
3993 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3994 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303995 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003996
3997 /* handlers for main ioctl */
3998 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3999 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
4000 0,
4001 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05304002
4003 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
4004 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
4005 0,
4006 "dataSnapshot" },
4007
4008 /* handlers for main ioctl */
4009 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
4010 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
4011 0,
4012 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07004013};
Jeff Johnsone7245742012-09-05 17:12:55 -07004014
Jeff Johnson295189b2012-06-20 16:38:30 -07004015static const iw_handler hostapd_private[] = {
4016 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
4017 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07004018 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
4019 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
4020 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
4021 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
4022 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
4023 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
4024 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
4025 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
4026 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
4027 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
4028 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
4029 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
4030 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
4031 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08004032 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07004033 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
4034 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07004035 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05304036 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05304037 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07004038};
4039const struct iw_handler_def hostapd_handler_def = {
4040 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
4041 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
4042 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
4043 .standard = (iw_handler *)hostapd_handler,
4044 .private = (iw_handler *)hostapd_private,
4045 .private_args = hostapd_private_args,
4046 .get_wireless_stats = NULL,
4047};
4048#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4049struct net_device_ops net_ops_struct = {
4050 .ndo_open = hdd_hostapd_open,
4051 .ndo_stop = hdd_hostapd_stop,
4052 .ndo_uninit = hdd_hostapd_uninit,
4053 .ndo_start_xmit = hdd_softap_hard_start_xmit,
4054 .ndo_tx_timeout = hdd_softap_tx_timeout,
4055 .ndo_get_stats = hdd_softap_stats,
4056 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
4057 .ndo_do_ioctl = hdd_hostapd_ioctl,
4058 .ndo_change_mtu = hdd_hostapd_change_mtu,
4059 .ndo_select_queue = hdd_hostapd_select_queue,
4060 };
4061#endif
4062
4063int hdd_set_hostapd(hdd_adapter_t *pAdapter)
4064{
4065 return VOS_STATUS_SUCCESS;
4066}
4067
4068void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
4069{
4070#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4071 pWlanHostapdDev->netdev_ops = &net_ops_struct;
4072#else
4073 pWlanHostapdDev->open = hdd_hostapd_open;
4074 pWlanHostapdDev->stop = hdd_hostapd_stop;
4075 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
4076 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
4077 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
4078 pWlanHostapdDev->get_stats = hdd_softap_stats;
4079 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
4080 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
4081#endif
4082}
4083
4084VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
4085{
4086 hdd_hostapd_state_t * phostapdBuf;
4087 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004088 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08004090#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08004091 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
4092 v_U16_t unsafeChannelCount;
4093#endif /* FEATURE_WLAN_CH_AVOID */
4094
Anand N Sunkad0b39e842014-12-24 18:08:22 +05304095 if (pHddCtx->isLogpInProgress) {
4096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4097 "%s:LOGP in Progress. Ignore!!!",__func__);
4098 status = VOS_STATUS_E_FAILURE;
4099 }
4100
Jeff Johnson295189b2012-06-20 16:38:30 -07004101 ENTER();
4102 // Allocate the Wireless Extensions state structure
4103 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
4104
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004105 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
4106
Leo Chang0b0e45a2013-12-15 15:18:55 -08004107#ifdef FEATURE_WLAN_CH_AVOID
4108 /* Get unsafe cahnnel list from cached location */
4109 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
4110 sizeof(unsafeChannelList),
4111 &unsafeChannelCount);
4112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4113 "%s : Unsafe Channel count %d",
4114 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05304115 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08004116 unsafeChannelList,
4117 unsafeChannelCount);
4118#endif /* FEATURE_WLAN_CH_AVOID */
4119
Jeff Johnson295189b2012-06-20 16:38:30 -07004120 // Zero the memory. This zeros the profile structure.
4121 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
4122
4123 // Set up the pointer to the Wireless Extensions state structure
4124 // NOP
4125 status = hdd_set_hostapd(pAdapter);
4126 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004128 return status;
4129 }
4130
4131 status = vos_event_init(&phostapdBuf->vosEvent);
4132 if (!VOS_IS_STATUS_SUCCESS(status))
4133 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004135 return status;
4136 }
4137
4138 init_completion(&pAdapter->session_close_comp_var);
4139 init_completion(&pAdapter->session_open_comp_var);
4140
4141 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
4142
4143 // Register as a wireless device
4144 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
4145
4146 //Initialize the data path module
4147 status = hdd_softap_init_tx_rx(pAdapter);
4148 if ( !VOS_IS_STATUS_SUCCESS( status ))
4149 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004150 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004151 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304152
4153 status = hdd_wmm_adapter_init( pAdapter );
4154 if (!VOS_IS_STATUS_SUCCESS(status))
4155 {
4156 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004157 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304158 status, status );
4159 goto error_wmm_init;
4160 }
4161
4162 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
4163
Jeff Johnson295189b2012-06-20 16:38:30 -07004164 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304165
4166 return status;
4167
4168error_wmm_init:
4169 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07004170 EXIT();
4171 return status;
4172}
4173
4174hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
4175{
4176 struct net_device *pWlanHostapdDev = NULL;
4177 hdd_adapter_t *pHostapdAdapter = NULL;
4178 v_CONTEXT_t pVosContext= NULL;
4179
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07004181
4182 if (pWlanHostapdDev != NULL)
4183 {
4184 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
4185
4186 //Init the net_device structure
4187 ether_setup(pWlanHostapdDev);
4188
4189 //Initialize the adapter context to zeros.
4190 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
4191 pHostapdAdapter->dev = pWlanHostapdDev;
4192 pHostapdAdapter->pHddCtx = pHddCtx;
4193 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
4194
4195 //Get the Global VOSS context.
4196 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4197 //Save the adapter context in global context for future.
4198 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
4199
4200 //Init the net_device structure
4201 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
4202
4203 hdd_set_ap_ops( pHostapdAdapter->dev );
4204
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
4206 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
4207
4208 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
4209 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
4210
4211 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07004212 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
4213 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
4214 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
4215 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004216 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
4217 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05304218 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07004219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4220 init_completion(&pHostapdAdapter->offchannel_tx_event);
4221#endif
4222
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
4224 }
4225 return pHostapdAdapter;
4226}
4227
4228VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
4229{
4230 struct net_device *dev = pAdapter->dev;
4231 VOS_STATUS status = VOS_STATUS_SUCCESS;
4232
4233 ENTER();
4234
4235 if( rtnl_lock_held )
4236 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08004237 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07004238 if( dev_alloc_name(dev, dev->name) < 0 )
4239 {
4240 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
4241 return VOS_STATUS_E_FAILURE;
4242 }
4243 }
4244 if (register_netdevice(dev))
4245 {
4246 hddLog(VOS_TRACE_LEVEL_FATAL,
4247 "%s:Failed:register_netdevice", __func__);
4248 return VOS_STATUS_E_FAILURE;
4249 }
4250 }
4251 else
4252 {
4253 if (register_netdev(dev))
4254 {
4255 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
4256 return VOS_STATUS_E_FAILURE;
4257 }
4258 }
4259 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
4260
4261 EXIT();
4262 return status;
4263}
4264
4265VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
4266{
4267 ENTER();
4268
4269 hdd_softap_deinit_tx_rx(pAdapter);
4270
4271 /* if we are being called during driver unload, then the dev has already
4272 been invalidated. if we are being called at other times, then we can
4273 detatch the wireless device handlers */
4274 if (pAdapter->dev)
4275 {
4276 pAdapter->dev->wireless_handlers = NULL;
4277 }
4278 EXIT();
4279 return 0;
4280}