blob: 34b8358ccb4ad0988171e92f1a4167c04d9afb30 [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;
1984 int len = wrqu->data.length;
1985 pstatbuf = wrqu->data.pointer;
1986
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001987 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07001988 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
1989 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07001990
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05301991 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07001992 if(NULL == pstatbuf) {
1993 hddLog(LOG1, "unable to allocate memory");
1994 return -ENOMEM;
1995 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05301996
1997 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07001998 "RUF=%d RMF=%d RBF=%d "
1999 "RUB=%d RMB=%d RBB=%d "
2000 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302001 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002002 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2003 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2004 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2005 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2006 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2007 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002008
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302009 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002010 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2011 kfree(pstatbuf);
2012 return -EFAULT;
2013 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302014
2015 strlcpy(extra, pstatbuf, len);
2016 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002017 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002018 return 0;
2019}
2020
Jeff Johnson295189b2012-06-20 16:38:30 -07002021static
2022int iw_softap_setmlme(struct net_device *dev,
2023 struct iw_request_info *info,
2024 union iwreq_data *wrqu, char *extra)
2025{
2026 struct sQcSapreq_mlme *pmlme;
2027 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
2028 v_MACADDR_t destAddress;
2029 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
2030 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
2031 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
2032 switch(pmlme->im_op)
2033 {
2034 case QCSAP_MLME_AUTHORIZE:
2035 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
2036 break;
2037 case QCSAP_MLME_ASSOC:
2038 //TODO:inform to TL after associating (not needed as we do in sapCallback)
2039 break;
2040 case QCSAP_MLME_UNAUTHORIZE:
2041 //TODO: send the disassoc to station
2042 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
2043 break;
2044 case QCSAP_MLME_DISASSOC:
2045 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
2046 break;
2047 case QCSAP_MLME_DEAUTH:
2048 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
2049 break;
2050 case QCSAP_MLME_MICFAILURE:
2051 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
2052 break;
2053 default:
2054 break;
2055 }
2056 return 0;
2057}
2058
2059static int iw_softap_set_channel_range(struct net_device *dev,
2060 struct iw_request_info *info,
2061 union iwreq_data *wrqu, char *extra)
2062{
2063 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2064 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002065 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002066
2067 int *value = (int *)extra;
2068 int startChannel = value[0];
2069 int endChannel = value[1];
2070 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002071 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 int ret = 0; /* success */
2073
2074 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2075 if(status != VOS_STATUS_SUCCESS)
2076 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002077 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002078 startChannel,endChannel, band);
2079 ret = -EINVAL;
2080 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002081
2082 pHddCtx->is_dynamic_channel_range_set = 1;
2083
Jeff Johnson295189b2012-06-20 16:38:30 -07002084 return ret;
2085}
2086
2087int iw_softap_get_channel_list(struct net_device *dev,
2088 struct iw_request_info *info,
2089 union iwreq_data *wrqu, char *extra)
2090{
2091 v_U32_t num_channels = 0;
2092 v_U8_t i = 0;
2093 v_U8_t bandStartChannel = RF_CHAN_1;
2094 v_U8_t bandEndChannel = RF_CHAN_165;
2095 v_U32_t temp_num_channels = 0;
2096 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2097 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2098 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002100 eCsrBand curBand = eCSR_BAND_ALL;
2101
2102 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2103 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002104 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002105 return -EIO;
2106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 wrqu->data.length = sizeof(tChannelListInfo);
2108 ENTER();
2109
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002110 if (eCSR_BAND_24 == curBand)
2111 {
2112 bandStartChannel = RF_CHAN_1;
2113 bandEndChannel = RF_CHAN_14;
2114 }
2115 else if (eCSR_BAND_5G == curBand)
2116 {
2117 bandStartChannel = RF_CHAN_36;
2118 bandEndChannel = RF_CHAN_165;
2119 }
2120
Arif Hussain6d2a3322013-11-17 19:50:10 -08002121 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302122 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002123 bandStartChannel, bandEndChannel );
2124
Jeff Johnson295189b2012-06-20 16:38:30 -07002125 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2126 {
2127 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2128 {
2129 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2130 num_channels++;
2131 }
2132 }
2133
2134 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2135
2136 temp_num_channels = num_channels;
2137
2138 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2139 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302140 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002141 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 }
2143
2144 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
2145 {
2146 for(i = 0; i < temp_num_channels; i++)
2147 {
2148
2149 if((channel_list->channels[i] > 35) &&
2150 (channel_list->channels[i] < 49))
2151 {
2152 vos_mem_move(&channel_list->channels[i],
2153 &channel_list->channels[i+1],
2154 temp_num_channels - (i-1));
2155 num_channels--;
2156 temp_num_channels--;
2157 i--;
2158 }
2159 }
2160 }
2161
Arif Hussain6d2a3322013-11-17 19:50:10 -08002162 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002163
2164 if (num_channels > IW_MAX_FREQUENCIES)
2165 {
2166 num_channels = IW_MAX_FREQUENCIES;
2167 }
2168
2169 channel_list->num_channels = num_channels;
2170 EXIT();
2171
2172 return 0;
2173}
2174
2175static
2176int iw_get_genie(struct net_device *dev,
2177 struct iw_request_info *info,
2178 union iwreq_data *wrqu, char *extra)
2179{
2180 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2181 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2182 eHalStatus status;
2183 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2184 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2185 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002186 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2188 status = WLANSap_getstationIE_information(pVosContext,
2189 &length,
2190 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002191 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2192 if (wrqu->data.length < length ||
2193 copy_to_user(wrqu->data.pointer,
2194 (v_VOID_t*)genIeBytes, length))
2195 {
2196 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2197 return -EFAULT;
2198 }
2199 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002200
Arif Hussain6d2a3322013-11-17 19:50:10 -08002201 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002202
2203
2204 EXIT();
2205 return 0;
2206}
2207static
2208int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2209 struct iw_request_info *info,
2210 union iwreq_data *wrqu, char *extra)
2211{
2212 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002213 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2215 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002216
Arif Hussain6d2a3322013-11-17 19:50:10 -08002217 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002218 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2219
2220 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2221 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2222 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2223 WPSPBCProbeReqIEs.probeReqIELen);
2224 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2225 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2226 sizeof(v_MACADDR_t));
2227 if (copy_to_user(wrqu->data.pointer,
2228 (void *)&WPSPBCProbeReqIEs,
2229 sizeof(WPSPBCProbeReqIEs)))
2230 {
2231 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2232 return -EFAULT;
2233 }
2234 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002235 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002236 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002237 up(&pHddApCtx->semWpsPBCOverlapInd);
2238 EXIT();
2239 return 0;
2240}
2241
2242/**---------------------------------------------------------------------------
2243
2244 \brief iw_set_auth_hostap() -
2245 This function sets the auth type received from the wpa_supplicant.
2246
2247 \param - dev - Pointer to the net device.
2248 - info - Pointer to the iw_request_info.
2249 - wrqu - Pointer to the iwreq_data.
2250 - extra - Pointer to the data.
2251 \return - 0 for success, non zero for failure
2252
2253 --------------------------------------------------------------------------*/
2254int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
2255 union iwreq_data *wrqu,char *extra)
2256{
2257 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2258 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2259
2260 ENTER();
2261 switch(wrqu->param.flags & IW_AUTH_INDEX)
2262 {
2263 case IW_AUTH_TKIP_COUNTERMEASURES:
2264 {
2265 if(wrqu->param.value) {
2266 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2267 "Counter Measure started %d", wrqu->param.value);
2268 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2269 }
2270 else {
2271 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2272 "Counter Measure stopped=%d", wrqu->param.value);
2273 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2274 }
2275
2276 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2277 wrqu->param.value);
2278 }
2279 break;
2280
2281 default:
2282
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002283 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 wrqu->param.flags & IW_AUTH_INDEX);
2285 break;
2286 }
2287
2288 EXIT();
2289 return 0;
2290}
2291
2292static int iw_set_ap_encodeext(struct net_device *dev,
2293 struct iw_request_info *info,
2294 union iwreq_data *wrqu, char *extra)
2295{
2296 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2297 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2298 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002299 int retval = 0;
2300 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002301 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2302 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2303 int key_index;
2304 struct iw_point *encoding = &wrqu->encoding;
2305 tCsrRoamSetKey setKey;
2306// tCsrRoamRemoveKey RemoveKey;
2307 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002308
Jeff Johnson295189b2012-06-20 16:38:30 -07002309 ENTER();
2310
2311 key_index = encoding->flags & IW_ENCODE_INDEX;
2312
2313 if(key_index > 0) {
2314
2315 /*Convert from 1-based to 0-based keying*/
2316 key_index--;
2317 }
2318 if(!ext->key_len) {
2319#if 0
2320 /*Set the encrytion type to NONE*/
2321#if 0
2322 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2323#endif
2324
2325 RemoveKey.keyId = key_index;
2326 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2327 /*Key direction for group is RX only*/
2328 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2329 }
2330 else {
2331 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2332 }
2333 switch(ext->alg)
2334 {
2335 case IW_ENCODE_ALG_NONE:
2336 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2337 break;
2338 case IW_ENCODE_ALG_WEP:
2339 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2340 break;
2341 case IW_ENCODE_ALG_TKIP:
2342 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002343 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 case IW_ENCODE_ALG_CCMP:
2345 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2346 break;
2347 default:
2348 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2349 break;
2350 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002351 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 -07002352 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002354 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002355 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002356 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2357 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002358 {
2359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002360 __LINE__, vstatus );
2361 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002362 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002363#endif
2364 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002365
Jeff Johnson43971f52012-07-17 12:26:56 -07002366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002367
2368 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2369
2370 setKey.keyId = key_index;
2371 setKey.keyLength = ext->key_len;
2372
2373 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2374 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2375 }
2376
2377 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2378 /*Key direction for group is RX only*/
2379 setKey.keyDirection = eSIR_RX_ONLY;
2380 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2381 }
2382 else {
2383
2384 setKey.keyDirection = eSIR_TX_RX;
2385 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2386 }
2387 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2388 {
2389 setKey.keyDirection = eSIR_TX_DEFAULT;
2390 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2391 }
2392
2393 /*For supplicant pae role is zero*/
2394 setKey.paeRole = 0;
2395
2396 switch(ext->alg)
2397 {
2398 case IW_ENCODE_ALG_NONE:
2399 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2400 break;
2401
2402 case IW_ENCODE_ALG_WEP:
2403 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2404 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002405 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002406 break;
2407
2408 case IW_ENCODE_ALG_TKIP:
2409 {
2410 v_U8_t *pKey = &setKey.Key[0];
2411
2412 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2413
2414 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2415
2416 /*Supplicant sends the 32bytes key in this order
2417
2418 |--------------|----------|----------|
2419 | Tk1 |TX-MIC | RX Mic |
2420 |--------------|----------|----------|
2421 <---16bytes---><--8bytes--><--8bytes-->
2422
2423 */
2424 /*Sme expects the 32 bytes key to be in the below order
2425
2426 |--------------|----------|----------|
2427 | Tk1 |RX-MIC | TX Mic |
2428 |--------------|----------|----------|
2429 <---16bytes---><--8bytes--><--8bytes-->
2430 */
2431 /* Copy the Temporal Key 1 (TK1) */
2432 vos_mem_copy(pKey,ext->key,16);
2433
2434 /*Copy the rx mic first*/
2435 vos_mem_copy(&pKey[16],&ext->key[24],8);
2436
2437 /*Copy the tx mic */
2438 vos_mem_copy(&pKey[24],&ext->key[16],8);
2439
2440 }
2441 break;
2442
2443 case IW_ENCODE_ALG_CCMP:
2444 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2445 break;
2446
2447 default:
2448 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2449 break;
2450 }
2451
2452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302453 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002454 setKey.keyId);
2455 for(i=0; i< ext->key_len; i++)
2456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2457 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002458
2459 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2460 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002463 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2464 retval = -EINVAL;
2465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002466
Jeff Johnson43971f52012-07-17 12:26:56 -07002467 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002468}
Jeff Johnson43971f52012-07-17 12:26:56 -07002469
2470
Jeff Johnson295189b2012-06-20 16:38:30 -07002471static int iw_set_ap_mlme(struct net_device *dev,
2472 struct iw_request_info *info,
2473 union iwreq_data *wrqu,
2474 char *extra)
2475{
2476#if 0
2477 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2478 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2479
2480 ENTER();
2481
2482 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2483 switch (mlme->cmd) {
2484 case IW_MLME_DISASSOC:
2485 case IW_MLME_DEAUTH:
2486 hddLog(LOG1, "Station disassociate");
2487 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2488 {
2489 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2490
2491 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2492 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2493
2494 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2495
2496 //clear all the reason codes
2497 if (status != 0)
2498 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002499 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002500 }
2501
2502 netif_stop_queue(dev);
2503 netif_carrier_off(dev);
2504 }
2505 else
2506 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002507 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 -07002508 }
2509 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002510 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 return -EINVAL;
2512 }//end of switch
2513 EXIT();
2514#endif
2515 return 0;
2516// return status;
2517}
2518
2519static int iw_get_ap_rts_threshold(struct net_device *dev,
2520 struct iw_request_info *info,
2521 union iwreq_data *wrqu, char *extra)
2522{
2523 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2524 v_U32_t status = 0;
2525
2526 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2527
2528 return status;
2529}
2530
2531static int iw_get_ap_frag_threshold(struct net_device *dev,
2532 struct iw_request_info *info,
2533 union iwreq_data *wrqu, char *extra)
2534{
2535 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2536 v_U32_t status = 0;
2537
2538 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2539
2540 return status;
2541}
2542
2543static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2544 struct iw_freq *fwrq, char *extra)
2545{
Jeff Johnsone7245742012-09-05 17:12:55 -07002546 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2548 tHalHandle hHal;
2549 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002550 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002551
2552 ENTER();
2553
2554 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2556 "%s:LOGP in Progress. Ignore!!!",__func__);
2557 return status;
2558 }
2559
2560 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2561 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2562
2563 if(pHostapdState->bssState == BSS_STOP )
2564 {
2565 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2566 != eHAL_STATUS_SUCCESS)
2567 {
c_hpothuffdb5272013-10-02 16:42:35 +05302568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2569 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002570 return -EIO;
2571 }
2572 else
2573 {
2574 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002575 if( TRUE == status)
2576 {
2577 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2578 * iwlist & iwconfig command shows frequency into proper
2579 * format (2.412 GHz instead of 246.2 MHz)*/
2580 fwrq->m = freq;
2581 fwrq->e = MHZ;
2582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002583 }
2584 }
2585 else
2586 {
2587 channel = pHddApCtx->operatingChannel;
2588 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002589 if( TRUE == status)
2590 {
2591 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2592 * iwlist & iwconfig command shows frequency into proper
2593 * format (2.412 GHz instead of 246.2 MHz)*/
2594 fwrq->m = freq;
2595 fwrq->e = MHZ;
2596 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002598 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002599}
2600
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302601static int iw_get_mode(struct net_device *dev,
2602 struct iw_request_info *info,
2603 union iwreq_data *wrqu,
2604 char *extra)
2605{
2606 int status = 0;
2607
2608 wrqu->mode = IW_MODE_MASTER;
2609
2610 return status;
2611}
2612
Jeff Johnson295189b2012-06-20 16:38:30 -07002613static int iw_softap_setwpsie(struct net_device *dev,
2614 struct iw_request_info *info,
2615 union iwreq_data *wrqu,
2616 char *extra)
2617{
2618 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2619 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2620 hdd_hostapd_state_t *pHostapdState;
2621 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002622 u_int8_t *wps_genie;
2623 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 u_int8_t *pos;
2625 tpSap_WPSIE pSap_WPSIe;
2626 u_int8_t WPSIeType;
2627 u_int16_t length;
2628 ENTER();
2629
Arif Hussained667642013-10-27 23:01:14 -07002630 if(!wrqu->data.length || wrqu->data.length <= QCSAP_MAX_WSC_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002631 return 0;
2632
Arif Hussained667642013-10-27 23:01:14 -07002633 wps_genie = kmalloc(wrqu->data.length, GFP_KERNEL);
2634
2635 if(NULL == wps_genie) {
2636 hddLog(LOG1, "unable to allocate memory");
2637 return -ENOMEM;
2638 }
2639 fwps_genie = wps_genie;
2640 if (copy_from_user((void *)wps_genie,
2641 wrqu->data.pointer, wrqu->data.length))
2642 {
2643 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2644 kfree(fwps_genie);
2645 return -EFAULT;
2646 }
2647
Jeff Johnson295189b2012-06-20 16:38:30 -07002648 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2649 if (NULL == pSap_WPSIe)
2650 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002651 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07002652 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002653 return -ENOMEM;
2654 }
2655 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2656
Arif Hussain6d2a3322013-11-17 19:50:10 -08002657 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 -07002658 WPSIeType = wps_genie[0];
2659 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2660 {
2661 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2662 wps_genie = wps_genie + 1;
2663 switch ( wps_genie[0] )
2664 {
2665 case DOT11F_EID_WPA:
2666 if (wps_genie[1] < 2 + 4)
2667 {
2668 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002669 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002670 return -EINVAL;
2671 }
2672 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2673 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002674 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002675 pos = &wps_genie[6];
2676 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2677 {
2678 switch((u_int16_t)(*pos<<8) | *(pos+1))
2679 {
2680 case HDD_WPS_ELEM_VERSION:
2681 pos += 4;
2682 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002683 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002684 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2685 pos += 1;
2686 break;
2687
2688 case HDD_WPS_ELEM_WPS_STATE:
2689 pos +=4;
2690 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002691 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002692 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2693 pos += 1;
2694 break;
2695 case HDD_WPS_ELEM_APSETUPLOCK:
2696 pos += 4;
2697 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002698 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2700 pos += 1;
2701 break;
2702 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2703 pos += 4;
2704 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002705 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002706 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2707 pos += 1;
2708 break;
2709 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2710 pos += 4;
2711 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002712 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002713 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2714 pos += 2;
2715 break;
2716 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2717 pos += 4;
2718 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002719 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002720 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2721 pos += 2;
2722 break;
2723
2724 case HDD_WPS_ELEM_UUID_E:
2725 pos += 2;
2726 length = *pos<<8 | *(pos+1);
2727 pos += 2;
2728 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2729 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2730 pos += length;
2731 break;
2732 case HDD_WPS_ELEM_RF_BANDS:
2733 pos += 4;
2734 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002735 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002736 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2737 pos += 1;
2738 break;
2739
2740 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002741 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07002742 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002743 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002744 return -EINVAL;
2745 }
2746 }
2747 }
2748 else {
2749 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002750 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002751 }
2752 break;
2753
2754 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002755 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002757 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002758 return 0;
2759 }
2760 }
2761 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2762 {
2763 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2764 wps_genie = wps_genie + 1;
2765 switch ( wps_genie[0] )
2766 {
2767 case DOT11F_EID_WPA:
2768 if (wps_genie[1] < 2 + 4)
2769 {
2770 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002771 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002772 return -EINVAL;
2773 }
2774 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2775 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002776 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002777 pos = &wps_genie[6];
2778 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2779 {
2780 switch((u_int16_t)(*pos<<8) | *(pos+1))
2781 {
2782 case HDD_WPS_ELEM_VERSION:
2783 pos += 4;
2784 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002785 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002786 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2787 pos += 1;
2788 break;
2789
2790 case HDD_WPS_ELEM_WPS_STATE:
2791 pos +=4;
2792 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002793 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002794 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2795 pos += 1;
2796 break;
2797 case HDD_WPS_ELEM_APSETUPLOCK:
2798 pos += 4;
2799 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002800 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002801 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2802 pos += 1;
2803 break;
2804 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2805 pos += 4;
2806 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002807 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002808 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2809 pos += 1;
2810 break;
2811 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2812 pos += 4;
2813 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002814 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002815 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2816 pos += 2;
2817 break;
2818 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2819 pos += 4;
2820 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002821 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2823 pos += 2;
2824 break;
2825 case HDD_WPS_ELEM_RSP_TYPE:
2826 pos += 4;
2827 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002828 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002829 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2830 pos += 1;
2831 break;
2832 case HDD_WPS_ELEM_UUID_E:
2833 pos += 2;
2834 length = *pos<<8 | *(pos+1);
2835 pos += 2;
2836 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2837 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2838 pos += length;
2839 break;
2840
2841 case HDD_WPS_ELEM_MANUFACTURER:
2842 pos += 2;
2843 length = *pos<<8 | *(pos+1);
2844 pos += 2;
2845 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2846 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2847 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2848 pos += length;
2849 break;
2850
2851 case HDD_WPS_ELEM_MODEL_NAME:
2852 pos += 2;
2853 length = *pos<<8 | *(pos+1);
2854 pos += 2;
2855 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2856 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2857 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2858 pos += length;
2859 break;
2860 case HDD_WPS_ELEM_MODEL_NUM:
2861 pos += 2;
2862 length = *pos<<8 | *(pos+1);
2863 pos += 2;
2864 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2865 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2866 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2867 pos += length;
2868 break;
2869 case HDD_WPS_ELEM_SERIAL_NUM:
2870 pos += 2;
2871 length = *pos<<8 | *(pos+1);
2872 pos += 2;
2873 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2874 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2875 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2876 pos += length;
2877 break;
2878 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2879 pos += 4;
2880 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002881 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002882 pos += 2;
2883
2884 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002885 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002886 pos += 4;
2887 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002888 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002889 pos += 2;
2890 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2891 break;
2892 case HDD_WPS_ELEM_DEVICE_NAME:
2893 pos += 2;
2894 length = *pos<<8 | *(pos+1);
2895 pos += 2;
2896 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2897 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2898 pos += length;
2899 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2900 break;
2901 case HDD_WPS_ELEM_CONFIG_METHODS:
2902 pos += 4;
2903 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002904 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002905 pos += 2;
2906 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2907 break;
2908
2909 case HDD_WPS_ELEM_RF_BANDS:
2910 pos += 4;
2911 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002912 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002913 pos += 1;
2914 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2915 break;
2916 } // switch
2917 }
2918 }
2919 else
2920 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002921 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002922 }
2923
2924 } // switch
2925 }
2926 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2927 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2928 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2929 {
2930 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2931 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2932 WLANSAP_Update_WpsIe ( pVosContext );
2933 }
2934
2935 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002936 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002937 EXIT();
2938 return halStatus;
2939}
2940
2941static int iw_softap_stopbss(struct net_device *dev,
2942 struct iw_request_info *info,
2943 union iwreq_data *wrqu,
2944 char *extra)
2945{
2946 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2947 VOS_STATUS status = VOS_STATUS_SUCCESS;
2948 ENTER();
2949 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2950 {
2951 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2952 {
2953 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2954
2955 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2956
2957 if (!VOS_IS_STATUS_SUCCESS(status))
2958 {
2959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002960 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 VOS_ASSERT(0);
2962 }
2963 }
2964 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2965 }
2966 EXIT();
2967 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2968}
2969
2970static int iw_softap_version(struct net_device *dev,
2971 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002972 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 char *extra)
2974{
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002976
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002978 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002979 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 return 0;
2981}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002982
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002983VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002984{
2985 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002986 int len = 0;
2987 const char sta_info_header[] = "staId staAddress\n";
2988
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002989 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002990 pBuf += len;
2991 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002992
2993 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2994 {
2995 if(pAdapter->aStaInfo[i].isUsed)
2996 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08002997 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002998 pAdapter->aStaInfo[i].ucSTAId,
2999 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
3000 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
3001 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
3002 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
3003 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
3004 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003005 pBuf += len;
3006 buf_len -= len;
3007 }
3008 if(WE_GET_STA_INFO_SIZE > buf_len)
3009 {
3010 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003011 }
3012 }
3013 return VOS_STATUS_SUCCESS;
3014}
3015
3016static int iw_softap_get_sta_info(struct net_device *dev,
3017 struct iw_request_info *info,
3018 union iwreq_data *wrqu,
3019 char *extra)
3020{
3021 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3022 VOS_STATUS status;
3023 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003024 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003025 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003027 return -EINVAL;
3028 }
3029 wrqu->data.length = strlen(extra);
3030 EXIT();
3031 return 0;
3032}
3033
Jeff Johnson295189b2012-06-20 16:38:30 -07003034static int iw_set_ap_genie(struct net_device *dev,
3035 struct iw_request_info *info,
3036 union iwreq_data *wrqu,
3037 char *extra)
3038{
3039
3040 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3041 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3042 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003043 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003044
3045 ENTER();
3046
3047 if(!wrqu->data.length)
3048 {
3049 EXIT();
3050 return 0;
3051 }
Arif Hussained667642013-10-27 23:01:14 -07003052
Jeff Johnson295189b2012-06-20 16:38:30 -07003053 switch (genie[0])
3054 {
3055 case DOT11F_EID_WPA:
3056 case DOT11F_EID_RSN:
3057 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3058 {
3059 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3060 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3061 }
3062 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003063 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003064 break;
3065
3066 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003067 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003068 halStatus = 0;
3069 }
3070
3071 EXIT();
3072 return halStatus;
3073}
3074
3075static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3076{
3077 eHalStatus hstatus;
3078 long lrc;
3079 struct statsContext context;
3080
3081 if (NULL == pAdapter)
3082 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303083 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003084 return VOS_STATUS_E_FAULT;
3085 }
3086
3087 init_completion(&context.completion);
3088 context.pAdapter = pAdapter;
3089 context.magic = STATS_CONTEXT_MAGIC;
3090 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3091 eCSR_HDD,
3092 SME_GLOBAL_CLASSA_STATS,
3093 hdd_GetClassA_statisticsCB,
3094 0, // not periodic
3095 FALSE, //non-cached results
3096 staid,
3097 &context);
3098 if (eHAL_STATUS_SUCCESS != hstatus)
3099 {
3100 hddLog(VOS_TRACE_LEVEL_ERROR,
3101 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003102 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 }
3104 else
3105 {
3106 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3107 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 if (lrc <= 0)
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR,
3111 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003112 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003113 }
3114 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003115
3116 /* either we never sent a request, we sent a request and received a
3117 response or we sent a request and timed out. if we never sent a
3118 request or if we sent a request and got a response, we want to
3119 clear the magic out of paranoia. if we timed out there is a
3120 race condition such that the callback function could be
3121 executing at the same time we are. of primary concern is if the
3122 callback function had already verified the "magic" but had not
3123 yet set the completion variable when a timeout occurred. we
3124 serialize these activities by invalidating the magic while
3125 holding a shared spinlock which will cause us to block if the
3126 callback is currently executing */
3127 spin_lock(&hdd_context_lock);
3128 context.magic = 0;
3129 spin_unlock(&hdd_context_lock);
3130
Jeff Johnson295189b2012-06-20 16:38:30 -07003131 return VOS_STATUS_SUCCESS;
3132}
3133
3134int iw_get_softap_linkspeed(struct net_device *dev,
3135 struct iw_request_info *info,
3136 union iwreq_data *wrqu,
3137 char *extra)
3138
3139{
3140 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303141 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003142 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003143 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303144 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003145 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303146 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003148 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303149 int rc, valid;
3150
3151 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3152
3153 valid = wlan_hdd_validate_context(pHddCtx);
3154
3155 if (0 != valid)
3156 {
3157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3158 return valid;
3159 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003160
Arif Hussain6d2a3322013-11-17 19:50:10 -08003161 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003162
3163 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003164 {
Arif Hussaina9571842014-01-15 16:43:41 -08003165 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3166 if (NULL == pmacAddress) {
3167 hddLog(LOG1, "unable to allocate memory");
3168 return -ENOMEM;
3169 }
3170 if (copy_from_user((void *)pmacAddress,
3171 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3172 {
3173 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3174 kfree(pmacAddress);
3175 return -EFAULT;
3176 }
3177 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3178
3179 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003180 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003181
3182 if (!VOS_IS_STATUS_SUCCESS(status ))
3183 {
3184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3185 }
Arif Hussained667642013-10-27 23:01:14 -07003186 }
Kiet Lam61589852013-09-19 17:10:58 +05303187 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303188 * link speed for first connected client will be returned.
3189 */
Arif Hussaina9571842014-01-15 16:43:41 -08003190 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303191 {
3192 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3193 }
3194 else
3195 {
3196 status = hdd_softap_GetStaId(pHostapdAdapter,
3197 (v_MACADDR_t *)macAddress, (void *)(&staId));
3198 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003199
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303200 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003201 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003203 link_speed = 0;
3204 }
3205 else
3206 {
3207 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303208
Jeff Johnson295189b2012-06-20 16:38:30 -07003209 if (!VOS_IS_STATUS_SUCCESS(status ))
3210 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003212 return -EINVAL;
3213 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303214
3215 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3216 staId, &link_speed);
3217
3218 link_speed = link_speed / 10;
3219
3220 if (0 == link_speed)
3221 {
3222 /* The linkspeed returned by HAL is in units of 500kbps.
3223 * converting it to mbps.
3224 * This is required to support legacy firmware which does
3225 * not return link capacity.
3226 */
3227 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 }
3230
3231 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003232 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303233
Jeff Johnson295189b2012-06-20 16:38:30 -07003234 if ((rc < 0) || (rc >= len))
3235 {
3236 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303237 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003238 return -EIO;
3239 }
3240
3241 return 0;
3242}
3243
3244static const iw_handler hostapd_handler[] =
3245{
3246 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3247 (iw_handler) NULL, /* SIOCGIWNAME */
3248 (iw_handler) NULL, /* SIOCSIWNWID */
3249 (iw_handler) NULL, /* SIOCGIWNWID */
3250 (iw_handler) NULL, /* SIOCSIWFREQ */
3251 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3252 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303253 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003254 (iw_handler) NULL, /* SIOCSIWSENS */
3255 (iw_handler) NULL, /* SIOCGIWSENS */
3256 (iw_handler) NULL, /* SIOCSIWRANGE */
3257 (iw_handler) NULL, /* SIOCGIWRANGE */
3258 (iw_handler) NULL, /* SIOCSIWPRIV */
3259 (iw_handler) NULL, /* SIOCGIWPRIV */
3260 (iw_handler) NULL, /* SIOCSIWSTATS */
3261 (iw_handler) NULL, /* SIOCGIWSTATS */
3262 (iw_handler) NULL, /* SIOCSIWSPY */
3263 (iw_handler) NULL, /* SIOCGIWSPY */
3264 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3265 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3266 (iw_handler) NULL, /* SIOCSIWAP */
3267 (iw_handler) NULL, /* SIOCGIWAP */
3268 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3269 (iw_handler) NULL, /* SIOCGIWAPLIST */
3270 (iw_handler) NULL, /* SIOCSIWSCAN */
3271 (iw_handler) NULL, /* SIOCGIWSCAN */
3272 (iw_handler) NULL, /* SIOCSIWESSID */
3273 (iw_handler) NULL, /* SIOCGIWESSID */
3274 (iw_handler) NULL, /* SIOCSIWNICKN */
3275 (iw_handler) NULL, /* SIOCGIWNICKN */
3276 (iw_handler) NULL, /* -- hole -- */
3277 (iw_handler) NULL, /* -- hole -- */
3278 (iw_handler) NULL, /* SIOCSIWRATE */
3279 (iw_handler) NULL, /* SIOCGIWRATE */
3280 (iw_handler) NULL, /* SIOCSIWRTS */
3281 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3282 (iw_handler) NULL, /* SIOCSIWFRAG */
3283 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3284 (iw_handler) NULL, /* SIOCSIWTXPOW */
3285 (iw_handler) NULL, /* SIOCGIWTXPOW */
3286 (iw_handler) NULL, /* SIOCSIWRETRY */
3287 (iw_handler) NULL, /* SIOCGIWRETRY */
3288 (iw_handler) NULL, /* SIOCSIWENCODE */
3289 (iw_handler) NULL, /* SIOCGIWENCODE */
3290 (iw_handler) NULL, /* SIOCSIWPOWER */
3291 (iw_handler) NULL, /* SIOCGIWPOWER */
3292 (iw_handler) NULL, /* -- hole -- */
3293 (iw_handler) NULL, /* -- hole -- */
3294 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3295 (iw_handler) NULL, /* SIOCGIWGENIE */
3296 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3297 (iw_handler) NULL, /* SIOCGIWAUTH */
3298 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3299 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3300 (iw_handler) NULL, /* SIOCSIWPMKSA */
3301};
3302
Jeff Johnson224f3702014-03-26 11:09:47 -07003303/*
3304 * Note that the following ioctls were defined with semantics which
3305 * cannot be handled by the "iwpriv" userspace application and hence
3306 * they are not included in the hostapd_private_args array
3307 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3308 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003309
3310static const struct iw_priv_args hostapd_private_args[] = {
3311 { QCSAP_IOCTL_SETPARAM,
3312 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3313 { QCSAP_IOCTL_SETPARAM,
3314 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3315 { QCSAP_PARAM_MAX_ASSOC,
3316 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3317 { QCSAP_PARAM_HIDE_SSID,
3318 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003319 { QCSAP_PARAM_SET_MC_RATE,
3320 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003321 { QCSAP_IOCTL_GETPARAM,
3322 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3323 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3324 { QCSAP_IOCTL_GETPARAM, 0,
3325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3326 { QCSAP_PARAM_MAX_ASSOC, 0,
3327 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003328 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3329 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3330 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3331 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303332 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3333 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
3335 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
3336 { QCSAP_PARAM_CLR_ACL, 0,
3337 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3338 { QCSAP_PARAM_ACL_MODE,
3339 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003340 { QCSAP_IOCTL_SETMLME,
3341 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
3342 { QCSAP_IOCTL_GET_STAWPAIE,
3343 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3344 { QCSAP_IOCTL_SETWPAIE,
3345 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3346 { QCSAP_IOCTL_STOPBSS,
3347 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3348 { QCSAP_IOCTL_VERSION, 0,
3349 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003350 { QCSAP_IOCTL_GET_STA_INFO, 0,
3351 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003352 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003353 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003354 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003355 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003356 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003357 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
3358 { QCSAP_IOCTL_AP_STATS,
3359 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
3360 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3361 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303362 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003363
3364 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3365 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3366 /* handlers for sub-ioctl */
3367 { WE_SET_WLAN_DBG,
3368 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3369 0,
3370 "setwlandbg" },
3371
3372 /* handlers for main ioctl */
3373 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3374 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3375 0,
3376 "" },
3377
3378 /* handlers for sub-ioctl */
3379 { WE_LOG_DUMP_CMD,
3380 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3381 0,
3382 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003383 { WE_P2P_NOA_CMD,
3384 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3385 0,
3386 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003387 /* handlers for sub ioctl */
3388 {
3389 WE_MCC_CONFIG_CREDENTIAL,
3390 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3391 0,
3392 "setMccCrdnl" },
3393
3394 /* handlers for sub ioctl */
3395 {
3396 WE_MCC_CONFIG_PARAMS,
3397 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3398 0,
3399 "setMccConfig" },
3400
Jeff Johnson295189b2012-06-20 16:38:30 -07003401 /* handlers for main ioctl */
3402 { QCSAP_IOCTL_MODIFY_ACL,
3403 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3404 0,
3405 "modify_acl" },
3406
3407 /* handlers for main ioctl */
3408 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3409 0,
3410 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3411 "getChannelList" },
3412
Jeff Johnsone7245742012-09-05 17:12:55 -07003413 /* handlers for main ioctl */
3414 { QCSAP_IOCTL_SET_TX_POWER,
3415 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3416 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303417 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003418
3419 /* handlers for main ioctl */
3420 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3421 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3422 0,
3423 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303424
3425 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3426 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3427 0,
3428 "dataSnapshot" },
3429
3430 /* handlers for main ioctl */
3431 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3432 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3433 0,
3434 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003435};
Jeff Johnsone7245742012-09-05 17:12:55 -07003436
Jeff Johnson295189b2012-06-20 16:38:30 -07003437static const iw_handler hostapd_private[] = {
3438 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3439 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07003440 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
3441 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3442 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3443 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3444 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3445 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3446 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3447 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3448 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3449 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3450 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3451 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3452 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3453 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3454 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003455 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003456 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3457 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003458 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303459 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303460 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003461};
3462const struct iw_handler_def hostapd_handler_def = {
3463 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3464 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3465 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3466 .standard = (iw_handler *)hostapd_handler,
3467 .private = (iw_handler *)hostapd_private,
3468 .private_args = hostapd_private_args,
3469 .get_wireless_stats = NULL,
3470};
3471#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3472struct net_device_ops net_ops_struct = {
3473 .ndo_open = hdd_hostapd_open,
3474 .ndo_stop = hdd_hostapd_stop,
3475 .ndo_uninit = hdd_hostapd_uninit,
3476 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3477 .ndo_tx_timeout = hdd_softap_tx_timeout,
3478 .ndo_get_stats = hdd_softap_stats,
3479 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3480 .ndo_do_ioctl = hdd_hostapd_ioctl,
3481 .ndo_change_mtu = hdd_hostapd_change_mtu,
3482 .ndo_select_queue = hdd_hostapd_select_queue,
3483 };
3484#endif
3485
3486int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3487{
3488 return VOS_STATUS_SUCCESS;
3489}
3490
3491void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3492{
3493#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3494 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3495#else
3496 pWlanHostapdDev->open = hdd_hostapd_open;
3497 pWlanHostapdDev->stop = hdd_hostapd_stop;
3498 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3499 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3500 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3501 pWlanHostapdDev->get_stats = hdd_softap_stats;
3502 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3503 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3504#endif
3505}
3506
3507VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
3508{
3509 hdd_hostapd_state_t * phostapdBuf;
3510 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003511 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003512 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08003513#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08003514 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
3515 v_U16_t unsafeChannelCount;
3516#endif /* FEATURE_WLAN_CH_AVOID */
3517
Jeff Johnson295189b2012-06-20 16:38:30 -07003518 ENTER();
3519 // Allocate the Wireless Extensions state structure
3520 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
3521
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003522 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
3523
Leo Chang0b0e45a2013-12-15 15:18:55 -08003524#ifdef FEATURE_WLAN_CH_AVOID
3525 /* Get unsafe cahnnel list from cached location */
3526 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
3527 sizeof(unsafeChannelList),
3528 &unsafeChannelCount);
3529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3530 "%s : Unsafe Channel count %d",
3531 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05303532 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08003533 unsafeChannelList,
3534 unsafeChannelCount);
3535#endif /* FEATURE_WLAN_CH_AVOID */
3536
Jeff Johnson295189b2012-06-20 16:38:30 -07003537 // Zero the memory. This zeros the profile structure.
3538 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
3539
3540 // Set up the pointer to the Wireless Extensions state structure
3541 // NOP
3542 status = hdd_set_hostapd(pAdapter);
3543 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003545 return status;
3546 }
3547
3548 status = vos_event_init(&phostapdBuf->vosEvent);
3549 if (!VOS_IS_STATUS_SUCCESS(status))
3550 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003552 return status;
3553 }
3554
3555 init_completion(&pAdapter->session_close_comp_var);
3556 init_completion(&pAdapter->session_open_comp_var);
3557
3558 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
3559
3560 // Register as a wireless device
3561 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
3562
3563 //Initialize the data path module
3564 status = hdd_softap_init_tx_rx(pAdapter);
3565 if ( !VOS_IS_STATUS_SUCCESS( status ))
3566 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003567 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003568 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303569
3570 status = hdd_wmm_adapter_init( pAdapter );
3571 if (!VOS_IS_STATUS_SUCCESS(status))
3572 {
3573 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003574 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303575 status, status );
3576 goto error_wmm_init;
3577 }
3578
3579 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3580
Jeff Johnson295189b2012-06-20 16:38:30 -07003581 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303582
3583 return status;
3584
3585error_wmm_init:
3586 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003587 EXIT();
3588 return status;
3589}
3590
3591hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
3592{
3593 struct net_device *pWlanHostapdDev = NULL;
3594 hdd_adapter_t *pHostapdAdapter = NULL;
3595 v_CONTEXT_t pVosContext= NULL;
3596
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07003598
3599 if (pWlanHostapdDev != NULL)
3600 {
3601 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
3602
3603 //Init the net_device structure
3604 ether_setup(pWlanHostapdDev);
3605
3606 //Initialize the adapter context to zeros.
3607 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
3608 pHostapdAdapter->dev = pWlanHostapdDev;
3609 pHostapdAdapter->pHddCtx = pHddCtx;
3610 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3611
3612 //Get the Global VOSS context.
3613 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3614 //Save the adapter context in global context for future.
3615 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3616
3617 //Init the net_device structure
3618 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3619
3620 hdd_set_ap_ops( pHostapdAdapter->dev );
3621
Jeff Johnson295189b2012-06-20 16:38:30 -07003622 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3623 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3624
3625 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3626 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3627
3628 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003629 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3630 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3631 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3632 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3634 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05303635 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07003636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3637 init_completion(&pHostapdAdapter->offchannel_tx_event);
3638#endif
3639
Jeff Johnson295189b2012-06-20 16:38:30 -07003640 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3641 }
3642 return pHostapdAdapter;
3643}
3644
3645VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3646{
3647 struct net_device *dev = pAdapter->dev;
3648 VOS_STATUS status = VOS_STATUS_SUCCESS;
3649
3650 ENTER();
3651
3652 if( rtnl_lock_held )
3653 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003654 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003655 if( dev_alloc_name(dev, dev->name) < 0 )
3656 {
3657 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3658 return VOS_STATUS_E_FAILURE;
3659 }
3660 }
3661 if (register_netdevice(dev))
3662 {
3663 hddLog(VOS_TRACE_LEVEL_FATAL,
3664 "%s:Failed:register_netdevice", __func__);
3665 return VOS_STATUS_E_FAILURE;
3666 }
3667 }
3668 else
3669 {
3670 if (register_netdev(dev))
3671 {
3672 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3673 return VOS_STATUS_E_FAILURE;
3674 }
3675 }
3676 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3677
3678 EXIT();
3679 return status;
3680}
3681
3682VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3683{
3684 ENTER();
3685
3686 hdd_softap_deinit_tx_rx(pAdapter);
3687
3688 /* if we are being called during driver unload, then the dev has already
3689 been invalidated. if we are being called at other times, then we can
3690 detatch the wireless device handlers */
3691 if (pAdapter->dev)
3692 {
3693 pAdapter->dev->wireless_handlers = NULL;
3694 }
3695 EXIT();
3696 return 0;
3697}