blob: 1eab898fc30cbf4472b4e037d62f16bf3754a93c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
Jeff Johnson295189b2012-06-20 16:38:30 -070027
28/**========================================================================
29
30 \file wlan_hdd_hostapd.c
31 \brief WLAN Host Device Driver implementation
32
33 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
34
35 Qualcomm Confidential and Proprietary.
36
37 ========================================================================*/
38/**=========================================================================
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45 $Header:$ $DateTime: $ $Author: $
46
47
48 when who what, where, why
49 -------- --- --------------------------------------------------------
50 04/5/09 Shailender Created module.
51 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
52 ==========================================================================*/
53/*--------------------------------------------------------------------------
54 Include Files
55 ------------------------------------------------------------------------*/
56
57#include <linux/version.h>
58#include <linux/module.h>
59#include <linux/kernel.h>
60#include <linux/init.h>
61#include <linux/wireless.h>
62#include <linux/semaphore.h>
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -070063#include <linux/compat.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
66#include <linux/etherdevice.h>
67#include <wlan_hdd_includes.h>
68#include <qc_sap_ioctl.h>
69#include <wlan_hdd_hostapd.h>
70#include <sapApi.h>
71#include <sapInternal.h>
72#include <wlan_qct_tl.h>
73#include <wlan_hdd_softap_tx_rx.h>
74#include <wlan_hdd_main.h>
75#include <linux/netdevice.h>
76#include <linux/mmc/sdio_func.h>
77#include "wlan_nlink_common.h"
78#include "wlan_btc_svc.h"
79#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070080#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070081#include "cfgApi.h"
82#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070083
Leo Chang0b0e45a2013-12-15 15:18:55 -080084#ifdef FEATURE_WLAN_CH_AVOID
85#include "wcnss_wlan.h"
86#endif /* FEATURE_WLAN_CH_AVOID */
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Leo Chang0b0e45a2013-12-15 15:18:55 -080090
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define IS_UP(_dev) \
92 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
93#define IS_UP_AUTO(_ic) \
94 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
95#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -070096#define WE_GET_STA_INFO_SIZE 30
97/* WEXT limition: MAX allowed buf len for any *
98 * IW_PRIV_TYPE_CHAR is 2Kbytes *
99 */
100#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530102#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700103
Leo Chang0b0e45a2013-12-15 15:18:55 -0800104#ifdef FEATURE_WLAN_CH_AVOID
105/* Channle/Freqency table */
106extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
107safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
108{
109 /*CH , SAFE, default safe */
110 {1 , VOS_TRUE}, //RF_CHAN_1,
111 {2 , VOS_TRUE}, //RF_CHAN_2,
112 {3 , VOS_TRUE}, //RF_CHAN_3,
113 {4 , VOS_TRUE}, //RF_CHAN_4,
114 {5 , VOS_TRUE}, //RF_CHAN_5,
115 {6 , VOS_TRUE}, //RF_CHAN_6,
116 {7 , VOS_TRUE}, //RF_CHAN_7,
117 {8 , VOS_TRUE}, //RF_CHAN_8,
118 {9 , VOS_TRUE}, //RF_CHAN_9,
119 {10 , VOS_TRUE}, //RF_CHAN_10,
120 {11 , VOS_TRUE}, //RF_CHAN_11,
121 {12 , VOS_TRUE}, //RF_CHAN_12,
122 {13 , VOS_TRUE}, //RF_CHAN_13,
123 {14 , VOS_TRUE}, //RF_CHAN_14,
124 {240, VOS_TRUE}, //RF_CHAN_240,
125 {244, VOS_TRUE}, //RF_CHAN_244,
126 {248, VOS_TRUE}, //RF_CHAN_248,
127 {252, VOS_TRUE}, //RF_CHAN_252,
128 {208, VOS_TRUE}, //RF_CHAN_208,
129 {212, VOS_TRUE}, //RF_CHAN_212,
130 {216, VOS_TRUE}, //RF_CHAN_216,
131 {36 , VOS_TRUE}, //RF_CHAN_36,
132 {40 , VOS_TRUE}, //RF_CHAN_40,
133 {44 , VOS_TRUE}, //RF_CHAN_44,
134 {48 , VOS_TRUE}, //RF_CHAN_48,
135 {52 , VOS_TRUE}, //RF_CHAN_52,
136 {56 , VOS_TRUE}, //RF_CHAN_56,
137 {60 , VOS_TRUE}, //RF_CHAN_60,
138 {64 , VOS_TRUE}, //RF_CHAN_64,
139 {100, VOS_TRUE}, //RF_CHAN_100,
140 {104, VOS_TRUE}, //RF_CHAN_104,
141 {108, VOS_TRUE}, //RF_CHAN_108,
142 {112, VOS_TRUE}, //RF_CHAN_112,
143 {116, VOS_TRUE}, //RF_CHAN_116,
144 {120, VOS_TRUE}, //RF_CHAN_120,
145 {124, VOS_TRUE}, //RF_CHAN_124,
146 {128, VOS_TRUE}, //RF_CHAN_128,
147 {132, VOS_TRUE}, //RF_CHAN_132,
148 {136, VOS_TRUE}, //RF_CHAN_136,
149 {140, VOS_TRUE}, //RF_CHAN_140,
150 {149, VOS_TRUE}, //RF_CHAN_149,
151 {153, VOS_TRUE}, //RF_CHAN_153,
152 {157, VOS_TRUE}, //RF_CHAN_157,
153 {161, VOS_TRUE}, //RF_CHAN_161,
154 {165, VOS_TRUE}, //RF_CHAN_165,
155};
156#endif /* FEATURE_WLAN_CH_AVOID */
157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530158/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 * Function definitions
160 *-------------------------------------------------------------------------*/
161/**---------------------------------------------------------------------------
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530162
Jeff Johnson295189b2012-06-20 16:38:30 -0700163 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530164
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 This is called in response to ifconfig up
166
167 \param - dev Pointer to net_device structure
168
169 \return - 0 for success non-zero for failure
170
171 --------------------------------------------------------------------------*/
172int hdd_hostapd_open (struct net_device *dev)
173{
174 ENTER();
175
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530176 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
177 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 //Turn ON carrier state
179 netif_carrier_on(dev);
180 //Enable all Tx queues
181 netif_tx_start_all_queues(dev);
182
183 EXIT();
184 return 0;
185}
186/**---------------------------------------------------------------------------
187
188 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
189
190 This is called in response to ifconfig down
191
192 \param - dev Pointer to net_device structure
193
194 \return - 0 for success non-zero for failure
195
196 --------------------------------------------------------------------------*/
197int hdd_hostapd_stop (struct net_device *dev)
198{
199 ENTER();
200
201 //Stop all tx queues
202 netif_tx_disable(dev);
203
204 //Turn OFF carrier state
205 netif_carrier_off(dev);
206
207 EXIT();
208 return 0;
209}
210/**---------------------------------------------------------------------------
211
212 \brief hdd_hostapd_uninit() - HDD uninit function
213
214 This is called during the netdev unregister to uninitialize all data
215associated with the device
216
217 \param - dev Pointer to net_device structure
218
219 \return - void
220
221 --------------------------------------------------------------------------*/
222static void hdd_hostapd_uninit (struct net_device *dev)
223{
224 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
225
226 ENTER();
227
228 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
229 {
230 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
231
232 /* after uninit our adapter structure will no longer be valid */
233 pHostapdAdapter->dev = NULL;
234 }
235
236 EXIT();
237}
238
239
240/**============================================================================
241 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
242 transmitting packets. There are 2 versions of this function. One that uses
243 locked queue and other that uses lockless queues. Both have been retained to
244 do some performance testing
245 @param skb : [in] pointer to OS packet (sk_buff)
246 @param dev : [in] pointer to Libra network device
247
248 @return : NET_XMIT_DROP if packets are dropped
249 : NET_XMIT_SUCCESS if packet is enqueued succesfully
250 ===========================================================================*/
251int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
252{
253 return 0;
254}
255int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
256{
257 return 0;
258}
259
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700260static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
261 hdd_priv_data_t *priv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -0700262{
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700263 tANI_U8 *command = NULL;
264 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700265
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700266 /*
267 * Note that valid pointers are provided by caller
268 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700269
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700270 if (priv_data->total_len <= 0 ||
271 priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
272 {
273 /* below we allocate one more byte for command buffer.
274 * To avoid addition overflow total_len should be
275 * smaller than INT_MAX. */
276 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
277 __func__, priv_data->total_len);
278 ret = -EFAULT;
279 goto exit;
280 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700282 /* Allocate +1 for '\0' */
283 command = kmalloc((priv_data->total_len + 1), GFP_KERNEL);
284 if (!command)
285 {
286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__);
287 ret = -ENOMEM;
288 goto exit;
289 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700290
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700291 if (copy_from_user(command, priv_data->buf, priv_data->total_len))
292 {
293 ret = -EFAULT;
294 goto exit;
295 }
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800296
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700297 /* Make sure the command is NUL-terminated */
298 command[priv_data->total_len] = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -0700299
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700300 hddLog(VOS_TRACE_LEVEL_INFO,
301 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700303 if (strncmp(command, "P2P_SET_NOA", 11) == 0)
304 {
305 hdd_setP2pNoa(pAdapter->dev, command);
306 }
307 else if (strncmp(command, "P2P_SET_PS", 10) == 0)
308 {
309 hdd_setP2pOpps(pAdapter->dev, command);
310 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800311#ifdef FEATURE_WLAN_BATCH_SCAN
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700312 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
313 {
314 ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command);
315 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800316#endif
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700317 else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
318 {
319 /*
320 * command should be a string having format
321 * SET_SAP_CHANNEL_LIST <num channels> <channels seperated by spaces>
322 */
323 hddLog(VOS_TRACE_LEVEL_INFO,
324 "%s: Received Command to Set Preferred Channels for SAP",
325 __func__);
Rajeev Kumar8b373292014-01-08 20:36:55 -0800326
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700327 ret = sapSetPreferredChannel(command);
328 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700329
Jeff Johnson295189b2012-06-20 16:38:30 -0700330exit:
331 if (command)
332 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700333 kfree(command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 }
335 return ret;
336}
337
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700338#ifdef CONFIG_COMPAT
339static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
340 struct ifreq *ifr)
341{
342 struct {
343 compat_uptr_t buf;
344 int used_len;
345 int total_len;
346 } compat_priv_data;
347 hdd_priv_data_t priv_data;
348 int ret = 0;
349
350 /*
351 * Note that pAdapter and ifr have already been verified by caller,
352 * and HDD context has also been validated
353 */
354 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
355 sizeof(compat_priv_data))) {
356 ret = -EFAULT;
357 goto exit;
358 }
359 priv_data.buf = compat_ptr(compat_priv_data.buf);
360 priv_data.used_len = compat_priv_data.used_len;
361 priv_data.total_len = compat_priv_data.total_len;
362 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
363 exit:
364 return ret;
365}
366#else /* CONFIG_COMPAT */
367static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
368 struct ifreq *ifr)
369{
370 /* will never be invoked */
371 return 0;
372}
373#endif /* CONFIG_COMPAT */
374
375static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
376{
377 hdd_priv_data_t priv_data;
378 int ret = 0;
379
380 /*
381 * Note that pAdapter and ifr have already been verified by caller,
382 * and HDD context has also been validated
383 */
384 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
385 ret = -EFAULT;
386 } else {
387 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
388 }
389 return ret;
390}
391
392static int hdd_hostapd_ioctl(struct net_device *dev,
393 struct ifreq *ifr, int cmd)
394{
395 hdd_adapter_t *pAdapter;
396 hdd_context_t *pHddCtx;
397 int ret;
398
399 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
400 if (NULL == pAdapter) {
401 hddLog(VOS_TRACE_LEVEL_ERROR,
402 "%s: HDD adapter context is Null", __func__);
403 ret = -ENODEV;
404 goto exit;
405 }
406 if (dev != pAdapter->dev) {
407 hddLog(VOS_TRACE_LEVEL_ERROR,
408 "%s: HDD adapter/dev inconsistency", __func__);
409 ret = -ENODEV;
410 goto exit;
411 }
412
413 if ((!ifr) || (!ifr->ifr_data)) {
414 ret = -EINVAL;
415 goto exit;
416 }
417
418 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
419 ret = wlan_hdd_validate_context(pHddCtx);
420 if (ret) {
421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__);
422 ret = -EBUSY;
423 goto exit;
424 }
425
426 switch (cmd) {
427 case (SIOCDEVPRIVATE + 1):
428 if (is_compat_task())
429 ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
430 else
431 ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
432 break;
433 default:
434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
435 __func__, cmd);
436 ret = -EINVAL;
437 break;
438 }
439 exit:
440 return ret;
441}
442
Jeff Johnson295189b2012-06-20 16:38:30 -0700443/**---------------------------------------------------------------------------
444
445 \brief hdd_hostapd_set_mac_address() -
446 This function sets the user specified mac address using
447 the command ifconfig wlanX hw ether <mac adress>.
448
449 \param - dev - Pointer to the net device.
450 - addr - Pointer to the sockaddr.
451 \return - 0 for success, non zero for failure
452
453 --------------------------------------------------------------------------*/
454
455static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
456{
457 struct sockaddr *psta_mac_addr = addr;
458 ENTER();
459 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
460 EXIT();
461 return 0;
462}
463void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
464{
465 struct net_device *dev = (struct net_device *)usrDataForCallback;
466 v_BYTE_t we_custom_event[64];
467 union iwreq_data wrqu;
468#ifdef DISABLE_CONCURRENCY_AUTOSAVE
469 VOS_STATUS vos_status;
470 hdd_adapter_t *pHostapdAdapter;
471 hdd_ap_ctx_t *pHddApCtx;
472#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
473
474 /* event_name space-delimiter driver_module_name */
475 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
476 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
477 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
478
479 ENTER();
480
481#ifdef DISABLE_CONCURRENCY_AUTOSAVE
482 if (vos_concurrent_sessions_running())
483 {
484 /*
485 This timer routine is going to be called only when AP
486 persona is up.
487 If there are concurrent sessions running we do not want
488 to shut down the Bss.Instead we run the timer again so
489 that if Autosave is enabled next time and other session
490 was down only then we bring down AP
491 */
492 pHostapdAdapter = netdev_priv(dev);
493 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
494 vos_status = vos_timer_start(
495 &pHddApCtx->hdd_ap_inactivity_timer,
496 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
497 * 1000);
498 if (!VOS_IS_STATUS_SUCCESS(vos_status))
499 {
500 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
501 }
502 EXIT();
503 return;
504 }
505#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
506 memset(&we_custom_event, '\0', sizeof(we_custom_event));
507 memcpy(&we_custom_event, autoShutEvent, event_len);
508
509 memset(&wrqu, 0, sizeof(wrqu));
510 wrqu.data.length = event_len;
511
512 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
513 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
514
515 EXIT();
516}
517
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800518VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
519{
520 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
521 ptSapContext pSapCtx = NULL;
522 eHalStatus halStatus = eHAL_STATUS_FAILURE;
523 v_PVOID_t hHal = NULL;
524
525 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
526 "%s: UPDATE Beacon Params", __func__);
527
528 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
529 pSapCtx = VOS_GET_SAP_CB(pVosContext);
530 if ( NULL == pSapCtx )
531 {
532 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
533 "%s: Invalid SAP pointer from pvosGCtx", __func__);
534 return VOS_STATUS_E_FAULT;
535 }
536
537 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
538 if ( NULL == hHal ){
539 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
540 "%s: Invalid HAL pointer from pvosGCtx", __func__);
541 return VOS_STATUS_E_FAULT;
542 }
543 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
544 if(halStatus == eHAL_STATUS_FAILURE ){
545 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
546 "%s: Failed to update Beacon Params", __func__);
547 return VOS_STATUS_E_FAILURE;
548 }
549 }
550 return VOS_STATUS_SUCCESS;
551}
552
553void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
554{
555 v_U8_t staId = 0;
556 struct net_device *dev;
557 dev = (struct net_device *)usrDataForCallback;
558
Arif Hussain6d2a3322013-11-17 19:50:10 -0800559 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800560 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
561 {
562 if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
563 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
564 {
565 //Disconnect all the stations
566 hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
567 }
568 }
569}
570
571static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
572{
573 struct net_device *dev;
574 VOS_STATUS status = VOS_STATUS_SUCCESS;
575 dev = (struct net_device *)usrDataForCallback;
576 ENTER();
577 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
578 {
579 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
580 {
581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
582 }
583 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
584 }
585 EXIT();
586 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
587}
Jeff Johnson295189b2012-06-20 16:38:30 -0700588
589VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
590{
591 hdd_adapter_t *pHostapdAdapter;
592 hdd_ap_ctx_t *pHddApCtx;
593 hdd_hostapd_state_t *pHostapdState;
594 struct net_device *dev;
595 eSapHddEvent sapEvent;
596 union iwreq_data wrqu;
597 v_BYTE_t *we_custom_event_generic = NULL;
598 int we_event = 0;
599 int i = 0;
600 v_U8_t staId;
601 VOS_STATUS vos_status;
602 v_BOOL_t bWPSState;
603 v_BOOL_t bApActive = FALSE;
604 v_BOOL_t bAuthRequired = TRUE;
605 tpSap_AssocMacAddr pAssocStasArray = NULL;
606 char unknownSTAEvent[IW_CUSTOM_MAX+1];
607 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
608 v_BYTE_t we_custom_start_event[64];
609 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800610 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800611 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700612 struct iw_michaelmicfailure msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700613
614 dev = (struct net_device *)usrDataForCallback;
615 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530616
617 if ((NULL == pHostapdAdapter) ||
618 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
619 {
620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
621 "invalid adapter or adapter has invalid magic");
622 return eHAL_STATUS_FAILURE;
623 }
624
Jeff Johnson295189b2012-06-20 16:38:30 -0700625 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
626 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
627 sapEvent = pSapEvent->sapHddEventCode;
628 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800629 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700630
631 switch(sapEvent)
632 {
633 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800634 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700635 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
636 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
637 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
638
639 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
640 vos_status = vos_event_set(&pHostapdState->vosEvent);
641
642 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
643 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700645 goto stopbss;
646 }
647 else
648 {
649 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
650 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530651 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
652 if (!VOS_IS_STATUS_SUCCESS(vos_status))
653 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 }
655
656 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
657 {
658 // AP Inactivity timer init and start
659 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
660 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
661 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800662 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700663
664 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
665 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800666 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700667
668 }
669 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
670 pHostapdState->bssState = BSS_START;
671
672 // Send current operating channel of SoftAP to BTC-ES
673 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
674
Jeff Johnson295189b2012-06-20 16:38:30 -0700675 //Check if there is any group key pending to set.
676 if( pHddApCtx->groupKey.keyLength )
677 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700678 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700679 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
680 &pHddApCtx->groupKey ) )
681 {
682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
683 "%s: WLANSAP_SetKeySta failed", __func__);
684 }
685 pHddApCtx->groupKey.keyLength = 0;
686 }
687 else if ( pHddApCtx->wepKey[0].keyLength )
688 {
689 int i=0;
690 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
691 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700692 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
694 &pHddApCtx->wepKey[i] ) )
695 {
696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
697 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
698 }
699 pHddApCtx->wepKey[i].keyLength = 0;
700 }
701 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
703 startBssEvent = "SOFTAP.enabled";
704 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
705 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
706 memset(&wrqu, 0, sizeof(wrqu));
707 wrqu.data.length = strlen(startBssEvent);
708 we_event = IWEVCUSTOM;
709 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700710 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 break; //Event will be sent after Switch-Case stmt
712
713 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800714 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700715 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
716
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700717 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700718 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700719
Jeff Johnson295189b2012-06-20 16:38:30 -0700720 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700721 goto stopbss;
722 case eSAP_STA_SET_KEY_EVENT:
723 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800724 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
726 return VOS_STATUS_SUCCESS;
727 case eSAP_STA_DEL_KEY_EVENT:
728 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800729 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 return VOS_STATUS_SUCCESS;
731 case eSAP_STA_MIC_FAILURE_EVENT:
732 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 memset(&msg, '\0', sizeof(msg));
734 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800735 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800736 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700737 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 msg.flags = IW_MICFAILURE_GROUP;
739 else
740 msg.flags = IW_MICFAILURE_PAIRWISE;
741 memset(&wrqu, 0, sizeof(wrqu));
742 wrqu.data.length = sizeof(msg);
743 we_event = IWEVMICHAELMICFAILURE;
744 we_custom_event_generic = (v_BYTE_t *)&msg;
745 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 /* inform mic failure to nl80211 */
747 cfg80211_michael_mic_failure(dev,
748 pSapEvent->sapevt.
749 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700750 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700751 NL80211_KEYTYPE_GROUP :
752 NL80211_KEYTYPE_PAIRWISE),
753 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
754 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
755 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700756 break;
757
758 case eSAP_STA_ASSOC_EVENT:
759 case eSAP_STA_REASSOC_EVENT:
760 wrqu.addr.sa_family = ARPHRD_ETHER;
761 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800762 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800763 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 we_event = IWEVREGISTERED;
765
766 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
767
768 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
769 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
770 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
771 {
772 bAuthRequired = FALSE;
773 }
774
775 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
776 {
c_hpothuffdb5272013-10-02 16:42:35 +0530777 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 TRUE,
779 pHddApCtx->uPrivacy,
780 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
781 0,
782 0,
783 (v_MACADDR_t *)wrqu.addr.sa_data,
784 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530785
786 if (!VOS_IS_STATUS_SUCCESS(vos_status))
787 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
788 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700789 }
790 else
791 {
c_hpothuffdb5272013-10-02 16:42:35 +0530792 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 FALSE,
794 pHddApCtx->uPrivacy,
795 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
796 0,
797 0,
798 (v_MACADDR_t *)wrqu.addr.sa_data,
799 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530800 if (!VOS_IS_STATUS_SUCCESS(vos_status))
801 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
802 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Amar Singhal6144c002013-05-03 16:11:42 -0700803 }
804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 // Stop AP inactivity timer
806 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
807 {
808 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
809 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800810 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700811 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800812#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800813 if (wake_lock_active(&pHddCtx->sap_wake_lock))
814 {
815 wake_unlock(&pHddCtx->sap_wake_lock);
816 }
Amar Singhal6144c002013-05-03 16:11:42 -0700817 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
820 {
821 struct station_info staInfo;
822 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
823
824 memset(&staInfo, 0, sizeof(staInfo));
825 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
826 {
827 staInfo.assoc_req_ies =
828 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
829 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700831 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
832#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 cfg80211_new_sta(dev,
834 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
835 &staInfo, GFP_KERNEL);
836 }
837 else
838 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800839 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 }
841 }
842#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800843 pScanInfo = &pHddCtx->scan_info;
844 // Lets do abort scan to ensure smooth authentication for client
845 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
846 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530847 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
848 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800849 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700850
851 break;
852 case eSAP_STA_DISASSOC_EVENT:
853 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800854 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800855 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700856 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
857 hddLog(LOG1," User initiated disassociation");
858 else
859 hddLog(LOG1," MAC initiated disassociation");
860 we_event = IWEVEXPIRED;
861 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
862 if (!VOS_IS_STATUS_SUCCESS(vos_status))
863 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700864 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 -0700865 return VOS_STATUS_E_FAILURE;
866 }
867 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
868
869 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
870 {
871 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
872 // Start AP inactivity timer if no stations associated with it
873 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
874 {
875 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
876 {
877 bApActive = TRUE;
878 break;
879 }
880 }
881 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
882
883 if (bApActive == FALSE)
884 {
885 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
886 {
887 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
888 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800889 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 }
891 else
892 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
893 }
894 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
896 cfg80211_del_sta(dev,
897 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
898 GFP_KERNEL);
899#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800900 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +0530901 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
902 if (VOS_STATUS_SUCCESS != vos_status)
903 {
904 hddLog(LOGE, "%s: failed to update Beacon interval %d",
905 __func__, vos_status);
906 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 break;
908 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
909 {
910 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
911 union iwreq_data wreq;
912
913 down(&pHddApCtx->semWpsPBCOverlapInd);
914 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
915
916 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
917 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
918
919 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800920 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700921 memset(&wreq, 0, sizeof(wreq));
922 wreq.data.length = strlen(message); // This is length of message
923 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
924
925 return VOS_STATUS_SUCCESS;
926 }
927 case eSAP_ASSOC_STA_CALLBACK_EVENT:
928 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
929 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
930 { // List of associated stations
931 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
932 {
933 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
934 i+1,
935 pAssocStasArray->assocId,
936 pAssocStasArray->staId,
937 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
938 pAssocStasArray++;
939 }
940 }
941 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800942 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700943 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 case eSAP_INDICATE_MGMT_FRAME:
945 hdd_indicateMgmtFrame( pHostapdAdapter,
946 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
947 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
948 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530949 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 return VOS_STATUS_SUCCESS;
951 case eSAP_REMAIN_CHAN_READY:
952 hdd_remainChanReadyHandler( pHostapdAdapter );
953 return VOS_STATUS_SUCCESS;
954 case eSAP_SEND_ACTION_CNF:
955 hdd_sendActionCnf( pHostapdAdapter,
956 ( eSAP_STATUS_SUCCESS ==
957 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
958 TRUE : FALSE );
959 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 case eSAP_UNKNOWN_STA_JOIN:
961 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
962 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
963 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
964 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
965 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
966 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
967 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
968 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
969 wrqu.data.pointer = unknownSTAEvent;
970 wrqu.data.length = strlen(unknownSTAEvent);
971 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +0530972 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 break;
974
975 case eSAP_MAX_ASSOC_EXCEEDED:
976 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
977 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
978 " one or more devices to enable the new device connection",
979 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
980 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
981 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
982 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
983 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
984 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
985 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
986 wrqu.data.pointer = maxAssocExceededEvent;
987 wrqu.data.length = strlen(maxAssocExceededEvent);
988 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -0800989 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 break;
991 case eSAP_STA_ASSOC_IND:
992 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800993
994 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800995 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800996 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
997 return VOS_STATUS_SUCCESS;
998
999 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
c_hpothuffdb5272013-10-02 16:42:35 +05301000 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1001 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1002 {
1003 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1004 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001005 return VOS_STATUS_SUCCESS;
1006
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001008 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 goto stopbss;
1010 return VOS_STATUS_SUCCESS;
1011 }
1012 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1013 return VOS_STATUS_SUCCESS;
1014
1015stopbss :
1016 {
1017 v_BYTE_t we_custom_event[64];
1018 char *stopBssEvent = "STOP-BSS.response";//17
1019 int event_len = strlen(stopBssEvent);
1020
1021 hddLog(LOG1, FL("BSS stop status = %s"),
1022 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1023 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1024
1025 /* Change the BSS state now since, as we are shutting things down,
1026 * we don't want interfaces to become re-enabled */
1027 pHostapdState->bssState = BSS_STOP;
1028
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301029 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1030 {
1031 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1032 {
1033 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1034 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1035 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1036 }
1037
1038 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1039 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1040 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1041 }
1042
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 /* Stop the pkts from n/w stack as we are going to free all of
1044 * the TX WMM queues for all STAID's */
1045 hdd_hostapd_stop(dev);
1046
1047 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301048 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1049 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1050 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001051
Amar Singhal37e6f052013-03-05 16:16:54 -08001052 /* once the event is set, structure dev/pHostapdAdapter should
1053 * not be touched since they are now subject to being deleted
1054 * by another thread */
1055 if (eSAP_STOP_BSS_EVENT == sapEvent)
1056 vos_event_set(&pHostapdState->vosEvent);
1057
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 /* notify userspace that the BSS has stopped */
1059 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1060 memcpy(&we_custom_event, stopBssEvent, event_len);
1061 memset(&wrqu, 0, sizeof(wrqu));
1062 wrqu.data.length = event_len;
1063 we_event = IWEVCUSTOM;
1064 we_custom_event_generic = we_custom_event;
1065 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001066 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 }
1068 return VOS_STATUS_SUCCESS;
1069}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001070
1071int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001073 eCsrEncryptionType *pEncryptType,
1074 eCsrEncryptionType *mcEncryptType,
1075 eCsrAuthType *pAuthType,
1076 v_BOOL_t *pMFPCapable,
1077 v_BOOL_t *pMFPRequired,
1078 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 u_int8_t *gen_ie )
1080{
1081 tDot11fIERSN dot11RSNIE;
1082 tDot11fIEWPA dot11WPAIE;
1083
1084 tANI_U8 *pRsnIe;
1085 tANI_U16 RSNIeLen;
1086
1087 if (NULL == halHandle)
1088 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001089 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 return -EINVAL;
1091 }
1092
1093 // Validity checks
1094 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1095 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1096 return -EINVAL;
1097 // Type check
1098 if ( gen_ie[0] == DOT11F_EID_RSN)
1099 {
1100 // Validity checks
1101 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1102 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1103 {
1104 return VOS_STATUS_E_FAILURE;
1105 }
1106 // Skip past the EID byte and length byte
1107 pRsnIe = gen_ie + 2;
1108 RSNIeLen = gen_ie_len - 2;
1109 // Unpack the RSN IE
1110 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1111 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1112 pRsnIe,
1113 RSNIeLen,
1114 &dot11RSNIE);
1115 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001116 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001117 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001118 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001119 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 /*Here we have followed the apple base code,
1121 but probably I suspect we can do something different*/
1122 //dot11RSNIE.akm_suite_count
1123 // Just translate the FIRST one
1124 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1125 //dot11RSNIE.pwise_cipher_suite_count
1126 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1127 //dot11RSNIE.gp_cipher_suite_count
1128 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1129 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001130 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1131 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001132
1133 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1134 } else
1135 if (gen_ie[0] == DOT11F_EID_WPA)
1136 {
1137 // Validity checks
1138 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1139 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1140 {
1141 return VOS_STATUS_E_FAILURE;
1142 }
1143 // Skip past the EID byte and length byte - and four byte WiFi OUI
1144 pRsnIe = gen_ie + 2 + 4;
1145 RSNIeLen = gen_ie_len - (2 + 4);
1146 // Unpack the WPA IE
1147 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1148 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1149 pRsnIe,
1150 RSNIeLen,
1151 &dot11WPAIE);
1152 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001153 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001154 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001155 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001156 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 //dot11WPAIE.auth_suite_count
1158 // Just translate the FIRST one
1159 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1160 //dot11WPAIE.unicast_cipher_count
1161 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1162 //dot11WPAIE.unicast_cipher_count
1163 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001164 *pMFPCapable = VOS_FALSE;
1165 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 }
1167 else
1168 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001169 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 return VOS_STATUS_E_FAILURE;
1171 }
1172 return VOS_STATUS_SUCCESS;
1173}
Leo Chang614d2072013-08-22 14:59:44 -07001174
Leo Chang0b0e45a2013-12-15 15:18:55 -08001175#ifdef FEATURE_WLAN_CH_AVOID
1176/**---------------------------------------------------------------------------
1177
1178 \brief hdd_hostapd_freq_to_chn() -
1179
1180 Input frequency translated into channel number
1181
1182 \param - freq input frequency with order of kHz
1183
1184 \return - corresponding channel number.
1185 incannot find correct channel number, return 0
1186
1187 --------------------------------------------------------------------------*/
1188v_U16_t hdd_hostapd_freq_to_chn
1189(
1190 v_U16_t freq
1191)
1192{
1193 int loop;
1194
1195 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1196 {
1197 if (rfChannels[loop].targetFreq == freq)
1198 {
1199 return rfChannels[loop].channelNum;
1200 }
1201 }
1202
1203 return (0);
1204}
1205
1206/*==========================================================================
1207 FUNCTION sapUpdateUnsafeChannelList
1208
1209 DESCRIPTION
1210 Function Undate unsafe channel list table
1211
1212 DEPENDENCIES
1213 NA.
1214
1215 PARAMETERS
1216
1217 IN
1218 pSapCtx : SAP context pointer, include unsafe channel list
1219
1220 RETURN VALUE
1221 NONE
1222============================================================================*/
1223void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1224 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1225{
1226 v_U16_t i, j;
1227
1228 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1229 sizeof(pHddCtx->unsafeChannelList));
1230 if (0 == unsafeChannelCount)
1231 {
1232 pHddCtx->unsafeChannelCount = 0;
1233 }
1234 else
1235 {
1236 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1237 unsafeChannelList,
1238 unsafeChannelCount * sizeof(tANI_U16));
1239 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1240 }
1241
1242 /* Flush, default set all channel safe */
1243 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1244 {
1245 safeChannels[i].isSafe = VOS_TRUE;
1246 }
1247
1248 /* Try to find unsafe channel */
1249 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1250 {
1251 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1252 {
1253 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1254 {
1255 /* Found unsafe channel, update it */
1256 safeChannels[j].isSafe = VOS_FALSE;
1257 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1258 "%s : CH %d is not safe",
1259 __func__, pHddCtx->unsafeChannelList[i]);
1260 break;
1261 }
1262 }
1263 }
1264
1265 return;
1266}
1267
1268/**---------------------------------------------------------------------------
1269
1270 \brief hdd_hostapd_ch_avoid_cb() -
1271
1272 Avoid channel notification from FW handler.
1273 FW will send un-safe channle list to avoid overwrapping.
1274 hostapd should not use notified channel
1275
1276 \param - pAdapter HDD adapter pointer
1277 indParam channel avoid notification parameter
1278
1279 \return - None
1280
1281 --------------------------------------------------------------------------*/
1282void hdd_hostapd_ch_avoid_cb
1283(
1284 void *pAdapter,
1285 void *indParam
1286)
1287{
1288 hdd_adapter_t *pHostapdAdapter = NULL;
1289 hdd_context_t *hddCtxt;
1290 tSirChAvoidIndType *chAvoidInd;
1291 v_U8_t rangeLoop;
1292 v_U16_t channelLoop;
1293 v_U16_t dupCheck;
1294 v_U16_t startChannel;
1295 v_U16_t endChannel;
1296 v_U16_t unsafeChannelCount = 0;
1297 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1298 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001299 tHddAvoidFreqList hddAvoidFreqList;
1300 tANI_U32 i;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001301
1302 /* Basic sanity */
1303 if ((NULL == pAdapter) || (NULL == indParam))
1304 {
1305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1306 "%s : Invalid arguments", __func__);
1307 return;
1308 }
1309
1310 hddCtxt = (hdd_context_t *)pAdapter;
1311 chAvoidInd = (tSirChAvoidIndType *)indParam;
1312 pVosContext = hddCtxt->pvosContext;
1313
1314 /* Make unsafe channel list */
1315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1316 "%s : band count %d",
1317 __func__, chAvoidInd->avoidRangeCount);
1318 vos_mem_zero((void *)unsafeChannelList,
1319 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1320 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1321 {
1322 startChannel = hdd_hostapd_freq_to_chn(
1323 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1324 endChannel = hdd_hostapd_freq_to_chn(
1325 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1327 "%s : start %d : %d, end %d : %d",
1328 __func__,
1329 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1330 startChannel,
1331 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1332 endChannel);
1333 for (channelLoop = startChannel;
1334 channelLoop < (endChannel + 1);
1335 channelLoop++)
1336 {
1337 /* Channel duplicate check routine */
1338 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1339 {
1340 if (unsafeChannelList[dupCheck] == channelLoop)
1341 {
1342 /* This channel is duplicated */
1343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1344 "%s : found duplicated channel %d",
1345 __func__, channelLoop);
1346 break;
1347 }
1348 }
1349 if (dupCheck == unsafeChannelCount)
1350 {
1351 unsafeChannelList[unsafeChannelCount] = channelLoop;
1352 unsafeChannelCount++;
1353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1354 "%s : unsafe channel %d, count %d",
1355 __func__,
1356 channelLoop, unsafeChannelCount);
1357 }
1358 else
1359 {
1360 /* DUP, do nothing */
1361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1362 "%s : duplicated channel %d",
1363 __func__, channelLoop);
1364 }
1365 }
1366 }
1367 /* Update unsafe channel cache
1368 * WCN Platform Driver cache */
1369 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1370 unsafeChannelCount);
1371
1372 /* Store into local cache
1373 * Start with STA and later start SAP
1374 * in this scenario, local cache will be used */
1375 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1376 unsafeChannelList,
1377 unsafeChannelCount);
1378
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001379 /* generate vendor specific event */
1380 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1381 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1382 {
1383 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1384 chAvoidInd->avoidFreqRange[i].startFreq;
1385 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1386 chAvoidInd->avoidFreqRange[i].endFreq;
1387 }
1388 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1389
1390 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1391
Leo Chang0b0e45a2013-12-15 15:18:55 -08001392 /* Get SAP context first
1393 * SAP and P2PGO would not concurrent */
1394 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
1395 if ((pHostapdAdapter) && (unsafeChannelCount))
1396 {
1397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1398 "%s : Current operation channel %d",
1399 __func__,
1400 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1401 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1402 {
1403 if (((unsafeChannelList[channelLoop] ==
1404 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1405 (AUTO_CHANNEL_SELECT ==
1406 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1407 {
1408 /* current operating channel is un-safe channel
1409 * restart driver */
1410 hdd_hostapd_stop(pHostapdAdapter->dev);
1411 break;
1412 }
1413 }
1414 }
1415
1416 return;
1417}
1418
1419#endif /* FEATURE_WLAN_CH_AVOID */
1420
Jeff Johnson295189b2012-06-20 16:38:30 -07001421int
1422static iw_softap_setparam(struct net_device *dev,
1423 struct iw_request_info *info,
1424 union iwreq_data *wrqu, char *extra)
1425{
1426 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001427 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 int *value = (int *)extra;
1429 int sub_cmd = value[0];
1430 int set_value = value[1];
1431 eHalStatus status;
1432 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001433 v_CONTEXT_t pVosContext;
1434
1435 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1436 {
1437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1438 "%s: either hostapd Adapter is null or HDD ctx is null",
1439 __func__);
1440 return -1;
1441 }
1442
1443 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1444 if (!hHal)
1445 {
1446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1447 "%s: Hal ctx is null", __func__);
1448 return -1;
1449 }
1450
1451 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1452 if (!pVosContext)
1453 {
1454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1455 "%s: Vos ctx is null", __func__);
1456 return -1;
1457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001458
1459 switch(sub_cmd)
1460 {
1461
1462 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001463 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001464 {
1465 ret = -EIO;
1466 }
1467 break;
1468
1469 case QCSAP_PARAM_ACL_MODE:
1470 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1471 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1472 {
1473 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1474 ret = -EINVAL;
1475 }
1476 else
1477 {
1478 WLANSAP_SetMode(pVosContext, set_value);
1479 }
1480 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301481
1482 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1483 if ((0 != set_value) && (1 != set_value))
1484 {
1485 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1486 ret = -EINVAL;
1487 }
1488 else
1489 {
1490 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1491 }
1492 break;
1493
Jeff Johnson295189b2012-06-20 16:38:30 -07001494 case QCSAP_PARAM_MAX_ASSOC:
1495 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1496 {
1497 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1498 ret = -EINVAL;
1499 }
1500 else
1501 {
1502 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1503 {
1504 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1505 "Setting it to max allowed and continuing"),
1506 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1507 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1508 }
1509 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1510 set_value, NULL, eANI_BOOLEAN_FALSE);
1511 if ( status != eHAL_STATUS_SUCCESS )
1512 {
1513 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1514 status);
1515 ret = -EIO;
1516 }
1517 }
1518 break;
1519
1520 case QCSAP_PARAM_HIDE_SSID:
1521 {
1522 eHalStatus status = eHAL_STATUS_SUCCESS;
1523 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1524 if(eHAL_STATUS_SUCCESS != status)
1525 {
1526 hddLog(VOS_TRACE_LEVEL_ERROR,
1527 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001528 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 return status;
1530 }
1531 break;
1532 }
1533
Leo Chang614d2072013-08-22 14:59:44 -07001534 case QCSAP_PARAM_SET_MC_RATE:
1535 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001536 tSirRateUpdateInd *rateUpdate;
1537
1538 rateUpdate = (tSirRateUpdateInd *)
1539 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1540 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001541 {
1542 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001543 "%s: SET_MC_RATE indication alloc fail", __func__);
1544 ret = -1;
1545 break;
1546 }
1547 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1548
1549 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1550 /* Ignore unicast */
1551 rateUpdate->ucastDataRate = -1;
1552 rateUpdate->mcastDataRate24GHz = set_value;
1553 rateUpdate->mcastDataRate5GHz = set_value;
1554 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1555 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1556 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1557 if (eHAL_STATUS_SUCCESS != status)
1558 {
1559 hddLog(VOS_TRACE_LEVEL_ERROR,
1560 "%s: SET_MC_RATE failed", __func__);
1561 vos_mem_free(rateUpdate);
1562 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001563 }
1564 break;
1565 }
1566
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 default:
1568 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1569 sub_cmd, set_value);
1570 ret = -EINVAL;
1571 break;
1572 }
1573
1574 return ret;
1575}
1576
1577
1578int
1579static iw_softap_getparam(struct net_device *dev,
1580 struct iw_request_info *info,
1581 union iwreq_data *wrqu, char *extra)
1582{
1583 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1584 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1585 int *value = (int *)extra;
1586 int sub_cmd = value[0];
1587 eHalStatus status;
1588 int ret = 0; /* success */
1589 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1590
1591 switch (sub_cmd)
1592 {
1593 case QCSAP_PARAM_MAX_ASSOC:
1594 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1595 if (eHAL_STATUS_SUCCESS != status)
1596 {
c_hpothuffdb5272013-10-02 16:42:35 +05301597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 ret = -EIO;
1600 }
1601 break;
1602
1603 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001604 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 {
c_hpothuffdb5272013-10-02 16:42:35 +05301606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1607 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 ret = -EIO;
1609 }
1610 *value = 0;
1611 break;
1612
1613 case QCSAP_PARAM_MODULE_DOWN_IND:
1614 {
1615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001616 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1618#ifdef WLAN_BTAMP_FEATURE
1619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001620 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001621 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1622#endif
1623 *value = 0;
1624 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001625 }
1626
1627 case QCSAP_PARAM_GET_WLAN_DBG:
1628 {
1629 vos_trace_display();
1630 *value = 0;
1631 break;
1632 }
1633
1634 case QCSAP_PARAM_AUTO_CHANNEL:
1635 {
1636 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1637 break;
1638 }
1639
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 default:
1641 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1642 ret = -EINVAL;
1643 break;
1644
1645 }
1646
1647 return ret;
1648}
1649
1650/* Usage:
1651 BLACK_LIST = 0
1652 WHITE_LIST = 1
1653 ADD MAC = 0
1654 REMOVE MAC = 1
1655
1656 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1657 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1658 while using this ioctl
1659
1660 Syntax:
1661 iwpriv softap.0 modify_acl
1662 <6 octet mac addr> <list type> <cmd type>
1663
1664 Examples:
1665 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1666 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1667 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1668 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1669*/
1670int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1671 union iwreq_data *wrqu, char *extra)
1672{
1673 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1674 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1675 v_BYTE_t *value = (v_BYTE_t*)extra;
1676 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1677 int listType, cmd, i;
1678 int ret = 0; /* success */
1679
1680 ENTER();
1681 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1682 {
1683 pPeerStaMac[i] = *(value+i);
1684 }
1685 listType = (int)(*(value+i));
1686 i++;
1687 cmd = (int)(*(value+i));
1688
Arif Hussain24bafea2013-11-15 15:10:03 -08001689 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1690 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001691
1692 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1693 != VOS_STATUS_SUCCESS)
1694 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001695 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001696 ret = -EIO;
1697 }
1698 EXIT();
1699 return ret;
1700}
1701
1702int
1703static iw_softap_getchannel(struct net_device *dev,
1704 struct iw_request_info *info,
1705 union iwreq_data *wrqu, char *extra)
1706{
1707 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1708
Jeff Johnson43971f52012-07-17 12:26:56 -07001709 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001710
Jeff Johnson43971f52012-07-17 12:26:56 -07001711 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001712 return 0;
1713}
1714
Jeff Johnsone7245742012-09-05 17:12:55 -07001715int
schang86c22c42013-03-13 18:41:24 -07001716static iw_softap_set_max_tx_power(struct net_device *dev,
Jeff Johnsone7245742012-09-05 17:12:55 -07001717 struct iw_request_info *info,
1718 union iwreq_data *wrqu, char *extra)
1719{
1720 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1721 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001722 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001723 int set_value;
1724 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1725 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1726
schang86c22c42013-03-13 18:41:24 -07001727 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001728 return -ENOMEM;
1729
Leo Changd37675a2013-08-01 13:19:45 -07001730 /* Assign correct slef MAC address */
1731 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1732 VOS_MAC_ADDR_SIZE);
1733 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1734 VOS_MAC_ADDR_SIZE);
1735
schang86c22c42013-03-13 18:41:24 -07001736 set_value = value[0];
1737 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001740 __func__);
schang86c22c42013-03-13 18:41:24 -07001741 return -EIO;
1742 }
1743
1744 return 0;
1745}
1746
1747int
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301748static iw_display_data_path_snapshot(struct net_device *dev,
1749 struct iw_request_info *info,
1750 union iwreq_data *wrqu, char *extra)
1751{
1752
1753 /* Function intitiating dumping states of
1754 * HDD(WMM Tx Queues)
1755 * TL State (with Per Client infor)
1756 * DXE Snapshot (Called at the end of TL Snapshot)
1757 */
1758 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1759 hddLog(LOGE, "%s: called for SAP",__func__);
1760 hdd_wmm_tx_snapshot(pHostapdAdapter);
1761 WLANTL_TLDebugMessage(VOS_TRUE);
1762 return 0;
1763}
1764
1765int
schang86c22c42013-03-13 18:41:24 -07001766static iw_softap_set_tx_power(struct net_device *dev,
1767 struct iw_request_info *info,
1768 union iwreq_data *wrqu, char *extra)
1769{
1770 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1771 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1773 int *value = (int *)extra;
1774 int set_value;
1775 ptSapContext pSapCtx = NULL;
1776
1777 if (NULL == value)
1778 return -ENOMEM;
1779
1780 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1781 if (NULL == pSapCtx)
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1784 "%s: Invalid SAP pointer from pvosGCtx", __func__);
1785 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07001786 }
1787
1788 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07001789 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07001790 {
schang86c22c42013-03-13 18:41:24 -07001791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07001792 __func__);
1793 return -EIO;
1794 }
1795
1796 return 0;
1797}
1798
Kiet Lambcf38522013-10-26 18:28:27 +05301799/**---------------------------------------------------------------------------
1800
1801 \brief iw_softap_set_trafficmonitor() -
1802 This function dynamically enable/disable traffic monitor functonality
1803 the command iwpriv wlanX setTrafficMon <value>.
1804
1805 \param - dev - Pointer to the net device.
1806 - addr - Pointer to the sockaddr.
1807 \return - 0 for success, non zero for failure
1808
1809 --------------------------------------------------------------------------*/
1810
1811static int iw_softap_set_trafficmonitor(struct net_device *dev,
1812 struct iw_request_info *info,
1813 union iwreq_data *wrqu, char *extra)
1814{
1815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1816 int *isSetTrafficMon = (int *)wrqu->data.pointer;
1817 hdd_context_t *pHddCtx;
1818 int status;
1819
1820 if (NULL == pAdapter)
1821 {
1822 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1823 "%s: HDD adapter is Null", __func__);
1824 return -ENODEV;
1825 }
1826
1827 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1828
1829 status = wlan_hdd_validate_context(pHddCtx);
1830
1831 if (0 != status)
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "%s: HDD context is not valid", __func__);
1835 return status;
1836 }
1837
1838 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
1839
1840 if (NULL == isSetTrafficMon)
1841 {
1842 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1843 "%s: Invalid SAP pointer from extra", __func__);
1844 return -ENOMEM;
1845 }
1846
1847 if (TRUE == *isSetTrafficMon)
1848 {
1849 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
1850 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
1851 {
1852 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1853 "%s: failed to Start Traffic Monitor timer ", __func__ );
1854 return -EIO;
1855 }
1856 }
1857 else if (FALSE == *isSetTrafficMon)
1858 {
1859 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
1860 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
1861 {
1862 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1863 "%s: failed to Stop Traffic Monitor timer ", __func__ );
1864 return -EIO;
1865 }
1866
1867 }
1868 return 0;
1869}
1870
Jeff Johnson295189b2012-06-20 16:38:30 -07001871#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1872
1873int
1874static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1875 struct iw_request_info *info,
1876 union iwreq_data *wrqu, char *extra)
1877{
1878 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson295189b2012-06-20 16:38:30 -07001879 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07001880 char *buf;
1881 int cnt = 0;
1882 int left;
1883 int ret = 0;
1884 /* maclist_index must be u32 to match userspace */
1885 u32 maclist_index;
Jeff Johnson295189b2012-06-20 16:38:30 -07001886
Jeff Johnson224f3702014-03-26 11:09:47 -07001887 /*
1888 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
1889 * number, and even numbered iocts are supposed to have "set"
1890 * semantics. Hence the wireless extensions support in the kernel
1891 * won't correctly copy the result to userspace, so the ioctl
1892 * handler itself must copy the data. Output format is 32-bit
1893 * record length, followed by 0 or more 6-byte STA MAC addresses.
1894 *
1895 * Further note that due to the incorrect semantics, the "iwpriv"
1896 * userspace application is unable to correctly invoke this API,
1897 * hence it is not registered in the hostapd_private_args. This
1898 * API can only be invoked by directly invoking the ioctl() system
1899 * call.
1900 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001901
Jeff Johnson224f3702014-03-26 11:09:47 -07001902 /* make sure userspace allocated a reasonable buffer size */
1903 if (wrqu->data.length < sizeof(maclist_index)) {
1904 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
1905 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07001906 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001907
Jeff Johnson224f3702014-03-26 11:09:47 -07001908 /* allocate local buffer to build the response */
1909 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
1910 if (!buf) {
1911 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
1912 return -ENOMEM;
1913 }
1914
1915 /* start indexing beyond where the record count will be written */
1916 maclist_index = sizeof(maclist_index);
1917 left = wrqu->data.length - maclist_index;
1918
1919 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1920 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
1921 if ((pStaInfo[cnt].isUsed) &&
1922 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
1923 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
1924 VOS_MAC_ADDR_SIZE);
1925 maclist_index += VOS_MAC_ADDR_SIZE;
1926 left -= VOS_MAC_ADDR_SIZE;
1927 }
1928 cnt++;
1929 }
1930 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1931
1932 *((u32 *)buf) = maclist_index;
1933 wrqu->data.length = maclist_index;
1934 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
1935 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
1936 ret = -EFAULT;
1937 }
1938 kfree(buf);
1939 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001940}
1941
1942/* Usage:
1943 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1944 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1945 while using this ioctl
1946
1947 Syntax:
1948 iwpriv softap.0 disassoc_sta <6 octet mac address>
1949
1950 e.g.
1951 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1952 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1953*/
1954
1955int
1956static iw_softap_disassoc_sta(struct net_device *dev,
1957 struct iw_request_info *info,
1958 union iwreq_data *wrqu, char *extra)
1959{
1960 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1961 v_U8_t *peerMacAddr;
1962
1963 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301964 /* iwpriv tool or framework calls this ioctl with
1965 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301967 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07001968
Arif Hussain24bafea2013-11-15 15:10:03 -08001969 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
1970 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1972 EXIT();
1973 return 0;
1974}
1975
1976int
1977static iw_softap_ap_stats(struct net_device *dev,
1978 struct iw_request_info *info,
1979 union iwreq_data *wrqu, char *extra)
1980{
1981 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1982 WLANTL_TRANSFER_STA_TYPE statBuffer;
1983 char *pstatbuf;
Girish Gowlif3769802014-06-16 21:17:16 +05301984 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07001985
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001986 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07001987 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
1988 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07001989
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05301990 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07001991 if(NULL == pstatbuf) {
1992 hddLog(LOG1, "unable to allocate memory");
1993 return -ENOMEM;
1994 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05301995
1996 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07001997 "RUF=%d RMF=%d RBF=%d "
1998 "RUB=%d RMB=%d RBB=%d "
1999 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302000 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002001 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2002 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2003 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2004 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2005 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2006 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002007
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302008 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002009 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2010 kfree(pstatbuf);
2011 return -EFAULT;
2012 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302013
2014 strlcpy(extra, pstatbuf, len);
2015 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002016 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002017 return 0;
2018}
2019
Jeff Johnson295189b2012-06-20 16:38:30 -07002020static
2021int iw_softap_setmlme(struct net_device *dev,
2022 struct iw_request_info *info,
2023 union iwreq_data *wrqu, char *extra)
2024{
2025 struct sQcSapreq_mlme *pmlme;
2026 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
2027 v_MACADDR_t destAddress;
2028 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
2029 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
2030 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
2031 switch(pmlme->im_op)
2032 {
2033 case QCSAP_MLME_AUTHORIZE:
2034 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
2035 break;
2036 case QCSAP_MLME_ASSOC:
2037 //TODO:inform to TL after associating (not needed as we do in sapCallback)
2038 break;
2039 case QCSAP_MLME_UNAUTHORIZE:
2040 //TODO: send the disassoc to station
2041 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
2042 break;
2043 case QCSAP_MLME_DISASSOC:
2044 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
2045 break;
2046 case QCSAP_MLME_DEAUTH:
2047 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
2048 break;
2049 case QCSAP_MLME_MICFAILURE:
2050 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
2051 break;
2052 default:
2053 break;
2054 }
2055 return 0;
2056}
2057
2058static int iw_softap_set_channel_range(struct net_device *dev,
2059 struct iw_request_info *info,
2060 union iwreq_data *wrqu, char *extra)
2061{
2062 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2063 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002064 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002065
2066 int *value = (int *)extra;
2067 int startChannel = value[0];
2068 int endChannel = value[1];
2069 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002070 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 int ret = 0; /* success */
2072
2073 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2074 if(status != VOS_STATUS_SUCCESS)
2075 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002076 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 startChannel,endChannel, band);
2078 ret = -EINVAL;
2079 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002080
2081 pHddCtx->is_dynamic_channel_range_set = 1;
2082
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 return ret;
2084}
2085
2086int iw_softap_get_channel_list(struct net_device *dev,
2087 struct iw_request_info *info,
2088 union iwreq_data *wrqu, char *extra)
2089{
2090 v_U32_t num_channels = 0;
2091 v_U8_t i = 0;
2092 v_U8_t bandStartChannel = RF_CHAN_1;
2093 v_U8_t bandEndChannel = RF_CHAN_165;
2094 v_U32_t temp_num_channels = 0;
2095 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2096 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2097 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002099 eCsrBand curBand = eCSR_BAND_ALL;
2100
2101 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2102 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002103 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002104 return -EIO;
2105 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 wrqu->data.length = sizeof(tChannelListInfo);
2107 ENTER();
2108
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002109 if (eCSR_BAND_24 == curBand)
2110 {
2111 bandStartChannel = RF_CHAN_1;
2112 bandEndChannel = RF_CHAN_14;
2113 }
2114 else if (eCSR_BAND_5G == curBand)
2115 {
2116 bandStartChannel = RF_CHAN_36;
2117 bandEndChannel = RF_CHAN_165;
2118 }
2119
Arif Hussain6d2a3322013-11-17 19:50:10 -08002120 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302121 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002122 bandStartChannel, bandEndChannel );
2123
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2125 {
2126 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2127 {
2128 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2129 num_channels++;
2130 }
2131 }
2132
2133 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2134
2135 temp_num_channels = num_channels;
2136
2137 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2138 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302139 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002140 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002141 }
2142
2143 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
2144 {
2145 for(i = 0; i < temp_num_channels; i++)
2146 {
2147
2148 if((channel_list->channels[i] > 35) &&
2149 (channel_list->channels[i] < 49))
2150 {
2151 vos_mem_move(&channel_list->channels[i],
2152 &channel_list->channels[i+1],
2153 temp_num_channels - (i-1));
2154 num_channels--;
2155 temp_num_channels--;
2156 i--;
2157 }
2158 }
2159 }
2160
Arif Hussain6d2a3322013-11-17 19:50:10 -08002161 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002162
2163 if (num_channels > IW_MAX_FREQUENCIES)
2164 {
2165 num_channels = IW_MAX_FREQUENCIES;
2166 }
2167
2168 channel_list->num_channels = num_channels;
2169 EXIT();
2170
2171 return 0;
2172}
2173
2174static
2175int iw_get_genie(struct net_device *dev,
2176 struct iw_request_info *info,
2177 union iwreq_data *wrqu, char *extra)
2178{
2179 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2180 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2181 eHalStatus status;
2182 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2183 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2184 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002185 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002186 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2187 status = WLANSap_getstationIE_information(pVosContext,
2188 &length,
2189 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002190 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2191 if (wrqu->data.length < length ||
2192 copy_to_user(wrqu->data.pointer,
2193 (v_VOID_t*)genIeBytes, length))
2194 {
2195 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2196 return -EFAULT;
2197 }
2198 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002199
Arif Hussain6d2a3322013-11-17 19:50:10 -08002200 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002201
2202
2203 EXIT();
2204 return 0;
2205}
2206static
2207int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2208 struct iw_request_info *info,
2209 union iwreq_data *wrqu, char *extra)
2210{
2211 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002212 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002213 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2214 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002215
Arif Hussain6d2a3322013-11-17 19:50:10 -08002216 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002217 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2218
2219 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2220 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2221 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2222 WPSPBCProbeReqIEs.probeReqIELen);
2223 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2224 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2225 sizeof(v_MACADDR_t));
2226 if (copy_to_user(wrqu->data.pointer,
2227 (void *)&WPSPBCProbeReqIEs,
2228 sizeof(WPSPBCProbeReqIEs)))
2229 {
2230 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2231 return -EFAULT;
2232 }
2233 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002234 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002235 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 up(&pHddApCtx->semWpsPBCOverlapInd);
2237 EXIT();
2238 return 0;
2239}
2240
2241/**---------------------------------------------------------------------------
2242
2243 \brief iw_set_auth_hostap() -
2244 This function sets the auth type received from the wpa_supplicant.
2245
2246 \param - dev - Pointer to the net device.
2247 - info - Pointer to the iw_request_info.
2248 - wrqu - Pointer to the iwreq_data.
2249 - extra - Pointer to the data.
2250 \return - 0 for success, non zero for failure
2251
2252 --------------------------------------------------------------------------*/
2253int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
2254 union iwreq_data *wrqu,char *extra)
2255{
2256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2257 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2258
2259 ENTER();
2260 switch(wrqu->param.flags & IW_AUTH_INDEX)
2261 {
2262 case IW_AUTH_TKIP_COUNTERMEASURES:
2263 {
2264 if(wrqu->param.value) {
2265 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2266 "Counter Measure started %d", wrqu->param.value);
2267 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2268 }
2269 else {
2270 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2271 "Counter Measure stopped=%d", wrqu->param.value);
2272 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2273 }
2274
2275 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2276 wrqu->param.value);
2277 }
2278 break;
2279
2280 default:
2281
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002282 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002283 wrqu->param.flags & IW_AUTH_INDEX);
2284 break;
2285 }
2286
2287 EXIT();
2288 return 0;
2289}
2290
2291static int iw_set_ap_encodeext(struct net_device *dev,
2292 struct iw_request_info *info,
2293 union iwreq_data *wrqu, char *extra)
2294{
2295 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2296 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2297 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002298 int retval = 0;
2299 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2301 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2302 int key_index;
2303 struct iw_point *encoding = &wrqu->encoding;
2304 tCsrRoamSetKey setKey;
2305// tCsrRoamRemoveKey RemoveKey;
2306 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002307
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 ENTER();
2309
2310 key_index = encoding->flags & IW_ENCODE_INDEX;
2311
2312 if(key_index > 0) {
2313
2314 /*Convert from 1-based to 0-based keying*/
2315 key_index--;
2316 }
2317 if(!ext->key_len) {
2318#if 0
2319 /*Set the encrytion type to NONE*/
2320#if 0
2321 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2322#endif
2323
2324 RemoveKey.keyId = key_index;
2325 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2326 /*Key direction for group is RX only*/
2327 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2328 }
2329 else {
2330 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2331 }
2332 switch(ext->alg)
2333 {
2334 case IW_ENCODE_ALG_NONE:
2335 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2336 break;
2337 case IW_ENCODE_ALG_WEP:
2338 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2339 break;
2340 case IW_ENCODE_ALG_TKIP:
2341 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002342 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 case IW_ENCODE_ALG_CCMP:
2344 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2345 break;
2346 default:
2347 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2348 break;
2349 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002350 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 -07002351 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002353 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002355 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2356 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002357 {
2358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002359 __LINE__, vstatus );
2360 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002362#endif
2363 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002364
Jeff Johnson43971f52012-07-17 12:26:56 -07002365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002366
2367 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2368
2369 setKey.keyId = key_index;
2370 setKey.keyLength = ext->key_len;
2371
2372 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2373 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2374 }
2375
2376 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2377 /*Key direction for group is RX only*/
2378 setKey.keyDirection = eSIR_RX_ONLY;
2379 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2380 }
2381 else {
2382
2383 setKey.keyDirection = eSIR_TX_RX;
2384 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2385 }
2386 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2387 {
2388 setKey.keyDirection = eSIR_TX_DEFAULT;
2389 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2390 }
2391
2392 /*For supplicant pae role is zero*/
2393 setKey.paeRole = 0;
2394
2395 switch(ext->alg)
2396 {
2397 case IW_ENCODE_ALG_NONE:
2398 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2399 break;
2400
2401 case IW_ENCODE_ALG_WEP:
2402 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2403 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002404 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002405 break;
2406
2407 case IW_ENCODE_ALG_TKIP:
2408 {
2409 v_U8_t *pKey = &setKey.Key[0];
2410
2411 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2412
2413 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2414
2415 /*Supplicant sends the 32bytes key in this order
2416
2417 |--------------|----------|----------|
2418 | Tk1 |TX-MIC | RX Mic |
2419 |--------------|----------|----------|
2420 <---16bytes---><--8bytes--><--8bytes-->
2421
2422 */
2423 /*Sme expects the 32 bytes key to be in the below order
2424
2425 |--------------|----------|----------|
2426 | Tk1 |RX-MIC | TX Mic |
2427 |--------------|----------|----------|
2428 <---16bytes---><--8bytes--><--8bytes-->
2429 */
2430 /* Copy the Temporal Key 1 (TK1) */
2431 vos_mem_copy(pKey,ext->key,16);
2432
2433 /*Copy the rx mic first*/
2434 vos_mem_copy(&pKey[16],&ext->key[24],8);
2435
2436 /*Copy the tx mic */
2437 vos_mem_copy(&pKey[24],&ext->key[16],8);
2438
2439 }
2440 break;
2441
2442 case IW_ENCODE_ALG_CCMP:
2443 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2444 break;
2445
2446 default:
2447 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2448 break;
2449 }
2450
2451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302452 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002453 setKey.keyId);
2454 for(i=0; i< ext->key_len; i++)
2455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2456 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002457
2458 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2459 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002460 {
2461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002462 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2463 retval = -EINVAL;
2464 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002465
Jeff Johnson43971f52012-07-17 12:26:56 -07002466 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002467}
Jeff Johnson43971f52012-07-17 12:26:56 -07002468
2469
Jeff Johnson295189b2012-06-20 16:38:30 -07002470static int iw_set_ap_mlme(struct net_device *dev,
2471 struct iw_request_info *info,
2472 union iwreq_data *wrqu,
2473 char *extra)
2474{
2475#if 0
2476 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2477 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2478
2479 ENTER();
2480
2481 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2482 switch (mlme->cmd) {
2483 case IW_MLME_DISASSOC:
2484 case IW_MLME_DEAUTH:
2485 hddLog(LOG1, "Station disassociate");
2486 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2487 {
2488 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2489
2490 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2491 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2492
2493 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2494
2495 //clear all the reason codes
2496 if (status != 0)
2497 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002498 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002499 }
2500
2501 netif_stop_queue(dev);
2502 netif_carrier_off(dev);
2503 }
2504 else
2505 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002506 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 -07002507 }
2508 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002509 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002510 return -EINVAL;
2511 }//end of switch
2512 EXIT();
2513#endif
2514 return 0;
2515// return status;
2516}
2517
2518static int iw_get_ap_rts_threshold(struct net_device *dev,
2519 struct iw_request_info *info,
2520 union iwreq_data *wrqu, char *extra)
2521{
2522 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2523 v_U32_t status = 0;
2524
2525 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2526
2527 return status;
2528}
2529
2530static int iw_get_ap_frag_threshold(struct net_device *dev,
2531 struct iw_request_info *info,
2532 union iwreq_data *wrqu, char *extra)
2533{
2534 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2535 v_U32_t status = 0;
2536
2537 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2538
2539 return status;
2540}
2541
2542static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2543 struct iw_freq *fwrq, char *extra)
2544{
Jeff Johnsone7245742012-09-05 17:12:55 -07002545 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2547 tHalHandle hHal;
2548 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002549 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002550
2551 ENTER();
2552
2553 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2555 "%s:LOGP in Progress. Ignore!!!",__func__);
2556 return status;
2557 }
2558
2559 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2560 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2561
2562 if(pHostapdState->bssState == BSS_STOP )
2563 {
2564 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2565 != eHAL_STATUS_SUCCESS)
2566 {
c_hpothuffdb5272013-10-02 16:42:35 +05302567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 return -EIO;
2570 }
2571 else
2572 {
2573 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002574 if( TRUE == status)
2575 {
2576 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2577 * iwlist & iwconfig command shows frequency into proper
2578 * format (2.412 GHz instead of 246.2 MHz)*/
2579 fwrq->m = freq;
2580 fwrq->e = MHZ;
2581 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002582 }
2583 }
2584 else
2585 {
2586 channel = pHddApCtx->operatingChannel;
2587 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002588 if( TRUE == status)
2589 {
2590 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2591 * iwlist & iwconfig command shows frequency into proper
2592 * format (2.412 GHz instead of 246.2 MHz)*/
2593 fwrq->m = freq;
2594 fwrq->e = MHZ;
2595 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002596 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002597 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002598}
2599
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302600static int iw_get_mode(struct net_device *dev,
2601 struct iw_request_info *info,
2602 union iwreq_data *wrqu,
2603 char *extra)
2604{
2605 int status = 0;
2606
2607 wrqu->mode = IW_MODE_MASTER;
2608
2609 return status;
2610}
2611
Jeff Johnson295189b2012-06-20 16:38:30 -07002612static int iw_softap_setwpsie(struct net_device *dev,
2613 struct iw_request_info *info,
2614 union iwreq_data *wrqu,
2615 char *extra)
2616{
2617 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2618 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2619 hdd_hostapd_state_t *pHostapdState;
2620 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002621 u_int8_t *wps_genie;
2622 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07002623 u_int8_t *pos;
2624 tpSap_WPSIE pSap_WPSIe;
2625 u_int8_t WPSIeType;
2626 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05302627 struct iw_point s_priv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002628 ENTER();
2629
Girish Gowli07c05ec2014-06-17 20:47:03 +05302630 /* helper function to get iwreq_data with compat handling. */
2631 if (hdd_priv_get_data(&s_priv_data, wrqu))
2632 {
2633 return -EINVAL;
2634 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002635
Girish Gowli07c05ec2014-06-17 20:47:03 +05302636 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
2637 {
2638 return -EINVAL;
2639 }
2640
2641 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
2642 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07002643
Girish Gowli86c471e2014-06-17 19:28:05 +05302644 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07002645 {
Girish Gowli86c471e2014-06-17 19:28:05 +05302646 hddLog(LOG1, "%s: failed to alloc memory "
2647 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07002648 return -EFAULT;
2649 }
2650
Girish Gowli86c471e2014-06-17 19:28:05 +05302651 fwps_genie = wps_genie;
2652
Jeff Johnson295189b2012-06-20 16:38:30 -07002653 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2654 if (NULL == pSap_WPSIe)
2655 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002656 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07002657 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 return -ENOMEM;
2659 }
2660 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2661
Arif Hussain6d2a3322013-11-17 19:50:10 -08002662 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 -07002663 WPSIeType = wps_genie[0];
2664 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2665 {
2666 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2667 wps_genie = wps_genie + 1;
2668 switch ( wps_genie[0] )
2669 {
2670 case DOT11F_EID_WPA:
2671 if (wps_genie[1] < 2 + 4)
2672 {
2673 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002674 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002675 return -EINVAL;
2676 }
2677 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2678 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002679 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 pos = &wps_genie[6];
2681 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2682 {
2683 switch((u_int16_t)(*pos<<8) | *(pos+1))
2684 {
2685 case HDD_WPS_ELEM_VERSION:
2686 pos += 4;
2687 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002688 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002689 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2690 pos += 1;
2691 break;
2692
2693 case HDD_WPS_ELEM_WPS_STATE:
2694 pos +=4;
2695 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002696 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002697 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2698 pos += 1;
2699 break;
2700 case HDD_WPS_ELEM_APSETUPLOCK:
2701 pos += 4;
2702 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002703 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002704 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2705 pos += 1;
2706 break;
2707 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2708 pos += 4;
2709 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002710 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002711 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2712 pos += 1;
2713 break;
2714 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2715 pos += 4;
2716 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002717 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002718 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2719 pos += 2;
2720 break;
2721 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2722 pos += 4;
2723 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002724 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2726 pos += 2;
2727 break;
2728
2729 case HDD_WPS_ELEM_UUID_E:
2730 pos += 2;
2731 length = *pos<<8 | *(pos+1);
2732 pos += 2;
2733 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2734 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2735 pos += length;
2736 break;
2737 case HDD_WPS_ELEM_RF_BANDS:
2738 pos += 4;
2739 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002740 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002741 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2742 pos += 1;
2743 break;
2744
2745 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002746 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07002747 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002748 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 return -EINVAL;
2750 }
2751 }
2752 }
2753 else {
2754 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002755 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 }
2757 break;
2758
2759 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002760 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002761 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002762 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002763 return 0;
2764 }
2765 }
2766 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2767 {
2768 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2769 wps_genie = wps_genie + 1;
2770 switch ( wps_genie[0] )
2771 {
2772 case DOT11F_EID_WPA:
2773 if (wps_genie[1] < 2 + 4)
2774 {
2775 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002776 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002777 return -EINVAL;
2778 }
2779 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2780 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002781 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002782 pos = &wps_genie[6];
2783 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2784 {
2785 switch((u_int16_t)(*pos<<8) | *(pos+1))
2786 {
2787 case HDD_WPS_ELEM_VERSION:
2788 pos += 4;
2789 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002790 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002791 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2792 pos += 1;
2793 break;
2794
2795 case HDD_WPS_ELEM_WPS_STATE:
2796 pos +=4;
2797 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002798 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002799 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2800 pos += 1;
2801 break;
2802 case HDD_WPS_ELEM_APSETUPLOCK:
2803 pos += 4;
2804 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002805 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002806 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2807 pos += 1;
2808 break;
2809 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2810 pos += 4;
2811 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002812 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002813 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2814 pos += 1;
2815 break;
2816 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2817 pos += 4;
2818 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002819 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002820 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2821 pos += 2;
2822 break;
2823 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2824 pos += 4;
2825 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002826 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002827 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2828 pos += 2;
2829 break;
2830 case HDD_WPS_ELEM_RSP_TYPE:
2831 pos += 4;
2832 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002833 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002834 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2835 pos += 1;
2836 break;
2837 case HDD_WPS_ELEM_UUID_E:
2838 pos += 2;
2839 length = *pos<<8 | *(pos+1);
2840 pos += 2;
2841 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2842 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2843 pos += length;
2844 break;
2845
2846 case HDD_WPS_ELEM_MANUFACTURER:
2847 pos += 2;
2848 length = *pos<<8 | *(pos+1);
2849 pos += 2;
2850 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2851 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2852 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2853 pos += length;
2854 break;
2855
2856 case HDD_WPS_ELEM_MODEL_NAME:
2857 pos += 2;
2858 length = *pos<<8 | *(pos+1);
2859 pos += 2;
2860 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2861 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2862 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2863 pos += length;
2864 break;
2865 case HDD_WPS_ELEM_MODEL_NUM:
2866 pos += 2;
2867 length = *pos<<8 | *(pos+1);
2868 pos += 2;
2869 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2870 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2871 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2872 pos += length;
2873 break;
2874 case HDD_WPS_ELEM_SERIAL_NUM:
2875 pos += 2;
2876 length = *pos<<8 | *(pos+1);
2877 pos += 2;
2878 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2879 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2880 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2881 pos += length;
2882 break;
2883 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2884 pos += 4;
2885 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002886 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 pos += 2;
2888
2889 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002890 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002891 pos += 4;
2892 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002893 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002894 pos += 2;
2895 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2896 break;
2897 case HDD_WPS_ELEM_DEVICE_NAME:
2898 pos += 2;
2899 length = *pos<<8 | *(pos+1);
2900 pos += 2;
2901 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2902 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2903 pos += length;
2904 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2905 break;
2906 case HDD_WPS_ELEM_CONFIG_METHODS:
2907 pos += 4;
2908 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002909 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002910 pos += 2;
2911 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2912 break;
2913
2914 case HDD_WPS_ELEM_RF_BANDS:
2915 pos += 4;
2916 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002917 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002918 pos += 1;
2919 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2920 break;
2921 } // switch
2922 }
2923 }
2924 else
2925 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002926 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002927 }
2928
2929 } // switch
2930 }
2931 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2932 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2933 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2934 {
2935 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2936 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2937 WLANSAP_Update_WpsIe ( pVosContext );
2938 }
2939
2940 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002941 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002942 EXIT();
2943 return halStatus;
2944}
2945
2946static int iw_softap_stopbss(struct net_device *dev,
2947 struct iw_request_info *info,
2948 union iwreq_data *wrqu,
2949 char *extra)
2950{
2951 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2952 VOS_STATUS status = VOS_STATUS_SUCCESS;
2953 ENTER();
2954 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2955 {
2956 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2957 {
2958 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2959
2960 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2961
2962 if (!VOS_IS_STATUS_SUCCESS(status))
2963 {
2964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002965 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002966 VOS_ASSERT(0);
2967 }
2968 }
2969 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2970 }
2971 EXIT();
2972 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2973}
2974
2975static int iw_softap_version(struct net_device *dev,
2976 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002977 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07002978 char *extra)
2979{
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002981
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002983 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002984 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002985 return 0;
2986}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002987
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002988VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002989{
2990 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002991 int len = 0;
2992 const char sta_info_header[] = "staId staAddress\n";
2993
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002994 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002995 pBuf += len;
2996 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002997
2998 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2999 {
3000 if(pAdapter->aStaInfo[i].isUsed)
3001 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003002 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003003 pAdapter->aStaInfo[i].ucSTAId,
3004 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
3005 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
3006 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
3007 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
3008 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
3009 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003010 pBuf += len;
3011 buf_len -= len;
3012 }
3013 if(WE_GET_STA_INFO_SIZE > buf_len)
3014 {
3015 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003016 }
3017 }
3018 return VOS_STATUS_SUCCESS;
3019}
3020
3021static int iw_softap_get_sta_info(struct net_device *dev,
3022 struct iw_request_info *info,
3023 union iwreq_data *wrqu,
3024 char *extra)
3025{
3026 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3027 VOS_STATUS status;
3028 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003029 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003030 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003032 return -EINVAL;
3033 }
3034 wrqu->data.length = strlen(extra);
3035 EXIT();
3036 return 0;
3037}
3038
Jeff Johnson295189b2012-06-20 16:38:30 -07003039static int iw_set_ap_genie(struct net_device *dev,
3040 struct iw_request_info *info,
3041 union iwreq_data *wrqu,
3042 char *extra)
3043{
3044
3045 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3046 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3047 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003048 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003049
3050 ENTER();
3051
3052 if(!wrqu->data.length)
3053 {
3054 EXIT();
3055 return 0;
3056 }
Arif Hussained667642013-10-27 23:01:14 -07003057
Jeff Johnson295189b2012-06-20 16:38:30 -07003058 switch (genie[0])
3059 {
3060 case DOT11F_EID_WPA:
3061 case DOT11F_EID_RSN:
3062 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3063 {
3064 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3065 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3066 }
3067 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003068 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003069 break;
3070
3071 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003072 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003073 halStatus = 0;
3074 }
3075
3076 EXIT();
3077 return halStatus;
3078}
3079
3080static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3081{
3082 eHalStatus hstatus;
3083 long lrc;
3084 struct statsContext context;
3085
3086 if (NULL == pAdapter)
3087 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303088 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 return VOS_STATUS_E_FAULT;
3090 }
3091
3092 init_completion(&context.completion);
3093 context.pAdapter = pAdapter;
3094 context.magic = STATS_CONTEXT_MAGIC;
3095 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3096 eCSR_HDD,
3097 SME_GLOBAL_CLASSA_STATS,
3098 hdd_GetClassA_statisticsCB,
3099 0, // not periodic
3100 FALSE, //non-cached results
3101 staid,
3102 &context);
3103 if (eHAL_STATUS_SUCCESS != hstatus)
3104 {
3105 hddLog(VOS_TRACE_LEVEL_ERROR,
3106 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003107 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 }
3109 else
3110 {
3111 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3112 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003113 if (lrc <= 0)
3114 {
3115 hddLog(VOS_TRACE_LEVEL_ERROR,
3116 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003117 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003118 }
3119 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003120
3121 /* either we never sent a request, we sent a request and received a
3122 response or we sent a request and timed out. if we never sent a
3123 request or if we sent a request and got a response, we want to
3124 clear the magic out of paranoia. if we timed out there is a
3125 race condition such that the callback function could be
3126 executing at the same time we are. of primary concern is if the
3127 callback function had already verified the "magic" but had not
3128 yet set the completion variable when a timeout occurred. we
3129 serialize these activities by invalidating the magic while
3130 holding a shared spinlock which will cause us to block if the
3131 callback is currently executing */
3132 spin_lock(&hdd_context_lock);
3133 context.magic = 0;
3134 spin_unlock(&hdd_context_lock);
3135
Jeff Johnson295189b2012-06-20 16:38:30 -07003136 return VOS_STATUS_SUCCESS;
3137}
3138
3139int iw_get_softap_linkspeed(struct net_device *dev,
3140 struct iw_request_info *info,
3141 union iwreq_data *wrqu,
3142 char *extra)
3143
3144{
3145 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303146 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003148 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303149 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003150 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303151 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003152 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003153 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303154 int rc, valid;
3155
3156 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3157
3158 valid = wlan_hdd_validate_context(pHddCtx);
3159
3160 if (0 != valid)
3161 {
3162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3163 return valid;
3164 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003165
Arif Hussain6d2a3322013-11-17 19:50:10 -08003166 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003167
3168 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003169 {
Arif Hussaina9571842014-01-15 16:43:41 -08003170 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3171 if (NULL == pmacAddress) {
3172 hddLog(LOG1, "unable to allocate memory");
3173 return -ENOMEM;
3174 }
3175 if (copy_from_user((void *)pmacAddress,
3176 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3177 {
3178 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3179 kfree(pmacAddress);
3180 return -EFAULT;
3181 }
3182 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3183
3184 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003185 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003186
3187 if (!VOS_IS_STATUS_SUCCESS(status ))
3188 {
3189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3190 }
Arif Hussained667642013-10-27 23:01:14 -07003191 }
Kiet Lam61589852013-09-19 17:10:58 +05303192 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303193 * link speed for first connected client will be returned.
3194 */
Arif Hussaina9571842014-01-15 16:43:41 -08003195 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303196 {
3197 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3198 }
3199 else
3200 {
3201 status = hdd_softap_GetStaId(pHostapdAdapter,
3202 (v_MACADDR_t *)macAddress, (void *)(&staId));
3203 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003204
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303205 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003206 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003208 link_speed = 0;
3209 }
3210 else
3211 {
3212 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303213
Jeff Johnson295189b2012-06-20 16:38:30 -07003214 if (!VOS_IS_STATUS_SUCCESS(status ))
3215 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 return -EINVAL;
3218 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303219
3220 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3221 staId, &link_speed);
3222
3223 link_speed = link_speed / 10;
3224
3225 if (0 == link_speed)
3226 {
3227 /* The linkspeed returned by HAL is in units of 500kbps.
3228 * converting it to mbps.
3229 * This is required to support legacy firmware which does
3230 * not return link capacity.
3231 */
3232 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003234 }
3235
3236 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003237 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303238
Jeff Johnson295189b2012-06-20 16:38:30 -07003239 if ((rc < 0) || (rc >= len))
3240 {
3241 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303242 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003243 return -EIO;
3244 }
3245
3246 return 0;
3247}
3248
3249static const iw_handler hostapd_handler[] =
3250{
3251 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3252 (iw_handler) NULL, /* SIOCGIWNAME */
3253 (iw_handler) NULL, /* SIOCSIWNWID */
3254 (iw_handler) NULL, /* SIOCGIWNWID */
3255 (iw_handler) NULL, /* SIOCSIWFREQ */
3256 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3257 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303258 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003259 (iw_handler) NULL, /* SIOCSIWSENS */
3260 (iw_handler) NULL, /* SIOCGIWSENS */
3261 (iw_handler) NULL, /* SIOCSIWRANGE */
3262 (iw_handler) NULL, /* SIOCGIWRANGE */
3263 (iw_handler) NULL, /* SIOCSIWPRIV */
3264 (iw_handler) NULL, /* SIOCGIWPRIV */
3265 (iw_handler) NULL, /* SIOCSIWSTATS */
3266 (iw_handler) NULL, /* SIOCGIWSTATS */
3267 (iw_handler) NULL, /* SIOCSIWSPY */
3268 (iw_handler) NULL, /* SIOCGIWSPY */
3269 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3270 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3271 (iw_handler) NULL, /* SIOCSIWAP */
3272 (iw_handler) NULL, /* SIOCGIWAP */
3273 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3274 (iw_handler) NULL, /* SIOCGIWAPLIST */
3275 (iw_handler) NULL, /* SIOCSIWSCAN */
3276 (iw_handler) NULL, /* SIOCGIWSCAN */
3277 (iw_handler) NULL, /* SIOCSIWESSID */
3278 (iw_handler) NULL, /* SIOCGIWESSID */
3279 (iw_handler) NULL, /* SIOCSIWNICKN */
3280 (iw_handler) NULL, /* SIOCGIWNICKN */
3281 (iw_handler) NULL, /* -- hole -- */
3282 (iw_handler) NULL, /* -- hole -- */
3283 (iw_handler) NULL, /* SIOCSIWRATE */
3284 (iw_handler) NULL, /* SIOCGIWRATE */
3285 (iw_handler) NULL, /* SIOCSIWRTS */
3286 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3287 (iw_handler) NULL, /* SIOCSIWFRAG */
3288 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3289 (iw_handler) NULL, /* SIOCSIWTXPOW */
3290 (iw_handler) NULL, /* SIOCGIWTXPOW */
3291 (iw_handler) NULL, /* SIOCSIWRETRY */
3292 (iw_handler) NULL, /* SIOCGIWRETRY */
3293 (iw_handler) NULL, /* SIOCSIWENCODE */
3294 (iw_handler) NULL, /* SIOCGIWENCODE */
3295 (iw_handler) NULL, /* SIOCSIWPOWER */
3296 (iw_handler) NULL, /* SIOCGIWPOWER */
3297 (iw_handler) NULL, /* -- hole -- */
3298 (iw_handler) NULL, /* -- hole -- */
3299 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3300 (iw_handler) NULL, /* SIOCGIWGENIE */
3301 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3302 (iw_handler) NULL, /* SIOCGIWAUTH */
3303 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3304 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3305 (iw_handler) NULL, /* SIOCSIWPMKSA */
3306};
3307
Jeff Johnson224f3702014-03-26 11:09:47 -07003308/*
3309 * Note that the following ioctls were defined with semantics which
3310 * cannot be handled by the "iwpriv" userspace application and hence
3311 * they are not included in the hostapd_private_args array
3312 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3313 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003314
3315static const struct iw_priv_args hostapd_private_args[] = {
3316 { QCSAP_IOCTL_SETPARAM,
3317 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3318 { QCSAP_IOCTL_SETPARAM,
3319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3320 { QCSAP_PARAM_MAX_ASSOC,
3321 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3322 { QCSAP_PARAM_HIDE_SSID,
3323 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003324 { QCSAP_PARAM_SET_MC_RATE,
3325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003326 { QCSAP_IOCTL_GETPARAM,
3327 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3328 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3329 { QCSAP_IOCTL_GETPARAM, 0,
3330 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3331 { QCSAP_PARAM_MAX_ASSOC, 0,
3332 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003333 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3334 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3335 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3336 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303337 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3338 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003339 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
3340 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
3341 { QCSAP_PARAM_CLR_ACL, 0,
3342 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3343 { QCSAP_PARAM_ACL_MODE,
3344 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003345 { QCSAP_IOCTL_SETMLME,
3346 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
3347 { QCSAP_IOCTL_GET_STAWPAIE,
3348 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3349 { QCSAP_IOCTL_SETWPAIE,
3350 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3351 { QCSAP_IOCTL_STOPBSS,
3352 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3353 { QCSAP_IOCTL_VERSION, 0,
3354 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003355 { QCSAP_IOCTL_GET_STA_INFO, 0,
3356 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003357 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003358 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003359 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003360 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003361 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003362 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05303363 { QCSAP_IOCTL_AP_STATS, 0,
3364 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003365 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3366 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303367 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003368
3369 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3370 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3371 /* handlers for sub-ioctl */
3372 { WE_SET_WLAN_DBG,
3373 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3374 0,
3375 "setwlandbg" },
3376
3377 /* handlers for main ioctl */
3378 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3379 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3380 0,
3381 "" },
3382
3383 /* handlers for sub-ioctl */
3384 { WE_LOG_DUMP_CMD,
3385 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3386 0,
3387 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 { WE_P2P_NOA_CMD,
3389 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3390 0,
3391 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003392 /* handlers for sub ioctl */
3393 {
3394 WE_MCC_CONFIG_CREDENTIAL,
3395 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3396 0,
3397 "setMccCrdnl" },
3398
3399 /* handlers for sub ioctl */
3400 {
3401 WE_MCC_CONFIG_PARAMS,
3402 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3403 0,
3404 "setMccConfig" },
3405
Jeff Johnson295189b2012-06-20 16:38:30 -07003406 /* handlers for main ioctl */
3407 { QCSAP_IOCTL_MODIFY_ACL,
3408 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3409 0,
3410 "modify_acl" },
3411
3412 /* handlers for main ioctl */
3413 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3414 0,
3415 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3416 "getChannelList" },
3417
Jeff Johnsone7245742012-09-05 17:12:55 -07003418 /* handlers for main ioctl */
3419 { QCSAP_IOCTL_SET_TX_POWER,
3420 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3421 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303422 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003423
3424 /* handlers for main ioctl */
3425 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3426 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3427 0,
3428 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303429
3430 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3431 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3432 0,
3433 "dataSnapshot" },
3434
3435 /* handlers for main ioctl */
3436 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3437 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3438 0,
3439 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003440};
Jeff Johnsone7245742012-09-05 17:12:55 -07003441
Jeff Johnson295189b2012-06-20 16:38:30 -07003442static const iw_handler hostapd_private[] = {
3443 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3444 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07003445 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
3446 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3447 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3448 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3449 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3450 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3451 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3452 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3453 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3454 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3455 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3456 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3457 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3458 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3459 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003460 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003461 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3462 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003463 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303464 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303465 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003466};
3467const struct iw_handler_def hostapd_handler_def = {
3468 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3469 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3470 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3471 .standard = (iw_handler *)hostapd_handler,
3472 .private = (iw_handler *)hostapd_private,
3473 .private_args = hostapd_private_args,
3474 .get_wireless_stats = NULL,
3475};
3476#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3477struct net_device_ops net_ops_struct = {
3478 .ndo_open = hdd_hostapd_open,
3479 .ndo_stop = hdd_hostapd_stop,
3480 .ndo_uninit = hdd_hostapd_uninit,
3481 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3482 .ndo_tx_timeout = hdd_softap_tx_timeout,
3483 .ndo_get_stats = hdd_softap_stats,
3484 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3485 .ndo_do_ioctl = hdd_hostapd_ioctl,
3486 .ndo_change_mtu = hdd_hostapd_change_mtu,
3487 .ndo_select_queue = hdd_hostapd_select_queue,
3488 };
3489#endif
3490
3491int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3492{
3493 return VOS_STATUS_SUCCESS;
3494}
3495
3496void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3497{
3498#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3499 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3500#else
3501 pWlanHostapdDev->open = hdd_hostapd_open;
3502 pWlanHostapdDev->stop = hdd_hostapd_stop;
3503 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3504 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3505 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3506 pWlanHostapdDev->get_stats = hdd_softap_stats;
3507 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3508 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3509#endif
3510}
3511
3512VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
3513{
3514 hdd_hostapd_state_t * phostapdBuf;
3515 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003516 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08003518#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08003519 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
3520 v_U16_t unsafeChannelCount;
3521#endif /* FEATURE_WLAN_CH_AVOID */
3522
Jeff Johnson295189b2012-06-20 16:38:30 -07003523 ENTER();
3524 // Allocate the Wireless Extensions state structure
3525 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
3526
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003527 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
3528
Leo Chang0b0e45a2013-12-15 15:18:55 -08003529#ifdef FEATURE_WLAN_CH_AVOID
3530 /* Get unsafe cahnnel list from cached location */
3531 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
3532 sizeof(unsafeChannelList),
3533 &unsafeChannelCount);
3534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3535 "%s : Unsafe Channel count %d",
3536 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05303537 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08003538 unsafeChannelList,
3539 unsafeChannelCount);
3540#endif /* FEATURE_WLAN_CH_AVOID */
3541
Jeff Johnson295189b2012-06-20 16:38:30 -07003542 // Zero the memory. This zeros the profile structure.
3543 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
3544
3545 // Set up the pointer to the Wireless Extensions state structure
3546 // NOP
3547 status = hdd_set_hostapd(pAdapter);
3548 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003550 return status;
3551 }
3552
3553 status = vos_event_init(&phostapdBuf->vosEvent);
3554 if (!VOS_IS_STATUS_SUCCESS(status))
3555 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003557 return status;
3558 }
3559
3560 init_completion(&pAdapter->session_close_comp_var);
3561 init_completion(&pAdapter->session_open_comp_var);
3562
3563 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
3564
3565 // Register as a wireless device
3566 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
3567
3568 //Initialize the data path module
3569 status = hdd_softap_init_tx_rx(pAdapter);
3570 if ( !VOS_IS_STATUS_SUCCESS( status ))
3571 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003572 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003573 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303574
3575 status = hdd_wmm_adapter_init( pAdapter );
3576 if (!VOS_IS_STATUS_SUCCESS(status))
3577 {
3578 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003579 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303580 status, status );
3581 goto error_wmm_init;
3582 }
3583
3584 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3585
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303587
3588 return status;
3589
3590error_wmm_init:
3591 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 EXIT();
3593 return status;
3594}
3595
3596hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
3597{
3598 struct net_device *pWlanHostapdDev = NULL;
3599 hdd_adapter_t *pHostapdAdapter = NULL;
3600 v_CONTEXT_t pVosContext= NULL;
3601
Jeff Johnson295189b2012-06-20 16:38:30 -07003602 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07003603
3604 if (pWlanHostapdDev != NULL)
3605 {
3606 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
3607
3608 //Init the net_device structure
3609 ether_setup(pWlanHostapdDev);
3610
3611 //Initialize the adapter context to zeros.
3612 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
3613 pHostapdAdapter->dev = pWlanHostapdDev;
3614 pHostapdAdapter->pHddCtx = pHddCtx;
3615 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3616
3617 //Get the Global VOSS context.
3618 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3619 //Save the adapter context in global context for future.
3620 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3621
3622 //Init the net_device structure
3623 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3624
3625 hdd_set_ap_ops( pHostapdAdapter->dev );
3626
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3628 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3629
3630 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3631 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3632
3633 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003634 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3635 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3636 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3637 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003638 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3639 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05303640 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07003641#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3642 init_completion(&pHostapdAdapter->offchannel_tx_event);
3643#endif
3644
Jeff Johnson295189b2012-06-20 16:38:30 -07003645 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3646 }
3647 return pHostapdAdapter;
3648}
3649
3650VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3651{
3652 struct net_device *dev = pAdapter->dev;
3653 VOS_STATUS status = VOS_STATUS_SUCCESS;
3654
3655 ENTER();
3656
3657 if( rtnl_lock_held )
3658 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003659 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 if( dev_alloc_name(dev, dev->name) < 0 )
3661 {
3662 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3663 return VOS_STATUS_E_FAILURE;
3664 }
3665 }
3666 if (register_netdevice(dev))
3667 {
3668 hddLog(VOS_TRACE_LEVEL_FATAL,
3669 "%s:Failed:register_netdevice", __func__);
3670 return VOS_STATUS_E_FAILURE;
3671 }
3672 }
3673 else
3674 {
3675 if (register_netdev(dev))
3676 {
3677 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3678 return VOS_STATUS_E_FAILURE;
3679 }
3680 }
3681 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3682
3683 EXIT();
3684 return status;
3685}
3686
3687VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3688{
3689 ENTER();
3690
3691 hdd_softap_deinit_tx_rx(pAdapter);
3692
3693 /* if we are being called during driver unload, then the dev has already
3694 been invalidated. if we are being called at other times, then we can
3695 detatch the wireless device handlers */
3696 if (pAdapter->dev)
3697 {
3698 pAdapter->dev->wireless_handlers = NULL;
3699 }
3700 EXIT();
3701 return 0;
3702}