blob: 6c4c25136a7e91a9d6b04da1828fc6f9e4fe65e2 [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 Bhal2db319d2014-12-03 12:37:18 +0530174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
175
Jeff Johnson295189b2012-06-20 16:38:30 -0700176 ENTER();
177
Siddharth Bhal2db319d2014-12-03 12:37:18 +0530178 if(!test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
179 {
180 //WMM_INIT OR BSS_START not completed
181 hddLog( LOGW, "Ignore hostadp open request");
182 EXIT();
183 return 0;
184 }
185
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530186 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
187 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -0700188 //Turn ON carrier state
189 netif_carrier_on(dev);
190 //Enable all Tx queues
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, Vidyullatha99bd6c42014-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, Sushant96122442014-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, Sushant96122442014-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, Sushant96122442014-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, Sushant96122442014-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 Ahujabcb0b7e2014-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 Ahujabcb0b7e2014-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 Ahujabcb0b7e2014-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 Ahujabcb0b7e2014-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 Ahujabcb0b7e2014-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 Ahujabcb0b7e2014-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 {
913 struct station_info staInfo;
914 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
915
916 memset(&staInfo, 0, sizeof(staInfo));
917 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
918 {
919 staInfo.assoc_req_ies =
920 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
921 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700922#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700923 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700925 cfg80211_new_sta(dev,
926 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
927 &staInfo, GFP_KERNEL);
928 }
929 else
930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800931 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 }
933 }
934#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800935 pScanInfo = &pHddCtx->scan_info;
936 // Lets do abort scan to ensure smooth authentication for client
937 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
938 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +0530939 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530940 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800941 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700942
943 break;
944 case eSAP_STA_DISASSOC_EVENT:
945 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800946 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800947 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
949 hddLog(LOG1," User initiated disassociation");
950 else
951 hddLog(LOG1," MAC initiated disassociation");
952 we_event = IWEVEXPIRED;
953 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
954 if (!VOS_IS_STATUS_SUCCESS(vos_status))
955 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700956 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 -0700957 return VOS_STATUS_E_FAILURE;
958 }
959 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
960
961 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
962 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530963 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 // Start AP inactivity timer if no stations associated with it
965 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
966 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530967 if (pSapCtx->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 {
969 bApActive = TRUE;
970 break;
971 }
972 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530973 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700974
975 if (bApActive == FALSE)
976 {
977 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
978 {
979 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
980 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800981 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 }
983 else
984 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
985 }
986 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
988 cfg80211_del_sta(dev,
989 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
990 GFP_KERNEL);
991#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800992 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +0530993 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
994 if (VOS_STATUS_SUCCESS != vos_status)
995 {
996 hddLog(LOGE, "%s: failed to update Beacon interval %d",
997 __func__, vos_status);
998 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700999 break;
1000 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1001 {
1002 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
1003 union iwreq_data wreq;
1004
1005 down(&pHddApCtx->semWpsPBCOverlapInd);
1006 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
1007
1008 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
1009 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1010
1011 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -08001012 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001013 memset(&wreq, 0, sizeof(wreq));
1014 wreq.data.length = strlen(message); // This is length of message
1015 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
1016
1017 return VOS_STATUS_SUCCESS;
1018 }
1019 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1020 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1021 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
1022 { // List of associated stations
1023 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
1024 {
1025 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
1026 i+1,
1027 pAssocStasArray->assocId,
1028 pAssocStasArray->staId,
1029 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
1030 pAssocStasArray++;
1031 }
1032 }
1033 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001034 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001036 case eSAP_INDICATE_MGMT_FRAME:
1037 hdd_indicateMgmtFrame( pHostapdAdapter,
1038 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
1039 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
1040 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05301041 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 return VOS_STATUS_SUCCESS;
1043 case eSAP_REMAIN_CHAN_READY:
1044 hdd_remainChanReadyHandler( pHostapdAdapter );
1045 return VOS_STATUS_SUCCESS;
1046 case eSAP_SEND_ACTION_CNF:
1047 hdd_sendActionCnf( pHostapdAdapter,
1048 ( eSAP_STATUS_SUCCESS ==
1049 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
1050 TRUE : FALSE );
1051 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 case eSAP_UNKNOWN_STA_JOIN:
1053 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1054 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1055 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1056 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1057 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1058 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1059 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1060 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1061 wrqu.data.pointer = unknownSTAEvent;
1062 wrqu.data.length = strlen(unknownSTAEvent);
1063 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +05301064 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001065 break;
1066
1067 case eSAP_MAX_ASSOC_EXCEEDED:
1068 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1069 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1070 " one or more devices to enable the new device connection",
1071 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1072 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1073 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1074 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1075 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1076 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
1077 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1078 wrqu.data.pointer = maxAssocExceededEvent;
1079 wrqu.data.length = strlen(maxAssocExceededEvent);
1080 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001081 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 break;
1083 case eSAP_STA_ASSOC_IND:
1084 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001085
1086 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001087 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001088 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
1089 return VOS_STATUS_SUCCESS;
1090
1091 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
c_hpothuffdb5272013-10-02 16:42:35 +05301092 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1093 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1094 {
1095 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1096 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001097 return VOS_STATUS_SUCCESS;
1098
Jeff Johnson295189b2012-06-20 16:38:30 -07001099 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001100 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 goto stopbss;
1102 return VOS_STATUS_SUCCESS;
1103 }
1104 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1105 return VOS_STATUS_SUCCESS;
1106
1107stopbss :
1108 {
1109 v_BYTE_t we_custom_event[64];
1110 char *stopBssEvent = "STOP-BSS.response";//17
1111 int event_len = strlen(stopBssEvent);
1112
1113 hddLog(LOG1, FL("BSS stop status = %s"),
1114 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1115 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1116
1117 /* Change the BSS state now since, as we are shutting things down,
1118 * we don't want interfaces to become re-enabled */
1119 pHostapdState->bssState = BSS_STOP;
1120
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301121 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1122 {
1123 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1124 {
1125 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1126 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1127 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1128 }
1129
1130 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1131 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1132 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1133 }
1134
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 /* Stop the pkts from n/w stack as we are going to free all of
1136 * the TX WMM queues for all STAID's */
1137 hdd_hostapd_stop(dev);
1138
1139 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301140 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1141 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1142 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001143
Amar Singhal37e6f052013-03-05 16:16:54 -08001144 /* once the event is set, structure dev/pHostapdAdapter should
1145 * not be touched since they are now subject to being deleted
1146 * by another thread */
1147 if (eSAP_STOP_BSS_EVENT == sapEvent)
1148 vos_event_set(&pHostapdState->vosEvent);
1149
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 /* notify userspace that the BSS has stopped */
1151 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1152 memcpy(&we_custom_event, stopBssEvent, event_len);
1153 memset(&wrqu, 0, sizeof(wrqu));
1154 wrqu.data.length = event_len;
1155 we_event = IWEVCUSTOM;
1156 we_custom_event_generic = we_custom_event;
1157 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001158 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001159 }
1160 return VOS_STATUS_SUCCESS;
1161}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001162
1163int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001164 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001165 eCsrEncryptionType *pEncryptType,
1166 eCsrEncryptionType *mcEncryptType,
1167 eCsrAuthType *pAuthType,
1168 v_BOOL_t *pMFPCapable,
1169 v_BOOL_t *pMFPRequired,
1170 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 u_int8_t *gen_ie )
1172{
1173 tDot11fIERSN dot11RSNIE;
1174 tDot11fIEWPA dot11WPAIE;
1175
1176 tANI_U8 *pRsnIe;
1177 tANI_U16 RSNIeLen;
1178
1179 if (NULL == halHandle)
1180 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001181 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 return -EINVAL;
1183 }
1184
1185 // Validity checks
1186 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1187 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1188 return -EINVAL;
1189 // Type check
1190 if ( gen_ie[0] == DOT11F_EID_RSN)
1191 {
1192 // Validity checks
1193 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1194 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1195 {
1196 return VOS_STATUS_E_FAILURE;
1197 }
1198 // Skip past the EID byte and length byte
1199 pRsnIe = gen_ie + 2;
1200 RSNIeLen = gen_ie_len - 2;
1201 // Unpack the RSN IE
1202 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1203 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1204 pRsnIe,
1205 RSNIeLen,
1206 &dot11RSNIE);
1207 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001208 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001209 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001210 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001211 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 /*Here we have followed the apple base code,
1213 but probably I suspect we can do something different*/
1214 //dot11RSNIE.akm_suite_count
1215 // Just translate the FIRST one
1216 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1217 //dot11RSNIE.pwise_cipher_suite_count
1218 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1219 //dot11RSNIE.gp_cipher_suite_count
1220 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1221 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001222 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1223 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001224
1225 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1226 } else
1227 if (gen_ie[0] == DOT11F_EID_WPA)
1228 {
1229 // Validity checks
1230 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1231 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1232 {
1233 return VOS_STATUS_E_FAILURE;
1234 }
1235 // Skip past the EID byte and length byte - and four byte WiFi OUI
1236 pRsnIe = gen_ie + 2 + 4;
1237 RSNIeLen = gen_ie_len - (2 + 4);
1238 // Unpack the WPA IE
1239 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1240 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1241 pRsnIe,
1242 RSNIeLen,
1243 &dot11WPAIE);
1244 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001245 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001246 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001247 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001248 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001249 //dot11WPAIE.auth_suite_count
1250 // Just translate the FIRST one
1251 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1252 //dot11WPAIE.unicast_cipher_count
1253 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1254 //dot11WPAIE.unicast_cipher_count
1255 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001256 *pMFPCapable = VOS_FALSE;
1257 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001258 }
1259 else
1260 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001261 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001262 return VOS_STATUS_E_FAILURE;
1263 }
1264 return VOS_STATUS_SUCCESS;
1265}
Leo Chang614d2072013-08-22 14:59:44 -07001266
Leo Chang0b0e45a2013-12-15 15:18:55 -08001267#ifdef FEATURE_WLAN_CH_AVOID
1268/**---------------------------------------------------------------------------
1269
1270 \brief hdd_hostapd_freq_to_chn() -
1271
1272 Input frequency translated into channel number
1273
1274 \param - freq input frequency with order of kHz
1275
1276 \return - corresponding channel number.
1277 incannot find correct channel number, return 0
1278
1279 --------------------------------------------------------------------------*/
1280v_U16_t hdd_hostapd_freq_to_chn
1281(
1282 v_U16_t freq
1283)
1284{
1285 int loop;
1286
1287 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1288 {
1289 if (rfChannels[loop].targetFreq == freq)
1290 {
1291 return rfChannels[loop].channelNum;
1292 }
1293 }
1294
1295 return (0);
1296}
1297
1298/*==========================================================================
1299 FUNCTION sapUpdateUnsafeChannelList
1300
1301 DESCRIPTION
1302 Function Undate unsafe channel list table
1303
1304 DEPENDENCIES
1305 NA.
1306
1307 PARAMETERS
1308
1309 IN
1310 pSapCtx : SAP context pointer, include unsafe channel list
1311
1312 RETURN VALUE
1313 NONE
1314============================================================================*/
1315void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1316 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1317{
1318 v_U16_t i, j;
1319
1320 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1321 sizeof(pHddCtx->unsafeChannelList));
1322 if (0 == unsafeChannelCount)
1323 {
1324 pHddCtx->unsafeChannelCount = 0;
1325 }
1326 else
1327 {
c_hpothu8de53e42014-08-22 15:00:37 +05301328 if (unsafeChannelCount > NUM_20MHZ_RF_CHANNELS)
1329 {
1330 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1331 FL("unsafeChannelCount%hd greater than %d"),
1332 unsafeChannelCount, NUM_20MHZ_RF_CHANNELS);
1333 unsafeChannelCount = NUM_20MHZ_RF_CHANNELS;
1334 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001335 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1336 unsafeChannelList,
1337 unsafeChannelCount * sizeof(tANI_U16));
1338 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1339 }
1340
1341 /* Flush, default set all channel safe */
1342 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1343 {
1344 safeChannels[i].isSafe = VOS_TRUE;
1345 }
1346
1347 /* Try to find unsafe channel */
1348 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1349 {
1350 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1351 {
1352 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1353 {
1354 /* Found unsafe channel, update it */
1355 safeChannels[j].isSafe = VOS_FALSE;
1356 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1357 "%s : CH %d is not safe",
1358 __func__, pHddCtx->unsafeChannelList[i]);
1359 break;
1360 }
1361 }
1362 }
1363
1364 return;
1365}
1366
1367/**---------------------------------------------------------------------------
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301368 \brief hdd_restart_softap() -
1369 Restart SAP on STA channel to support
1370 STA + SAP concurrency.
1371
1372 --------------------------------------------------------------------------*/
1373void hdd_restart_softap
1374(
1375 hdd_context_t *pHddCtx,
1376 hdd_adapter_t *pHostapdAdapter
1377)
1378{
1379 tSirChAvoidIndType *chAvoidInd;
1380
1381 chAvoidInd =
1382 (tSirChAvoidIndType *)vos_mem_malloc(sizeof(tSirChAvoidIndType));
1383 if (NULL == chAvoidInd)
1384 {
1385 hddLog(VOS_TRACE_LEVEL_INFO, FL("CH_AVOID IND buffer alloc Fail"));
1386 return ;
1387 }
1388 chAvoidInd->avoidRangeCount = 1;
1389 chAvoidInd->avoidFreqRange[0].startFreq =
1390 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1391 chAvoidInd->avoidFreqRange[0].endFreq =
1392 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1393 hdd_hostapd_ch_avoid_cb((void *)pHddCtx, (void *)chAvoidInd);
Girish Gowlic1725582014-07-31 20:37:35 +05301394 vos_mem_free(chAvoidInd);
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301395}
1396/**---------------------------------------------------------------------------
Leo Chang0b0e45a2013-12-15 15:18:55 -08001397
1398 \brief hdd_hostapd_ch_avoid_cb() -
1399
1400 Avoid channel notification from FW handler.
1401 FW will send un-safe channle list to avoid overwrapping.
1402 hostapd should not use notified channel
1403
1404 \param - pAdapter HDD adapter pointer
1405 indParam channel avoid notification parameter
1406
1407 \return - None
1408
1409 --------------------------------------------------------------------------*/
1410void hdd_hostapd_ch_avoid_cb
1411(
1412 void *pAdapter,
1413 void *indParam
1414)
1415{
1416 hdd_adapter_t *pHostapdAdapter = NULL;
1417 hdd_context_t *hddCtxt;
1418 tSirChAvoidIndType *chAvoidInd;
1419 v_U8_t rangeLoop;
1420 v_U16_t channelLoop;
1421 v_U16_t dupCheck;
1422 v_U16_t startChannel;
1423 v_U16_t endChannel;
1424 v_U16_t unsafeChannelCount = 0;
1425 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1426 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001427 tHddAvoidFreqList hddAvoidFreqList;
1428 tANI_U32 i;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001429
1430 /* Basic sanity */
1431 if ((NULL == pAdapter) || (NULL == indParam))
1432 {
1433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1434 "%s : Invalid arguments", __func__);
1435 return;
1436 }
1437
1438 hddCtxt = (hdd_context_t *)pAdapter;
1439 chAvoidInd = (tSirChAvoidIndType *)indParam;
1440 pVosContext = hddCtxt->pvosContext;
1441
1442 /* Make unsafe channel list */
1443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1444 "%s : band count %d",
1445 __func__, chAvoidInd->avoidRangeCount);
1446 vos_mem_zero((void *)unsafeChannelList,
1447 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1448 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1449 {
1450 startChannel = hdd_hostapd_freq_to_chn(
1451 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1452 endChannel = hdd_hostapd_freq_to_chn(
1453 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1455 "%s : start %d : %d, end %d : %d",
1456 __func__,
1457 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1458 startChannel,
1459 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1460 endChannel);
1461 for (channelLoop = startChannel;
1462 channelLoop < (endChannel + 1);
1463 channelLoop++)
1464 {
1465 /* Channel duplicate check routine */
1466 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1467 {
1468 if (unsafeChannelList[dupCheck] == channelLoop)
1469 {
1470 /* This channel is duplicated */
1471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1472 "%s : found duplicated channel %d",
1473 __func__, channelLoop);
1474 break;
1475 }
1476 }
1477 if (dupCheck == unsafeChannelCount)
1478 {
c_hpothu8de53e42014-08-22 15:00:37 +05301479 int ii;
1480 for(ii=0; ii<NUM_20MHZ_RF_CHANNELS; ii++)
1481 {
1482 if (channelLoop == safeChannels[ii].channelNumber)
1483 {
1484 unsafeChannelList[unsafeChannelCount] = channelLoop;
1485 unsafeChannelCount++;
1486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1487 "%s : unsafe channel %d, count %d",
1488 __func__,
1489 channelLoop, unsafeChannelCount);
1490 }
1491 }
Leo Chang0b0e45a2013-12-15 15:18:55 -08001492 }
1493 else
1494 {
1495 /* DUP, do nothing */
1496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1497 "%s : duplicated channel %d",
1498 __func__, channelLoop);
1499 }
1500 }
1501 }
1502 /* Update unsafe channel cache
1503 * WCN Platform Driver cache */
1504 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1505 unsafeChannelCount);
1506
1507 /* Store into local cache
1508 * Start with STA and later start SAP
1509 * in this scenario, local cache will be used */
1510 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1511 unsafeChannelList,
1512 unsafeChannelCount);
1513
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001514 /* generate vendor specific event */
1515 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1516 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1517 {
1518 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1519 chAvoidInd->avoidFreqRange[i].startFreq;
1520 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1521 chAvoidInd->avoidFreqRange[i].endFreq;
1522 }
1523 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1524
1525 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1526
Leo Chang0b0e45a2013-12-15 15:18:55 -08001527 /* Get SAP context first
1528 * SAP and P2PGO would not concurrent */
1529 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
Kanchanapally, Vidyullatha99bd6c42014-12-10 13:54:38 +05301530 if ((pHostapdAdapter) &&
1531 (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) &&
1532 (unsafeChannelCount))
Leo Chang0b0e45a2013-12-15 15:18:55 -08001533 {
1534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1535 "%s : Current operation channel %d",
1536 __func__,
1537 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1538 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1539 {
1540 if (((unsafeChannelList[channelLoop] ==
1541 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1542 (AUTO_CHANNEL_SELECT ==
1543 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1544 {
1545 /* current operating channel is un-safe channel
1546 * restart driver */
1547 hdd_hostapd_stop(pHostapdAdapter->dev);
Neelansh Mittaledafed22014-09-04 18:54:39 +05301548 /* On LE, this event is handled by wlan-services to restart SAP.
1549 On android, this event would be ignored. */
1550 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND, NULL, 0);
Leo Chang0b0e45a2013-12-15 15:18:55 -08001551 break;
1552 }
1553 }
1554 }
1555
1556 return;
1557}
1558
1559#endif /* FEATURE_WLAN_CH_AVOID */
1560
Jeff Johnson295189b2012-06-20 16:38:30 -07001561int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301562static __iw_softap_setparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001563 struct iw_request_info *info,
1564 union iwreq_data *wrqu, char *extra)
1565{
1566 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001567 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 int *value = (int *)extra;
1569 int sub_cmd = value[0];
1570 int set_value = value[1];
1571 eHalStatus status;
1572 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001573 v_CONTEXT_t pVosContext;
1574
1575 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1576 {
1577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1578 "%s: either hostapd Adapter is null or HDD ctx is null",
1579 __func__);
1580 return -1;
1581 }
1582
1583 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1584 if (!hHal)
1585 {
1586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1587 "%s: Hal ctx is null", __func__);
1588 return -1;
1589 }
1590
1591 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1592 if (!pVosContext)
1593 {
1594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1595 "%s: Vos ctx is null", __func__);
1596 return -1;
1597 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001598
1599 switch(sub_cmd)
1600 {
1601
1602 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001603 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001604 {
1605 ret = -EIO;
1606 }
1607 break;
1608
1609 case QCSAP_PARAM_ACL_MODE:
1610 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1611 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1612 {
1613 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1614 ret = -EINVAL;
1615 }
1616 else
1617 {
1618 WLANSAP_SetMode(pVosContext, set_value);
1619 }
1620 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301621
1622 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1623 if ((0 != set_value) && (1 != set_value))
1624 {
1625 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1626 ret = -EINVAL;
1627 }
1628 else
1629 {
1630 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1631 }
1632 break;
1633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 case QCSAP_PARAM_MAX_ASSOC:
1635 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1636 {
1637 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1638 ret = -EINVAL;
1639 }
1640 else
1641 {
1642 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1643 {
1644 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1645 "Setting it to max allowed and continuing"),
1646 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1647 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1648 }
1649 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1650 set_value, NULL, eANI_BOOLEAN_FALSE);
1651 if ( status != eHAL_STATUS_SUCCESS )
1652 {
1653 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1654 status);
1655 ret = -EIO;
1656 }
1657 }
1658 break;
1659
1660 case QCSAP_PARAM_HIDE_SSID:
1661 {
1662 eHalStatus status = eHAL_STATUS_SUCCESS;
1663 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1664 if(eHAL_STATUS_SUCCESS != status)
1665 {
1666 hddLog(VOS_TRACE_LEVEL_ERROR,
1667 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001668 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 return status;
1670 }
1671 break;
1672 }
1673
Leo Chang614d2072013-08-22 14:59:44 -07001674 case QCSAP_PARAM_SET_MC_RATE:
1675 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001676 tSirRateUpdateInd *rateUpdate;
1677
1678 rateUpdate = (tSirRateUpdateInd *)
1679 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1680 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001681 {
1682 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001683 "%s: SET_MC_RATE indication alloc fail", __func__);
1684 ret = -1;
1685 break;
1686 }
1687 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1688
1689 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1690 /* Ignore unicast */
1691 rateUpdate->ucastDataRate = -1;
1692 rateUpdate->mcastDataRate24GHz = set_value;
1693 rateUpdate->mcastDataRate5GHz = set_value;
1694 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1695 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1696 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1697 if (eHAL_STATUS_SUCCESS != status)
1698 {
1699 hddLog(VOS_TRACE_LEVEL_ERROR,
1700 "%s: SET_MC_RATE failed", __func__);
1701 vos_mem_free(rateUpdate);
1702 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001703 }
1704 break;
1705 }
1706
Jeff Johnson295189b2012-06-20 16:38:30 -07001707 default:
1708 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1709 sub_cmd, set_value);
1710 ret = -EINVAL;
1711 break;
1712 }
1713
1714 return ret;
1715}
1716
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301717int
1718static iw_softap_setparam(struct net_device *dev,
1719 struct iw_request_info *info,
1720 union iwreq_data *wrqu, char *extra)
1721{
1722 int ret;
1723
1724 vos_ssr_protect(__func__);
1725 ret = __iw_softap_setparam(dev, info, wrqu, extra);
1726 vos_ssr_unprotect(__func__);
1727
1728 return ret;
1729}
Jeff Johnson295189b2012-06-20 16:38:30 -07001730
1731int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301732static __iw_softap_getparam(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001733 struct iw_request_info *info,
1734 union iwreq_data *wrqu, char *extra)
1735{
1736 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1737 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Girish Gowli385be612014-09-18 11:17:20 +05301738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 int *value = (int *)extra;
1740 int sub_cmd = value[0];
1741 eHalStatus status;
1742 int ret = 0; /* success */
1743 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1744
1745 switch (sub_cmd)
1746 {
1747 case QCSAP_PARAM_MAX_ASSOC:
1748 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1749 if (eHAL_STATUS_SUCCESS != status)
1750 {
c_hpothuffdb5272013-10-02 16:42:35 +05301751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1752 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 ret = -EIO;
1754 }
Girish Gowli385be612014-09-18 11:17:20 +05301755
1756#ifdef WLAN_SOFTAP_VSTA_FEATURE
1757 if (pHddCtx->cfg_ini->fEnableVSTASupport)
1758 {
1759 if (*value > VSTA_NUM_ASSOC_STA)
1760 {
1761 *value = VSTA_NUM_ASSOC_STA;
1762 }
1763 if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) &&
1764 (*value > (VSTA_NUM_ASSOC_STA -
1765 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA))))
1766 {
1767 *value = (VSTA_NUM_ASSOC_STA -
1768 (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA));
1769 }
1770 }
1771 else
1772#endif
1773 {
1774 if (*value > NUM_ASSOC_STA)
1775 {
1776 *value = NUM_ASSOC_STA;
1777 }
1778 if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) &&
1779 (*value > (NUM_ASSOC_STA -
1780 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA))))
1781 {
1782 *value = (NUM_ASSOC_STA -
1783 (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA));
1784 }
1785 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001786 break;
1787
1788 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001789 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 {
c_hpothuffdb5272013-10-02 16:42:35 +05301791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 ret = -EIO;
1794 }
1795 *value = 0;
1796 break;
1797
Jeff Johnson43971f52012-07-17 12:26:56 -07001798 case QCSAP_PARAM_GET_WLAN_DBG:
1799 {
1800 vos_trace_display();
1801 *value = 0;
1802 break;
1803 }
1804
1805 case QCSAP_PARAM_AUTO_CHANNEL:
1806 {
1807 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1808 break;
1809 }
1810
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 default:
1812 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1813 ret = -EINVAL;
1814 break;
1815
1816 }
1817
1818 return ret;
1819}
1820
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301821int
1822static iw_softap_getparam(struct net_device *dev,
1823 struct iw_request_info *info,
1824 union iwreq_data *wrqu, char *extra)
1825{
1826 int ret;
1827
1828 vos_ssr_protect(__func__);
1829 ret = __iw_softap_getparam(dev, info, wrqu, extra);
1830 vos_ssr_unprotect(__func__);
1831
1832 return ret;
1833}
Jeff Johnson295189b2012-06-20 16:38:30 -07001834/* Usage:
1835 BLACK_LIST = 0
1836 WHITE_LIST = 1
1837 ADD MAC = 0
1838 REMOVE MAC = 1
1839
1840 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1841 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1842 while using this ioctl
1843
1844 Syntax:
1845 iwpriv softap.0 modify_acl
1846 <6 octet mac addr> <list type> <cmd type>
1847
1848 Examples:
1849 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1850 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1851 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1852 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1853*/
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301854int __iw_softap_modify_acl(struct net_device *dev,
1855 struct iw_request_info *info,
1856 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001857{
1858 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1859 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1860 v_BYTE_t *value = (v_BYTE_t*)extra;
1861 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1862 int listType, cmd, i;
1863 int ret = 0; /* success */
1864
1865 ENTER();
1866 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1867 {
1868 pPeerStaMac[i] = *(value+i);
1869 }
1870 listType = (int)(*(value+i));
1871 i++;
1872 cmd = (int)(*(value+i));
1873
Arif Hussain24bafea2013-11-15 15:10:03 -08001874 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1875 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001876
1877 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1878 != VOS_STATUS_SUCCESS)
1879 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001880 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 ret = -EIO;
1882 }
1883 EXIT();
1884 return ret;
1885}
1886
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301887int iw_softap_modify_acl(struct net_device *dev,
1888 struct iw_request_info *info,
1889 union iwreq_data *wrqu, char *extra)
1890{
1891 int ret;
1892
1893 vos_ssr_protect(__func__);
1894 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
1895 vos_ssr_unprotect(__func__);
1896
1897 return ret;
1898}
1899
Jeff Johnson295189b2012-06-20 16:38:30 -07001900int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301901static __iw_softap_getchannel(struct net_device *dev,
1902 struct iw_request_info *info,
1903 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07001904{
1905 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1906
Jeff Johnson43971f52012-07-17 12:26:56 -07001907 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001908
Jeff Johnson43971f52012-07-17 12:26:56 -07001909 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001910 return 0;
1911}
1912
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301913
Jeff Johnsone7245742012-09-05 17:12:55 -07001914int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301915static iw_softap_getchannel(struct net_device *dev,
1916 struct iw_request_info *info,
1917 union iwreq_data *wrqu, char *extra)
1918{
1919 int ret;
1920
1921 vos_ssr_protect(__func__);
1922 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
1923 vos_ssr_unprotect(__func__);
1924
1925 return ret;
1926}
1927
1928int
1929static __iw_softap_set_max_tx_power(struct net_device *dev,
1930 struct iw_request_info *info,
1931 union iwreq_data *wrqu, char *extra)
Jeff Johnsone7245742012-09-05 17:12:55 -07001932{
1933 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1934 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001935 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001936 int set_value;
1937 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1938 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1939
schang86c22c42013-03-13 18:41:24 -07001940 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001941 return -ENOMEM;
1942
Leo Changd37675a2013-08-01 13:19:45 -07001943 /* Assign correct slef MAC address */
1944 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1945 VOS_MAC_ADDR_SIZE);
1946 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1947 VOS_MAC_ADDR_SIZE);
1948
schang86c22c42013-03-13 18:41:24 -07001949 set_value = value[0];
1950 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1951 {
1952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001953 __func__);
schang86c22c42013-03-13 18:41:24 -07001954 return -EIO;
1955 }
1956
1957 return 0;
1958}
1959
1960int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301961static iw_softap_set_max_tx_power(struct net_device *dev,
1962 struct iw_request_info *info,
1963 union iwreq_data *wrqu, char *extra)
1964{
1965 int ret;
1966
1967 vos_ssr_protect(__func__);
1968 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
1969 vos_ssr_unprotect(__func__);
1970
1971 return ret;
1972}
1973
1974
1975int
1976static __iw_display_data_path_snapshot(struct net_device *dev,
1977 struct iw_request_info *info,
1978 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301979{
1980
1981 /* Function intitiating dumping states of
1982 * HDD(WMM Tx Queues)
1983 * TL State (with Per Client infor)
1984 * DXE Snapshot (Called at the end of TL Snapshot)
1985 */
1986 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1987 hddLog(LOGE, "%s: called for SAP",__func__);
1988 hdd_wmm_tx_snapshot(pHostapdAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +05301989 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301990 return 0;
1991}
1992
1993int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05301994static iw_display_data_path_snapshot(struct net_device *dev,
1995 struct iw_request_info *info,
1996 union iwreq_data *wrqu, char *extra)
1997{
1998 int ret;
1999
2000 vos_ssr_protect(__func__);
2001 ret = __iw_display_data_path_snapshot(dev, info, wrqu, extra);
2002 vos_ssr_unprotect(__func__);
2003
2004 return ret;
2005}
2006
2007int
2008static __iw_softap_set_tx_power(struct net_device *dev,
2009 struct iw_request_info *info,
2010 union iwreq_data *wrqu, char *extra)
schang86c22c42013-03-13 18:41:24 -07002011{
2012 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2013 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2014 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2015 int *value = (int *)extra;
2016 int set_value;
2017 ptSapContext pSapCtx = NULL;
2018
2019 if (NULL == value)
2020 return -ENOMEM;
2021
2022 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2023 if (NULL == pSapCtx)
2024 {
2025 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2026 "%s: Invalid SAP pointer from pvosGCtx", __func__);
2027 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07002028 }
2029
2030 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07002031 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07002032 {
schang86c22c42013-03-13 18:41:24 -07002033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07002034 __func__);
2035 return -EIO;
2036 }
2037
2038 return 0;
2039}
2040
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302041int
2042static iw_softap_set_tx_power(struct net_device *dev,
2043 struct iw_request_info *info,
2044 union iwreq_data *wrqu, char *extra)
2045{
2046 int ret;
2047
2048 vos_ssr_protect(__func__);
2049 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
2050 vos_ssr_unprotect(__func__);
2051
2052 return ret;
2053}
2054
Kiet Lambcf38522013-10-26 18:28:27 +05302055/**---------------------------------------------------------------------------
2056
2057 \brief iw_softap_set_trafficmonitor() -
2058 This function dynamically enable/disable traffic monitor functonality
2059 the command iwpriv wlanX setTrafficMon <value>.
2060
2061 \param - dev - Pointer to the net device.
2062 - addr - Pointer to the sockaddr.
2063 \return - 0 for success, non zero for failure
2064
2065 --------------------------------------------------------------------------*/
2066
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302067static int __iw_softap_set_trafficmonitor(struct net_device *dev,
2068 struct iw_request_info *info,
2069 union iwreq_data *wrqu, char *extra)
Kiet Lambcf38522013-10-26 18:28:27 +05302070{
2071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik128a0bb2014-08-07 20:24:54 +05302072 int *isSetTrafficMon = (int *)extra;
Kiet Lambcf38522013-10-26 18:28:27 +05302073 hdd_context_t *pHddCtx;
2074 int status;
2075
2076 if (NULL == pAdapter)
2077 {
2078 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2079 "%s: HDD adapter is Null", __func__);
2080 return -ENODEV;
2081 }
2082
2083 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2084
2085 status = wlan_hdd_validate_context(pHddCtx);
2086
2087 if (0 != status)
2088 {
2089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2090 "%s: HDD context is not valid", __func__);
2091 return status;
2092 }
2093
2094 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
2095
2096 if (NULL == isSetTrafficMon)
2097 {
2098 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2099 "%s: Invalid SAP pointer from extra", __func__);
2100 return -ENOMEM;
2101 }
2102
2103 if (TRUE == *isSetTrafficMon)
2104 {
2105 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
2106 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
2107 {
2108 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2109 "%s: failed to Start Traffic Monitor timer ", __func__ );
2110 return -EIO;
2111 }
2112 }
2113 else if (FALSE == *isSetTrafficMon)
2114 {
2115 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
2116 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
2117 {
2118 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
2119 "%s: failed to Stop Traffic Monitor timer ", __func__ );
2120 return -EIO;
2121 }
2122
2123 }
2124 return 0;
2125}
2126
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302127static int iw_softap_set_trafficmonitor(struct net_device *dev,
2128 struct iw_request_info *info,
2129 union iwreq_data *wrqu, char *extra)
2130{
2131 int ret;
2132
2133 vos_ssr_protect(__func__);
2134 ret = __iw_softap_set_trafficmonitor(dev, info, wrqu, extra);
2135 vos_ssr_unprotect(__func__);
2136
2137 return ret;
2138}
2139
Jeff Johnson295189b2012-06-20 16:38:30 -07002140#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
2141
2142int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302143static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
2144 struct iw_request_info *info,
2145 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002146{
2147 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302148 hdd_station_info_t *pStaInfo = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002149 char *buf;
2150 int cnt = 0;
2151 int left;
2152 int ret = 0;
2153 /* maclist_index must be u32 to match userspace */
2154 u32 maclist_index;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302155 v_CONTEXT_t pVosContext = NULL;
2156 ptSapContext pSapCtx = NULL;
Jeff Johnson224f3702014-03-26 11:09:47 -07002157 /*
2158 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
2159 * number, and even numbered iocts are supposed to have "set"
2160 * semantics. Hence the wireless extensions support in the kernel
2161 * won't correctly copy the result to userspace, so the ioctl
2162 * handler itself must copy the data. Output format is 32-bit
2163 * record length, followed by 0 or more 6-byte STA MAC addresses.
2164 *
2165 * Further note that due to the incorrect semantics, the "iwpriv"
2166 * userspace application is unable to correctly invoke this API,
2167 * hence it is not registered in the hostapd_private_args. This
2168 * API can only be invoked by directly invoking the ioctl() system
2169 * call.
2170 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002171
Jeff Johnson224f3702014-03-26 11:09:47 -07002172 /* make sure userspace allocated a reasonable buffer size */
2173 if (wrqu->data.length < sizeof(maclist_index)) {
2174 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
2175 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07002176 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002177
Jeff Johnson224f3702014-03-26 11:09:47 -07002178 /* allocate local buffer to build the response */
2179 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
2180 if (!buf) {
2181 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
2182 return -ENOMEM;
2183 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302184 pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2185 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2186 if(pSapCtx == NULL){
2187 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
2188 FL("psapCtx is NULL"));
2189 return -EFAULT;
2190 }
2191 pStaInfo = pSapCtx->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07002192 /* start indexing beyond where the record count will be written */
2193 maclist_index = sizeof(maclist_index);
2194 left = wrqu->data.length - maclist_index;
2195
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302196 spin_lock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002197 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
2198 if ((pStaInfo[cnt].isUsed) &&
2199 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
2200 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
2201 VOS_MAC_ADDR_SIZE);
2202 maclist_index += VOS_MAC_ADDR_SIZE;
2203 left -= VOS_MAC_ADDR_SIZE;
2204 }
2205 cnt++;
2206 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302207 spin_unlock_bh(&pSapCtx->staInfo_lock);
Jeff Johnson224f3702014-03-26 11:09:47 -07002208
2209 *((u32 *)buf) = maclist_index;
2210 wrqu->data.length = maclist_index;
2211 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
2212 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
2213 ret = -EFAULT;
2214 }
2215 kfree(buf);
2216 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002217}
2218
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302219int
2220static iw_softap_getassoc_stamacaddr(struct net_device *dev,
2221 struct iw_request_info *info,
2222 union iwreq_data *wrqu, char *extra)
2223{
2224 int ret;
2225
2226 vos_ssr_protect(__func__);
2227 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
2228 vos_ssr_unprotect(__func__);
2229
2230 return ret;
2231}
2232
Jeff Johnson295189b2012-06-20 16:38:30 -07002233/* Usage:
2234 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
2235 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
2236 while using this ioctl
2237
2238 Syntax:
2239 iwpriv softap.0 disassoc_sta <6 octet mac address>
2240
2241 e.g.
2242 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
2243 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
2244*/
2245
2246int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302247static __iw_softap_disassoc_sta(struct net_device *dev,
2248 struct iw_request_info *info,
2249 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002250{
2251 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2252 v_U8_t *peerMacAddr;
2253
2254 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302255 /* iwpriv tool or framework calls this ioctl with
2256 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07002257 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05302258 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002259
Arif Hussain24bafea2013-11-15 15:10:03 -08002260 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
2261 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
2263 EXIT();
2264 return 0;
2265}
2266
2267int
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302268static iw_softap_disassoc_sta(struct net_device *dev,
2269 struct iw_request_info *info,
2270 union iwreq_data *wrqu, char *extra)
2271{
2272 int ret;
2273
2274 vos_ssr_protect(__func__);
2275 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
2276 vos_ssr_unprotect(__func__);
2277
2278 return ret;
2279}
2280
2281int
2282static __iw_softap_ap_stats(struct net_device *dev,
2283 struct iw_request_info *info,
2284 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002285{
2286 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2287 WLANTL_TRANSFER_STA_TYPE statBuffer;
2288 char *pstatbuf;
Girish Gowlif3769802014-06-16 21:17:16 +05302289 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07002290
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002291 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07002292 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
2293 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002294
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302295 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07002296 if(NULL == pstatbuf) {
2297 hddLog(LOG1, "unable to allocate memory");
2298 return -ENOMEM;
2299 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302300
2301 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07002302 "RUF=%d RMF=%d RBF=%d "
2303 "RUB=%d RMB=%d RBB=%d "
2304 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302305 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002306 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2307 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2308 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2309 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2310 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2311 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002312
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302313 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002314 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2315 kfree(pstatbuf);
2316 return -EFAULT;
2317 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302318
2319 strlcpy(extra, pstatbuf, len);
2320 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002321 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 return 0;
2323}
2324
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302325int
2326static iw_softap_ap_stats(struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002327 struct iw_request_info *info,
2328 union iwreq_data *wrqu, char *extra)
2329{
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302330 int ret;
2331
2332 vos_ssr_protect(__func__);
2333 ret = __iw_softap_ap_stats(dev, info, wrqu, extra);
2334 vos_ssr_unprotect(__func__);
2335
2336 return ret;
2337}
2338
2339static int __iw_softap_set_channel_range(struct net_device *dev,
2340 struct iw_request_info *info,
2341 union iwreq_data *wrqu, char *extra)
2342{
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2344 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002345 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002346
2347 int *value = (int *)extra;
2348 int startChannel = value[0];
2349 int endChannel = value[1];
2350 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002351 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002352 int ret = 0; /* success */
2353
2354 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2355 if(status != VOS_STATUS_SUCCESS)
2356 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002357 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002358 startChannel,endChannel, band);
2359 ret = -EINVAL;
2360 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002361
2362 pHddCtx->is_dynamic_channel_range_set = 1;
2363
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 return ret;
2365}
2366
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302367static int iw_softap_set_channel_range(struct net_device *dev,
2368 struct iw_request_info *info,
2369 union iwreq_data *wrqu, char *extra)
2370{
2371 int ret;
2372
2373 vos_ssr_protect(__func__);
2374 ret = __iw_softap_set_channel_range(dev, info, wrqu, extra);
2375 vos_ssr_unprotect(__func__);
2376
2377 return ret;
2378}
2379
2380
2381int __iw_softap_get_channel_list(struct net_device *dev,
2382 struct iw_request_info *info,
2383 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002384{
2385 v_U32_t num_channels = 0;
2386 v_U8_t i = 0;
2387 v_U8_t bandStartChannel = RF_CHAN_1;
2388 v_U8_t bandEndChannel = RF_CHAN_165;
2389 v_U32_t temp_num_channels = 0;
2390 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2391 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2392 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002393 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002394 eCsrBand curBand = eCSR_BAND_ALL;
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302395 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002396
2397 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2398 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002399 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002400 return -EIO;
2401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 wrqu->data.length = sizeof(tChannelListInfo);
2403 ENTER();
2404
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002405 if (eCSR_BAND_24 == curBand)
2406 {
2407 bandStartChannel = RF_CHAN_1;
2408 bandEndChannel = RF_CHAN_14;
2409 }
2410 else if (eCSR_BAND_5G == curBand)
2411 {
2412 bandStartChannel = RF_CHAN_36;
2413 bandEndChannel = RF_CHAN_165;
2414 }
2415
Arif Hussain6d2a3322013-11-17 19:50:10 -08002416 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302417 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002418 bandStartChannel, bandEndChannel );
2419
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2421 {
2422 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2423 {
2424 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2425 num_channels++;
2426 }
2427 }
2428
2429 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2430
2431 temp_num_channels = num_channels;
2432
2433 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2434 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302435 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002436 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 }
2438
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302439 if(REGDOMAIN_FCC == domainIdCurrentSoftap &&
2440 pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC )
Jeff Johnson295189b2012-06-20 16:38:30 -07002441 {
2442 for(i = 0; i < temp_num_channels; i++)
2443 {
2444
2445 if((channel_list->channels[i] > 35) &&
2446 (channel_list->channels[i] < 49))
2447 {
2448 vos_mem_move(&channel_list->channels[i],
2449 &channel_list->channels[i+1],
2450 temp_num_channels - (i-1));
2451 num_channels--;
2452 temp_num_channels--;
2453 i--;
2454 }
2455 }
2456 }
2457
Arif Hussain6d2a3322013-11-17 19:50:10 -08002458 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002459
2460 if (num_channels > IW_MAX_FREQUENCIES)
2461 {
2462 num_channels = IW_MAX_FREQUENCIES;
2463 }
2464
2465 channel_list->num_channels = num_channels;
2466 EXIT();
2467
2468 return 0;
2469}
2470
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302471int iw_softap_get_channel_list(struct net_device *dev,
2472 struct iw_request_info *info,
2473 union iwreq_data *wrqu, char *extra)
2474{
2475 int ret;
2476
2477 vos_ssr_protect(__func__);
2478 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
2479 vos_ssr_unprotect(__func__);
2480
2481 return ret;
2482}
2483
2484static
2485int __iw_get_genie(struct net_device *dev,
2486 struct iw_request_info *info,
2487 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002488{
2489 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2490 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2491 eHalStatus status;
2492 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2493 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2494 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002495 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002496 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2497 status = WLANSap_getstationIE_information(pVosContext,
2498 &length,
2499 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002500 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2501 if (wrqu->data.length < length ||
2502 copy_to_user(wrqu->data.pointer,
2503 (v_VOID_t*)genIeBytes, length))
2504 {
2505 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2506 return -EFAULT;
2507 }
2508 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002509
Arif Hussain6d2a3322013-11-17 19:50:10 -08002510 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002511
2512
2513 EXIT();
2514 return 0;
2515}
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302516
2517static
2518int iw_get_genie(struct net_device *dev,
2519 struct iw_request_info *info,
2520 union iwreq_data *wrqu, char *extra)
2521{
2522 int ret;
2523
2524 vos_ssr_protect(__func__);
2525 ret = __iw_get_genie(dev, info, wrqu, extra);
2526 vos_ssr_unprotect(__func__);
2527
2528 return ret;
2529}
2530
2531static
2532int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2533 struct iw_request_info *info,
2534 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002535{
2536 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002537 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002538 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2539 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002540
Arif Hussain6d2a3322013-11-17 19:50:10 -08002541 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002542 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2543
2544 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2545 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2546 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2547 WPSPBCProbeReqIEs.probeReqIELen);
2548 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2549 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2550 sizeof(v_MACADDR_t));
2551 if (copy_to_user(wrqu->data.pointer,
2552 (void *)&WPSPBCProbeReqIEs,
2553 sizeof(WPSPBCProbeReqIEs)))
2554 {
2555 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2556 return -EFAULT;
2557 }
2558 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002559 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002560 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002561 up(&pHddApCtx->semWpsPBCOverlapInd);
2562 EXIT();
2563 return 0;
2564}
2565
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05302566static
2567int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2568 struct iw_request_info *info,
2569 union iwreq_data *wrqu, char *extra)
2570{
2571 int ret;
2572
2573 vos_ssr_protect(__func__);
2574 ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra);
2575 vos_ssr_unprotect(__func__);
2576
2577 return ret;
2578}
2579
Jeff Johnson295189b2012-06-20 16:38:30 -07002580/**---------------------------------------------------------------------------
2581
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302582 \brief __iw_set_auth_hostap() -
Jeff Johnson295189b2012-06-20 16:38:30 -07002583 This function sets the auth type received from the wpa_supplicant.
2584
2585 \param - dev - Pointer to the net device.
2586 - info - Pointer to the iw_request_info.
2587 - wrqu - Pointer to the iwreq_data.
2588 - extra - Pointer to the data.
2589 \return - 0 for success, non zero for failure
2590
2591 --------------------------------------------------------------------------*/
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302592int __iw_set_auth_hostap(struct net_device *dev,
2593 struct iw_request_info *info,
2594 union iwreq_data *wrqu,char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002595{
2596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2597 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2598
2599 ENTER();
2600 switch(wrqu->param.flags & IW_AUTH_INDEX)
2601 {
2602 case IW_AUTH_TKIP_COUNTERMEASURES:
2603 {
2604 if(wrqu->param.value) {
2605 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2606 "Counter Measure started %d", wrqu->param.value);
2607 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2608 }
2609 else {
2610 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2611 "Counter Measure stopped=%d", wrqu->param.value);
2612 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2613 }
2614
2615 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2616 wrqu->param.value);
2617 }
2618 break;
2619
2620 default:
2621
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002622 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002623 wrqu->param.flags & IW_AUTH_INDEX);
2624 break;
2625 }
2626
2627 EXIT();
2628 return 0;
2629}
2630
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302631int iw_set_auth_hostap(struct net_device *dev,
2632 struct iw_request_info *info,
2633 union iwreq_data *wrqu,char *extra)
2634{
2635 int ret;
2636
2637 vos_ssr_protect(__func__);
2638 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
2639 vos_ssr_unprotect(__func__);
2640
2641 return ret;
2642}
2643
2644static int __iw_set_ap_encodeext(struct net_device *dev,
2645 struct iw_request_info *info,
2646 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002647{
2648 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2649 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2650 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002651 int retval = 0;
2652 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002653 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2654 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2655 int key_index;
2656 struct iw_point *encoding = &wrqu->encoding;
2657 tCsrRoamSetKey setKey;
2658// tCsrRoamRemoveKey RemoveKey;
2659 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002660
Jeff Johnson295189b2012-06-20 16:38:30 -07002661 ENTER();
2662
2663 key_index = encoding->flags & IW_ENCODE_INDEX;
2664
2665 if(key_index > 0) {
2666
2667 /*Convert from 1-based to 0-based keying*/
2668 key_index--;
2669 }
2670 if(!ext->key_len) {
2671#if 0
2672 /*Set the encrytion type to NONE*/
2673#if 0
2674 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2675#endif
2676
2677 RemoveKey.keyId = key_index;
2678 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2679 /*Key direction for group is RX only*/
2680 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2681 }
2682 else {
2683 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2684 }
2685 switch(ext->alg)
2686 {
2687 case IW_ENCODE_ALG_NONE:
2688 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2689 break;
2690 case IW_ENCODE_ALG_WEP:
2691 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2692 break;
2693 case IW_ENCODE_ALG_TKIP:
2694 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002695 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 case IW_ENCODE_ALG_CCMP:
2697 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2698 break;
2699 default:
2700 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2701 break;
2702 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002703 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 -07002704 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002706 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002707 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002708 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2709 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002710 {
2711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002712 __LINE__, vstatus );
2713 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002714 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002715#endif
2716 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002717
Jeff Johnson43971f52012-07-17 12:26:56 -07002718 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002719
2720 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2721
2722 setKey.keyId = key_index;
2723 setKey.keyLength = ext->key_len;
2724
2725 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2726 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2727 }
2728
2729 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2730 /*Key direction for group is RX only*/
2731 setKey.keyDirection = eSIR_RX_ONLY;
2732 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2733 }
2734 else {
2735
2736 setKey.keyDirection = eSIR_TX_RX;
2737 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2738 }
2739 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2740 {
2741 setKey.keyDirection = eSIR_TX_DEFAULT;
2742 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2743 }
2744
2745 /*For supplicant pae role is zero*/
2746 setKey.paeRole = 0;
2747
2748 switch(ext->alg)
2749 {
2750 case IW_ENCODE_ALG_NONE:
2751 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2752 break;
2753
2754 case IW_ENCODE_ALG_WEP:
2755 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2756 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002757 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002758 break;
2759
2760 case IW_ENCODE_ALG_TKIP:
2761 {
2762 v_U8_t *pKey = &setKey.Key[0];
2763
2764 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2765
2766 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2767
2768 /*Supplicant sends the 32bytes key in this order
2769
2770 |--------------|----------|----------|
2771 | Tk1 |TX-MIC | RX Mic |
2772 |--------------|----------|----------|
2773 <---16bytes---><--8bytes--><--8bytes-->
2774
2775 */
2776 /*Sme expects the 32 bytes key to be in the below order
2777
2778 |--------------|----------|----------|
2779 | Tk1 |RX-MIC | TX Mic |
2780 |--------------|----------|----------|
2781 <---16bytes---><--8bytes--><--8bytes-->
2782 */
2783 /* Copy the Temporal Key 1 (TK1) */
2784 vos_mem_copy(pKey,ext->key,16);
2785
2786 /*Copy the rx mic first*/
2787 vos_mem_copy(&pKey[16],&ext->key[24],8);
2788
2789 /*Copy the tx mic */
2790 vos_mem_copy(&pKey[24],&ext->key[16],8);
2791
2792 }
2793 break;
2794
2795 case IW_ENCODE_ALG_CCMP:
2796 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2797 break;
2798
2799 default:
2800 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2801 break;
2802 }
2803
2804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302805 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002806 setKey.keyId);
2807 for(i=0; i< ext->key_len; i++)
2808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2809 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002810
2811 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2812 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002813 {
2814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002815 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2816 retval = -EINVAL;
2817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002818
Jeff Johnson43971f52012-07-17 12:26:56 -07002819 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002820}
Jeff Johnson43971f52012-07-17 12:26:56 -07002821
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302822static int iw_set_ap_encodeext(struct net_device *dev,
2823 struct iw_request_info *info,
2824 union iwreq_data *wrqu, char *extra)
2825{
2826 int ret;
2827
2828 vos_ssr_protect(__func__);
2829 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
2830 vos_ssr_unprotect(__func__);
2831
2832 return ret;
2833}
Jeff Johnson43971f52012-07-17 12:26:56 -07002834
Jeff Johnson295189b2012-06-20 16:38:30 -07002835static int iw_set_ap_mlme(struct net_device *dev,
2836 struct iw_request_info *info,
2837 union iwreq_data *wrqu,
2838 char *extra)
2839{
2840#if 0
2841 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2842 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2843
2844 ENTER();
2845
2846 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2847 switch (mlme->cmd) {
2848 case IW_MLME_DISASSOC:
2849 case IW_MLME_DEAUTH:
2850 hddLog(LOG1, "Station disassociate");
2851 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2852 {
2853 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2854
2855 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2856 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2857
2858 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2859
2860 //clear all the reason codes
2861 if (status != 0)
2862 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002863 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002864 }
2865
2866 netif_stop_queue(dev);
2867 netif_carrier_off(dev);
2868 }
2869 else
2870 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002871 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 -07002872 }
2873 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002874 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002875 return -EINVAL;
2876 }//end of switch
2877 EXIT();
2878#endif
2879 return 0;
2880// return status;
2881}
2882
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302883static int __iw_get_ap_rts_threshold(struct net_device *dev,
2884 struct iw_request_info *info,
2885 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002886{
2887 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2888 v_U32_t status = 0;
2889
2890 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2891
2892 return status;
2893}
2894
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302895static int iw_get_ap_rts_threshold(struct net_device *dev,
2896 struct iw_request_info *info,
2897 union iwreq_data *wrqu, char *extra)
2898{
2899 int ret;
2900
2901 vos_ssr_protect(__func__);
2902 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
2903 vos_ssr_unprotect(__func__);
2904
2905 return ret;
2906}
2907
2908static int __iw_get_ap_frag_threshold(struct net_device *dev,
2909 struct iw_request_info *info,
2910 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002911{
2912 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2913 v_U32_t status = 0;
2914
2915 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2916
2917 return status;
2918}
2919
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302920static int iw_get_ap_frag_threshold(struct net_device *dev,
2921 struct iw_request_info *info,
2922 union iwreq_data *wrqu, char *extra)
2923{
2924 int ret;
2925
2926 vos_ssr_protect(__func__);
2927 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
2928 vos_ssr_unprotect(__func__);
2929
2930 return ret;
2931}
2932
2933static int __iw_get_ap_freq(struct net_device *dev,
2934 struct iw_request_info *info,
2935 struct iw_freq *fwrq, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002936{
Jeff Johnsone7245742012-09-05 17:12:55 -07002937 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2939 tHalHandle hHal;
2940 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002941 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002942
2943 ENTER();
2944
2945 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2947 "%s:LOGP in Progress. Ignore!!!",__func__);
2948 return status;
2949 }
2950
2951 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2952 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2953
2954 if(pHostapdState->bssState == BSS_STOP )
2955 {
2956 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2957 != eHAL_STATUS_SUCCESS)
2958 {
c_hpothuffdb5272013-10-02 16:42:35 +05302959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2960 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 return -EIO;
2962 }
2963 else
2964 {
2965 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002966 if( TRUE == status)
2967 {
2968 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2969 * iwlist & iwconfig command shows frequency into proper
2970 * format (2.412 GHz instead of 246.2 MHz)*/
2971 fwrq->m = freq;
2972 fwrq->e = MHZ;
2973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 }
2975 }
2976 else
2977 {
2978 channel = pHddApCtx->operatingChannel;
2979 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002980 if( TRUE == status)
2981 {
2982 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2983 * iwlist & iwconfig command shows frequency into proper
2984 * format (2.412 GHz instead of 246.2 MHz)*/
2985 fwrq->m = freq;
2986 fwrq->e = MHZ;
2987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002988 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002989 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002990}
2991
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302992static int iw_get_ap_freq(struct net_device *dev,
2993 struct iw_request_info *info,
2994 struct iw_freq *fwrq, char *extra)
2995{
2996 int ret;
2997
2998 vos_ssr_protect(__func__);
2999 ret = __iw_get_ap_freq(dev, info, fwrq, extra);
3000 vos_ssr_unprotect(__func__);
3001
3002 return ret;
3003}
3004
3005static int __iw_get_mode(struct net_device *dev,
3006 struct iw_request_info *info,
3007 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303008{
3009 int status = 0;
3010
3011 wrqu->mode = IW_MODE_MASTER;
3012
3013 return status;
3014}
3015
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303016static int iw_get_mode(struct net_device *dev,
3017 struct iw_request_info *info,
3018 union iwreq_data *wrqu, char *extra)
3019{
3020 int ret;
3021
3022 vos_ssr_protect(__func__);
3023 ret = __iw_get_mode(dev, info, wrqu, extra);
3024 vos_ssr_unprotect(__func__);
3025
3026 return ret;
3027}
3028
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303029static int __iw_softap_setwpsie(struct net_device *dev,
3030 struct iw_request_info *info,
3031 union iwreq_data *wrqu,
3032 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003033{
3034 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3035 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3036 hdd_hostapd_state_t *pHostapdState;
3037 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003038 u_int8_t *wps_genie;
3039 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07003040 u_int8_t *pos;
3041 tpSap_WPSIE pSap_WPSIe;
3042 u_int8_t WPSIeType;
3043 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05303044 struct iw_point s_priv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003045 ENTER();
3046
Girish Gowli07c05ec2014-06-17 20:47:03 +05303047 /* helper function to get iwreq_data with compat handling. */
3048 if (hdd_priv_get_data(&s_priv_data, wrqu))
3049 {
3050 return -EINVAL;
3051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003052
Girish Gowli07c05ec2014-06-17 20:47:03 +05303053 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
3054 {
3055 return -EINVAL;
3056 }
3057
3058 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
3059 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07003060
Girish Gowli86c471e2014-06-17 19:28:05 +05303061 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07003062 {
Girish Gowli86c471e2014-06-17 19:28:05 +05303063 hddLog(LOG1, "%s: failed to alloc memory "
3064 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07003065 return -EFAULT;
3066 }
3067
Girish Gowli86c471e2014-06-17 19:28:05 +05303068 fwps_genie = wps_genie;
3069
Jeff Johnson295189b2012-06-20 16:38:30 -07003070 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
3071 if (NULL == pSap_WPSIe)
3072 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003073 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07003074 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003075 return -ENOMEM;
3076 }
3077 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
3078
Arif Hussain6d2a3322013-11-17 19:50:10 -08003079 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 -07003080 WPSIeType = wps_genie[0];
3081 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
3082 {
3083 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
3084 wps_genie = wps_genie + 1;
3085 switch ( wps_genie[0] )
3086 {
3087 case DOT11F_EID_WPA:
3088 if (wps_genie[1] < 2 + 4)
3089 {
3090 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003091 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003092 return -EINVAL;
3093 }
3094 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3095 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003096 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003097 pos = &wps_genie[6];
3098 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3099 {
3100 switch((u_int16_t)(*pos<<8) | *(pos+1))
3101 {
3102 case HDD_WPS_ELEM_VERSION:
3103 pos += 4;
3104 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003105 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003106 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
3107 pos += 1;
3108 break;
3109
3110 case HDD_WPS_ELEM_WPS_STATE:
3111 pos +=4;
3112 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003113 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003114 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
3115 pos += 1;
3116 break;
3117 case HDD_WPS_ELEM_APSETUPLOCK:
3118 pos += 4;
3119 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003120 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003121 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
3122 pos += 1;
3123 break;
3124 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3125 pos += 4;
3126 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003127 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003128 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
3129 pos += 1;
3130 break;
3131 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3132 pos += 4;
3133 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003134 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003135 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
3136 pos += 2;
3137 break;
3138 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3139 pos += 4;
3140 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003141 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003142 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
3143 pos += 2;
3144 break;
3145
3146 case HDD_WPS_ELEM_UUID_E:
3147 pos += 2;
3148 length = *pos<<8 | *(pos+1);
3149 pos += 2;
3150 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
3151 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
3152 pos += length;
3153 break;
3154 case HDD_WPS_ELEM_RF_BANDS:
3155 pos += 4;
3156 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003157 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003158 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
3159 pos += 1;
3160 break;
3161
3162 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08003163 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07003164 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003165 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003166 return -EINVAL;
3167 }
3168 }
3169 }
3170 else {
3171 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003172 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003173 }
3174 break;
3175
3176 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003177 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003178 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003179 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180 return 0;
3181 }
3182 }
3183 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
3184 {
3185 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
3186 wps_genie = wps_genie + 1;
3187 switch ( wps_genie[0] )
3188 {
3189 case DOT11F_EID_WPA:
3190 if (wps_genie[1] < 2 + 4)
3191 {
3192 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003193 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003194 return -EINVAL;
3195 }
3196 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
3197 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003198 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 pos = &wps_genie[6];
3200 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
3201 {
3202 switch((u_int16_t)(*pos<<8) | *(pos+1))
3203 {
3204 case HDD_WPS_ELEM_VERSION:
3205 pos += 4;
3206 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003207 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07003208 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
3209 pos += 1;
3210 break;
3211
3212 case HDD_WPS_ELEM_WPS_STATE:
3213 pos +=4;
3214 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003215 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003216 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
3217 pos += 1;
3218 break;
3219 case HDD_WPS_ELEM_APSETUPLOCK:
3220 pos += 4;
3221 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003222 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07003223 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
3224 pos += 1;
3225 break;
3226 case HDD_WPS_ELEM_SELECTEDREGISTRA:
3227 pos += 4;
3228 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003229 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003230 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
3231 pos += 1;
3232 break;
3233 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
3234 pos += 4;
3235 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003236 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07003237 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
3238 pos += 2;
3239 break;
3240 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3241 pos += 4;
3242 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003243 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003244 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
3245 pos += 2;
3246 break;
3247 case HDD_WPS_ELEM_RSP_TYPE:
3248 pos += 4;
3249 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003250 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07003251 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
3252 pos += 1;
3253 break;
3254 case HDD_WPS_ELEM_UUID_E:
3255 pos += 2;
3256 length = *pos<<8 | *(pos+1);
3257 pos += 2;
3258 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
3259 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
3260 pos += length;
3261 break;
3262
3263 case HDD_WPS_ELEM_MANUFACTURER:
3264 pos += 2;
3265 length = *pos<<8 | *(pos+1);
3266 pos += 2;
3267 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
3268 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
3269 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
3270 pos += length;
3271 break;
3272
3273 case HDD_WPS_ELEM_MODEL_NAME:
3274 pos += 2;
3275 length = *pos<<8 | *(pos+1);
3276 pos += 2;
3277 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
3278 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
3279 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
3280 pos += length;
3281 break;
3282 case HDD_WPS_ELEM_MODEL_NUM:
3283 pos += 2;
3284 length = *pos<<8 | *(pos+1);
3285 pos += 2;
3286 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
3287 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
3288 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
3289 pos += length;
3290 break;
3291 case HDD_WPS_ELEM_SERIAL_NUM:
3292 pos += 2;
3293 length = *pos<<8 | *(pos+1);
3294 pos += 2;
3295 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
3296 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
3297 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
3298 pos += length;
3299 break;
3300 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
3301 pos += 4;
3302 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003303 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003304 pos += 2;
3305
3306 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003307 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003308 pos += 4;
3309 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003310 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003311 pos += 2;
3312 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
3313 break;
3314 case HDD_WPS_ELEM_DEVICE_NAME:
3315 pos += 2;
3316 length = *pos<<8 | *(pos+1);
3317 pos += 2;
3318 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
3319 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
3320 pos += length;
3321 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
3322 break;
3323 case HDD_WPS_ELEM_CONFIG_METHODS:
3324 pos += 4;
3325 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003326 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003327 pos += 2;
3328 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
3329 break;
3330
3331 case HDD_WPS_ELEM_RF_BANDS:
3332 pos += 4;
3333 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003334 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003335 pos += 1;
3336 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
3337 break;
3338 } // switch
3339 }
3340 }
3341 else
3342 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003343 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003344 }
3345
3346 } // switch
3347 }
3348 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
3349 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3350 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3351 {
3352 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3353 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3354 WLANSAP_Update_WpsIe ( pVosContext );
3355 }
3356
3357 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003358 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003359 EXIT();
3360 return halStatus;
3361}
3362
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303363static int iw_softap_setwpsie(struct net_device *dev,
3364 struct iw_request_info *info,
3365 union iwreq_data *wrqu,
3366 char *extra)
3367{
3368 int ret;
3369
3370 vos_ssr_protect(__func__);
3371 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
3372 vos_ssr_unprotect(__func__);
3373
3374 return ret;
3375}
3376
3377static int __iw_softap_stopbss(struct net_device *dev,
3378 struct iw_request_info *info,
3379 union iwreq_data *wrqu,
3380 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003381{
3382 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3383 VOS_STATUS status = VOS_STATUS_SUCCESS;
Agarwal Ashish51325b52014-06-16 16:50:49 +05303384 hdd_context_t *pHddCtx = NULL;
3385
Jeff Johnson295189b2012-06-20 16:38:30 -07003386 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +05303387
3388 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3389 status = wlan_hdd_validate_context(pHddCtx);
3390
3391 if (0 != status) {
3392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
3393 return status;
3394 }
3395
Jeff Johnson295189b2012-06-20 16:38:30 -07003396 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3397 {
3398 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
3399 {
3400 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3401
3402 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
3403
3404 if (!VOS_IS_STATUS_SUCCESS(status))
3405 {
3406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003407 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 VOS_ASSERT(0);
3409 }
3410 }
3411 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05303412 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003413 }
3414 EXIT();
3415 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
3416}
3417
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303418static int iw_softap_stopbss(struct net_device *dev,
3419 struct iw_request_info *info,
3420 union iwreq_data *wrqu,
3421 char *extra)
3422{
3423 int ret;
3424
3425 vos_ssr_protect(__func__);
3426 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
3427 vos_ssr_unprotect(__func__);
3428
3429 return ret;
3430}
3431
3432static int __iw_softap_version(struct net_device *dev,
3433 struct iw_request_info *info,
3434 union iwreq_data *wrqu,
3435 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003436{
Jeff Johnson295189b2012-06-20 16:38:30 -07003437 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003438
Jeff Johnson295189b2012-06-20 16:38:30 -07003439 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003440 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003441 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003442 return 0;
3443}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003444
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303445static int iw_softap_version(struct net_device *dev,
3446 struct iw_request_info *info,
3447 union iwreq_data *wrqu,
3448 char *extra)
3449{
3450 int ret;
3451
3452 vos_ssr_protect(__func__);
3453 ret = __iw_softap_version(dev, info, wrqu, extra);
3454 vos_ssr_unprotect(__func__);
3455
3456 return ret;
3457}
3458
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003459VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003460{
3461 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003462 int len = 0;
3463 const char sta_info_header[] = "staId staAddress\n";
3464
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303465 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3466 ptSapContext pSapCtx = NULL;
3467 pSapCtx = VOS_GET_SAP_CB(pVosContext);
3468 if(pSapCtx == NULL){
3469 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
3470 FL("psapCtx is NULL"));
3471 return VOS_STATUS_E_FAULT;
3472 }
3473
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003474 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003475 pBuf += len;
3476 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003477
3478 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
3479 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303480 if(pSapCtx->aStaInfo[i].isUsed)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003481 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003482 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05303483 pSapCtx->aStaInfo[i].ucSTAId,
3484 pSapCtx->aStaInfo[i].macAddrSTA.bytes[0],
3485 pSapCtx->aStaInfo[i].macAddrSTA.bytes[1],
3486 pSapCtx->aStaInfo[i].macAddrSTA.bytes[2],
3487 pSapCtx->aStaInfo[i].macAddrSTA.bytes[3],
3488 pSapCtx->aStaInfo[i].macAddrSTA.bytes[4],
3489 pSapCtx->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003490 pBuf += len;
3491 buf_len -= len;
3492 }
3493 if(WE_GET_STA_INFO_SIZE > buf_len)
3494 {
3495 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003496 }
3497 }
3498 return VOS_STATUS_SUCCESS;
3499}
3500
3501static int iw_softap_get_sta_info(struct net_device *dev,
3502 struct iw_request_info *info,
3503 union iwreq_data *wrqu,
3504 char *extra)
3505{
3506 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3507 VOS_STATUS status;
3508 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003509 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003510 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003512 return -EINVAL;
3513 }
3514 wrqu->data.length = strlen(extra);
3515 EXIT();
3516 return 0;
3517}
3518
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303519static int __iw_set_ap_genie(struct net_device *dev,
3520 struct iw_request_info *info,
3521 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003522{
3523
3524 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3525 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3526 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003527 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003528
3529 ENTER();
3530
3531 if(!wrqu->data.length)
3532 {
3533 EXIT();
3534 return 0;
3535 }
Arif Hussained667642013-10-27 23:01:14 -07003536
Jeff Johnson295189b2012-06-20 16:38:30 -07003537 switch (genie[0])
3538 {
3539 case DOT11F_EID_WPA:
3540 case DOT11F_EID_RSN:
3541 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3542 {
3543 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3544 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3545 }
3546 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003547 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003548 break;
3549
3550 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003551 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003552 halStatus = 0;
3553 }
3554
3555 EXIT();
3556 return halStatus;
3557}
3558
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303559static int iw_set_ap_genie(struct net_device *dev,
3560 struct iw_request_info *info,
3561 union iwreq_data *wrqu, char *extra)
3562{
3563 int ret;
3564
3565 vos_ssr_protect(__func__);
3566 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
3567 vos_ssr_unprotect(__func__);
3568
3569 return ret;
3570}
3571
Jeff Johnson295189b2012-06-20 16:38:30 -07003572static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3573{
3574 eHalStatus hstatus;
3575 long lrc;
3576 struct statsContext context;
3577
3578 if (NULL == pAdapter)
3579 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003581 return VOS_STATUS_E_FAULT;
3582 }
3583
3584 init_completion(&context.completion);
3585 context.pAdapter = pAdapter;
3586 context.magic = STATS_CONTEXT_MAGIC;
3587 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3588 eCSR_HDD,
3589 SME_GLOBAL_CLASSA_STATS,
3590 hdd_GetClassA_statisticsCB,
3591 0, // not periodic
3592 FALSE, //non-cached results
3593 staid,
3594 &context);
3595 if (eHAL_STATUS_SUCCESS != hstatus)
3596 {
3597 hddLog(VOS_TRACE_LEVEL_ERROR,
3598 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003599 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003600 }
3601 else
3602 {
3603 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3604 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003605 if (lrc <= 0)
3606 {
3607 hddLog(VOS_TRACE_LEVEL_ERROR,
3608 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003609 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 }
3611 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003612
3613 /* either we never sent a request, we sent a request and received a
3614 response or we sent a request and timed out. if we never sent a
3615 request or if we sent a request and got a response, we want to
3616 clear the magic out of paranoia. if we timed out there is a
3617 race condition such that the callback function could be
3618 executing at the same time we are. of primary concern is if the
3619 callback function had already verified the "magic" but had not
3620 yet set the completion variable when a timeout occurred. we
3621 serialize these activities by invalidating the magic while
3622 holding a shared spinlock which will cause us to block if the
3623 callback is currently executing */
3624 spin_lock(&hdd_context_lock);
3625 context.magic = 0;
3626 spin_unlock(&hdd_context_lock);
3627
Jeff Johnson295189b2012-06-20 16:38:30 -07003628 return VOS_STATUS_SUCCESS;
3629}
3630
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303631int __iw_get_softap_linkspeed(struct net_device *dev,
3632 struct iw_request_info *info,
3633 union iwreq_data *wrqu,
3634 char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003635
3636{
3637 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303638 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003639 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003640 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303641 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003642 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303643 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003644 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003645 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303646 int rc, valid;
3647
3648 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3649
3650 valid = wlan_hdd_validate_context(pHddCtx);
3651
3652 if (0 != valid)
3653 {
3654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3655 return valid;
3656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003657
Arif Hussain6d2a3322013-11-17 19:50:10 -08003658 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003659
3660 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003661 {
Arif Hussaina9571842014-01-15 16:43:41 -08003662 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3663 if (NULL == pmacAddress) {
3664 hddLog(LOG1, "unable to allocate memory");
3665 return -ENOMEM;
3666 }
3667 if (copy_from_user((void *)pmacAddress,
3668 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3669 {
3670 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3671 kfree(pmacAddress);
3672 return -EFAULT;
3673 }
3674 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3675
3676 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003677 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003678
3679 if (!VOS_IS_STATUS_SUCCESS(status ))
3680 {
3681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3682 }
Arif Hussained667642013-10-27 23:01:14 -07003683 }
Kiet Lam61589852013-09-19 17:10:58 +05303684 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303685 * link speed for first connected client will be returned.
3686 */
Arif Hussaina9571842014-01-15 16:43:41 -08003687 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303688 {
3689 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3690 }
3691 else
3692 {
3693 status = hdd_softap_GetStaId(pHostapdAdapter,
3694 (v_MACADDR_t *)macAddress, (void *)(&staId));
3695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003696
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303697 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003700 link_speed = 0;
3701 }
3702 else
3703 {
3704 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303705
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 if (!VOS_IS_STATUS_SUCCESS(status ))
3707 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003709 return -EINVAL;
3710 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303711
3712 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3713 staId, &link_speed);
3714
3715 link_speed = link_speed / 10;
3716
3717 if (0 == link_speed)
3718 {
3719 /* The linkspeed returned by HAL is in units of 500kbps.
3720 * converting it to mbps.
3721 * This is required to support legacy firmware which does
3722 * not return link capacity.
3723 */
3724 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3725 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 }
3727
3728 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003729 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303730
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 if ((rc < 0) || (rc >= len))
3732 {
3733 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303734 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 return -EIO;
3736 }
3737
3738 return 0;
3739}
3740
Mahesh A Saptasagar69e944e2014-08-13 20:01:27 +05303741int iw_get_softap_linkspeed(struct net_device *dev,
3742 struct iw_request_info *info,
3743 union iwreq_data *wrqu,
3744 char *extra)
3745{
3746 int ret;
3747
3748 vos_ssr_protect(__func__);
3749 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
3750 vos_ssr_unprotect(__func__);
3751
3752 return ret;
3753}
3754
3755
Jeff Johnson295189b2012-06-20 16:38:30 -07003756static const iw_handler hostapd_handler[] =
3757{
3758 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3759 (iw_handler) NULL, /* SIOCGIWNAME */
3760 (iw_handler) NULL, /* SIOCSIWNWID */
3761 (iw_handler) NULL, /* SIOCGIWNWID */
3762 (iw_handler) NULL, /* SIOCSIWFREQ */
3763 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3764 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303765 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 (iw_handler) NULL, /* SIOCSIWSENS */
3767 (iw_handler) NULL, /* SIOCGIWSENS */
3768 (iw_handler) NULL, /* SIOCSIWRANGE */
3769 (iw_handler) NULL, /* SIOCGIWRANGE */
3770 (iw_handler) NULL, /* SIOCSIWPRIV */
3771 (iw_handler) NULL, /* SIOCGIWPRIV */
3772 (iw_handler) NULL, /* SIOCSIWSTATS */
3773 (iw_handler) NULL, /* SIOCGIWSTATS */
3774 (iw_handler) NULL, /* SIOCSIWSPY */
3775 (iw_handler) NULL, /* SIOCGIWSPY */
3776 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3777 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3778 (iw_handler) NULL, /* SIOCSIWAP */
3779 (iw_handler) NULL, /* SIOCGIWAP */
3780 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3781 (iw_handler) NULL, /* SIOCGIWAPLIST */
3782 (iw_handler) NULL, /* SIOCSIWSCAN */
3783 (iw_handler) NULL, /* SIOCGIWSCAN */
3784 (iw_handler) NULL, /* SIOCSIWESSID */
3785 (iw_handler) NULL, /* SIOCGIWESSID */
3786 (iw_handler) NULL, /* SIOCSIWNICKN */
3787 (iw_handler) NULL, /* SIOCGIWNICKN */
3788 (iw_handler) NULL, /* -- hole -- */
3789 (iw_handler) NULL, /* -- hole -- */
3790 (iw_handler) NULL, /* SIOCSIWRATE */
3791 (iw_handler) NULL, /* SIOCGIWRATE */
3792 (iw_handler) NULL, /* SIOCSIWRTS */
3793 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3794 (iw_handler) NULL, /* SIOCSIWFRAG */
3795 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3796 (iw_handler) NULL, /* SIOCSIWTXPOW */
3797 (iw_handler) NULL, /* SIOCGIWTXPOW */
3798 (iw_handler) NULL, /* SIOCSIWRETRY */
3799 (iw_handler) NULL, /* SIOCGIWRETRY */
3800 (iw_handler) NULL, /* SIOCSIWENCODE */
3801 (iw_handler) NULL, /* SIOCGIWENCODE */
3802 (iw_handler) NULL, /* SIOCSIWPOWER */
3803 (iw_handler) NULL, /* SIOCGIWPOWER */
3804 (iw_handler) NULL, /* -- hole -- */
3805 (iw_handler) NULL, /* -- hole -- */
3806 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3807 (iw_handler) NULL, /* SIOCGIWGENIE */
3808 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3809 (iw_handler) NULL, /* SIOCGIWAUTH */
3810 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3811 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3812 (iw_handler) NULL, /* SIOCSIWPMKSA */
3813};
3814
Jeff Johnson224f3702014-03-26 11:09:47 -07003815/*
3816 * Note that the following ioctls were defined with semantics which
3817 * cannot be handled by the "iwpriv" userspace application and hence
3818 * they are not included in the hostapd_private_args array
3819 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3820 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003821
3822static const struct iw_priv_args hostapd_private_args[] = {
3823 { QCSAP_IOCTL_SETPARAM,
3824 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3825 { QCSAP_IOCTL_SETPARAM,
3826 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3827 { QCSAP_PARAM_MAX_ASSOC,
3828 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3829 { QCSAP_PARAM_HIDE_SSID,
3830 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003831 { QCSAP_PARAM_SET_MC_RATE,
3832 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003833 { QCSAP_IOCTL_GETPARAM,
3834 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3835 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3836 { QCSAP_IOCTL_GETPARAM, 0,
3837 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3838 { QCSAP_PARAM_MAX_ASSOC, 0,
3839 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003840 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3841 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3842 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3843 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303844 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3845 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003846 { QCSAP_PARAM_CLR_ACL, 0,
3847 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3848 { QCSAP_PARAM_ACL_MODE,
3849 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003850 { QCSAP_IOCTL_GET_STAWPAIE,
3851 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3852 { QCSAP_IOCTL_SETWPAIE,
3853 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3854 { QCSAP_IOCTL_STOPBSS,
3855 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3856 { QCSAP_IOCTL_VERSION, 0,
3857 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003858 { QCSAP_IOCTL_GET_STA_INFO, 0,
3859 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003860 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003861 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003862 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003863 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003864 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003865 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05303866 { QCSAP_IOCTL_AP_STATS, 0,
3867 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003868 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3869 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303870 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003871
3872 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3873 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3874 /* handlers for sub-ioctl */
3875 { WE_SET_WLAN_DBG,
3876 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3877 0,
3878 "setwlandbg" },
3879
3880 /* handlers for main ioctl */
3881 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3882 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3883 0,
3884 "" },
3885
3886 /* handlers for sub-ioctl */
3887 { WE_LOG_DUMP_CMD,
3888 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3889 0,
3890 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003891 { WE_P2P_NOA_CMD,
3892 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3893 0,
3894 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003895 /* handlers for sub ioctl */
3896 {
3897 WE_MCC_CONFIG_CREDENTIAL,
3898 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3899 0,
3900 "setMccCrdnl" },
3901
3902 /* handlers for sub ioctl */
3903 {
3904 WE_MCC_CONFIG_PARAMS,
3905 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3906 0,
3907 "setMccConfig" },
3908
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 /* handlers for main ioctl */
3910 { QCSAP_IOCTL_MODIFY_ACL,
3911 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3912 0,
3913 "modify_acl" },
3914
3915 /* handlers for main ioctl */
3916 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3917 0,
3918 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3919 "getChannelList" },
3920
Jeff Johnsone7245742012-09-05 17:12:55 -07003921 /* handlers for main ioctl */
3922 { QCSAP_IOCTL_SET_TX_POWER,
3923 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3924 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303925 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003926
3927 /* handlers for main ioctl */
3928 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3929 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3930 0,
3931 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303932
3933 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3934 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3935 0,
3936 "dataSnapshot" },
3937
3938 /* handlers for main ioctl */
3939 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3940 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3941 0,
3942 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003943};
Jeff Johnsone7245742012-09-05 17:12:55 -07003944
Jeff Johnson295189b2012-06-20 16:38:30 -07003945static const iw_handler hostapd_private[] = {
3946 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3947 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07003948 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3949 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3950 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3951 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3952 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3953 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3954 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3955 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3956 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3957 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3958 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3959 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3960 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3961 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003962 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003963 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3964 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003965 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303966 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303967 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003968};
3969const struct iw_handler_def hostapd_handler_def = {
3970 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3971 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3972 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3973 .standard = (iw_handler *)hostapd_handler,
3974 .private = (iw_handler *)hostapd_private,
3975 .private_args = hostapd_private_args,
3976 .get_wireless_stats = NULL,
3977};
3978#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3979struct net_device_ops net_ops_struct = {
3980 .ndo_open = hdd_hostapd_open,
3981 .ndo_stop = hdd_hostapd_stop,
3982 .ndo_uninit = hdd_hostapd_uninit,
3983 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3984 .ndo_tx_timeout = hdd_softap_tx_timeout,
3985 .ndo_get_stats = hdd_softap_stats,
3986 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3987 .ndo_do_ioctl = hdd_hostapd_ioctl,
3988 .ndo_change_mtu = hdd_hostapd_change_mtu,
3989 .ndo_select_queue = hdd_hostapd_select_queue,
3990 };
3991#endif
3992
3993int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3994{
3995 return VOS_STATUS_SUCCESS;
3996}
3997
3998void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3999{
4000#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
4001 pWlanHostapdDev->netdev_ops = &net_ops_struct;
4002#else
4003 pWlanHostapdDev->open = hdd_hostapd_open;
4004 pWlanHostapdDev->stop = hdd_hostapd_stop;
4005 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
4006 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
4007 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
4008 pWlanHostapdDev->get_stats = hdd_softap_stats;
4009 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
4010 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
4011#endif
4012}
4013
4014VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
4015{
4016 hdd_hostapd_state_t * phostapdBuf;
4017 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004018 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004019 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08004020#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08004021 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
4022 v_U16_t unsafeChannelCount;
4023#endif /* FEATURE_WLAN_CH_AVOID */
4024
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 ENTER();
4026 // Allocate the Wireless Extensions state structure
4027 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
4028
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07004029 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
4030
Leo Chang0b0e45a2013-12-15 15:18:55 -08004031#ifdef FEATURE_WLAN_CH_AVOID
4032 /* Get unsafe cahnnel list from cached location */
4033 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
4034 sizeof(unsafeChannelList),
4035 &unsafeChannelCount);
4036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4037 "%s : Unsafe Channel count %d",
4038 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05304039 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08004040 unsafeChannelList,
4041 unsafeChannelCount);
4042#endif /* FEATURE_WLAN_CH_AVOID */
4043
Jeff Johnson295189b2012-06-20 16:38:30 -07004044 // Zero the memory. This zeros the profile structure.
4045 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
4046
4047 // Set up the pointer to the Wireless Extensions state structure
4048 // NOP
4049 status = hdd_set_hostapd(pAdapter);
4050 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004052 return status;
4053 }
4054
4055 status = vos_event_init(&phostapdBuf->vosEvent);
4056 if (!VOS_IS_STATUS_SUCCESS(status))
4057 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004059 return status;
4060 }
4061
4062 init_completion(&pAdapter->session_close_comp_var);
4063 init_completion(&pAdapter->session_open_comp_var);
4064
4065 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
4066
4067 // Register as a wireless device
4068 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
4069
4070 //Initialize the data path module
4071 status = hdd_softap_init_tx_rx(pAdapter);
4072 if ( !VOS_IS_STATUS_SUCCESS( status ))
4073 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004074 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304076
4077 status = hdd_wmm_adapter_init( pAdapter );
4078 if (!VOS_IS_STATUS_SUCCESS(status))
4079 {
4080 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004081 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304082 status, status );
4083 goto error_wmm_init;
4084 }
4085
4086 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
4087
Jeff Johnson295189b2012-06-20 16:38:30 -07004088 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304089
4090 return status;
4091
4092error_wmm_init:
4093 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07004094 EXIT();
4095 return status;
4096}
4097
4098hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
4099{
4100 struct net_device *pWlanHostapdDev = NULL;
4101 hdd_adapter_t *pHostapdAdapter = NULL;
4102 v_CONTEXT_t pVosContext= NULL;
4103
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07004105
4106 if (pWlanHostapdDev != NULL)
4107 {
4108 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
4109
4110 //Init the net_device structure
4111 ether_setup(pWlanHostapdDev);
4112
4113 //Initialize the adapter context to zeros.
4114 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
4115 pHostapdAdapter->dev = pWlanHostapdDev;
4116 pHostapdAdapter->pHddCtx = pHddCtx;
4117 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
4118
4119 //Get the Global VOSS context.
4120 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4121 //Save the adapter context in global context for future.
4122 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
4123
4124 //Init the net_device structure
4125 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
4126
4127 hdd_set_ap_ops( pHostapdAdapter->dev );
4128
Jeff Johnson295189b2012-06-20 16:38:30 -07004129 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
4130 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
4131
4132 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
4133 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
4134
4135 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07004136 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
4137 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
4138 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
4139 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
4141 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05304142 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07004143#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4144 init_completion(&pHostapdAdapter->offchannel_tx_event);
4145#endif
4146
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
4148 }
4149 return pHostapdAdapter;
4150}
4151
4152VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
4153{
4154 struct net_device *dev = pAdapter->dev;
4155 VOS_STATUS status = VOS_STATUS_SUCCESS;
4156
4157 ENTER();
4158
4159 if( rtnl_lock_held )
4160 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08004161 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07004162 if( dev_alloc_name(dev, dev->name) < 0 )
4163 {
4164 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
4165 return VOS_STATUS_E_FAILURE;
4166 }
4167 }
4168 if (register_netdevice(dev))
4169 {
4170 hddLog(VOS_TRACE_LEVEL_FATAL,
4171 "%s:Failed:register_netdevice", __func__);
4172 return VOS_STATUS_E_FAILURE;
4173 }
4174 }
4175 else
4176 {
4177 if (register_netdev(dev))
4178 {
4179 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
4180 return VOS_STATUS_E_FAILURE;
4181 }
4182 }
4183 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
4184
4185 EXIT();
4186 return status;
4187}
4188
4189VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
4190{
4191 ENTER();
4192
4193 hdd_softap_deinit_tx_rx(pAdapter);
4194
4195 /* if we are being called during driver unload, then the dev has already
4196 been invalidated. if we are being called at other times, then we can
4197 detatch the wireless device handlers */
4198 if (pAdapter->dev)
4199 {
4200 pAdapter->dev->wireless_handlers = NULL;
4201 }
4202 EXIT();
4203 return 0;
4204}