blob: 70322cc40b8eb253f6efe4f2a713c407239199d9 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, 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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**========================================================================
43
44 \file wlan_hdd_hostapd.c
45 \brief WLAN Host Device Driver implementation
46
47 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
48
49 Qualcomm Confidential and Proprietary.
50
51 ========================================================================*/
52/**=========================================================================
53 EDIT HISTORY FOR FILE
54
55
56 This section contains comments describing changes made to the module.
57 Notice that changes are listed in reverse chronological order.
58
59 $Header:$ $DateTime: $ $Author: $
60
61
62 when who what, where, why
63 -------- --- --------------------------------------------------------
64 04/5/09 Shailender Created module.
65 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
66 ==========================================================================*/
67/*--------------------------------------------------------------------------
68 Include Files
69 ------------------------------------------------------------------------*/
70
71#include <linux/version.h>
72#include <linux/module.h>
73#include <linux/kernel.h>
74#include <linux/init.h>
75#include <linux/wireless.h>
76#include <linux/semaphore.h>
77#include <vos_api.h>
78#include <vos_sched.h>
79#include <linux/etherdevice.h>
80#include <wlan_hdd_includes.h>
81#include <qc_sap_ioctl.h>
82#include <wlan_hdd_hostapd.h>
83#include <sapApi.h>
84#include <sapInternal.h>
85#include <wlan_qct_tl.h>
86#include <wlan_hdd_softap_tx_rx.h>
87#include <wlan_hdd_main.h>
88#include <linux/netdevice.h>
89#include <linux/mmc/sdio_func.h>
90#include "wlan_nlink_common.h"
91#include "wlan_btc_svc.h"
92#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070093#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070094#include "cfgApi.h"
95#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070096
Leo Chang0b0e45a2013-12-15 15:18:55 -080097#ifdef FEATURE_WLAN_CH_AVOID
98#include "wcnss_wlan.h"
99#endif /* FEATURE_WLAN_CH_AVOID */
100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#define IS_UP(_dev) \
102 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
103#define IS_UP_AUTO(_ic) \
104 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
105#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -0700106#define WE_GET_STA_INFO_SIZE 30
107/* WEXT limition: MAX allowed buf len for any *
108 * IW_PRIV_TYPE_CHAR is 2Kbytes *
109 */
110#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700113
Leo Chang0b0e45a2013-12-15 15:18:55 -0800114#ifdef FEATURE_WLAN_CH_AVOID
115/* Channle/Freqency table */
116extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
117safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
118{
119 /*CH , SAFE, default safe */
120 {1 , VOS_TRUE}, //RF_CHAN_1,
121 {2 , VOS_TRUE}, //RF_CHAN_2,
122 {3 , VOS_TRUE}, //RF_CHAN_3,
123 {4 , VOS_TRUE}, //RF_CHAN_4,
124 {5 , VOS_TRUE}, //RF_CHAN_5,
125 {6 , VOS_TRUE}, //RF_CHAN_6,
126 {7 , VOS_TRUE}, //RF_CHAN_7,
127 {8 , VOS_TRUE}, //RF_CHAN_8,
128 {9 , VOS_TRUE}, //RF_CHAN_9,
129 {10 , VOS_TRUE}, //RF_CHAN_10,
130 {11 , VOS_TRUE}, //RF_CHAN_11,
131 {12 , VOS_TRUE}, //RF_CHAN_12,
132 {13 , VOS_TRUE}, //RF_CHAN_13,
133 {14 , VOS_TRUE}, //RF_CHAN_14,
134 {240, VOS_TRUE}, //RF_CHAN_240,
135 {244, VOS_TRUE}, //RF_CHAN_244,
136 {248, VOS_TRUE}, //RF_CHAN_248,
137 {252, VOS_TRUE}, //RF_CHAN_252,
138 {208, VOS_TRUE}, //RF_CHAN_208,
139 {212, VOS_TRUE}, //RF_CHAN_212,
140 {216, VOS_TRUE}, //RF_CHAN_216,
141 {36 , VOS_TRUE}, //RF_CHAN_36,
142 {40 , VOS_TRUE}, //RF_CHAN_40,
143 {44 , VOS_TRUE}, //RF_CHAN_44,
144 {48 , VOS_TRUE}, //RF_CHAN_48,
145 {52 , VOS_TRUE}, //RF_CHAN_52,
146 {56 , VOS_TRUE}, //RF_CHAN_56,
147 {60 , VOS_TRUE}, //RF_CHAN_60,
148 {64 , VOS_TRUE}, //RF_CHAN_64,
149 {100, VOS_TRUE}, //RF_CHAN_100,
150 {104, VOS_TRUE}, //RF_CHAN_104,
151 {108, VOS_TRUE}, //RF_CHAN_108,
152 {112, VOS_TRUE}, //RF_CHAN_112,
153 {116, VOS_TRUE}, //RF_CHAN_116,
154 {120, VOS_TRUE}, //RF_CHAN_120,
155 {124, VOS_TRUE}, //RF_CHAN_124,
156 {128, VOS_TRUE}, //RF_CHAN_128,
157 {132, VOS_TRUE}, //RF_CHAN_132,
158 {136, VOS_TRUE}, //RF_CHAN_136,
159 {140, VOS_TRUE}, //RF_CHAN_140,
160 {149, VOS_TRUE}, //RF_CHAN_149,
161 {153, VOS_TRUE}, //RF_CHAN_153,
162 {157, VOS_TRUE}, //RF_CHAN_157,
163 {161, VOS_TRUE}, //RF_CHAN_161,
164 {165, VOS_TRUE}, //RF_CHAN_165,
165};
166#endif /* FEATURE_WLAN_CH_AVOID */
167
Jeff Johnson295189b2012-06-20 16:38:30 -0700168/*---------------------------------------------------------------------------
169 * Function definitions
170 *-------------------------------------------------------------------------*/
171/**---------------------------------------------------------------------------
172
173 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
174
175 This is called in response to ifconfig up
176
177 \param - dev Pointer to net_device structure
178
179 \return - 0 for success non-zero for failure
180
181 --------------------------------------------------------------------------*/
182int hdd_hostapd_open (struct net_device *dev)
183{
184 ENTER();
185
186 //Turn ON carrier state
187 netif_carrier_on(dev);
188 //Enable all Tx queues
189 netif_tx_start_all_queues(dev);
190
191 EXIT();
192 return 0;
193}
194/**---------------------------------------------------------------------------
195
196 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
197
198 This is called in response to ifconfig down
199
200 \param - dev Pointer to net_device structure
201
202 \return - 0 for success non-zero for failure
203
204 --------------------------------------------------------------------------*/
205int hdd_hostapd_stop (struct net_device *dev)
206{
207 ENTER();
208
209 //Stop all tx queues
210 netif_tx_disable(dev);
211
212 //Turn OFF carrier state
213 netif_carrier_off(dev);
214
215 EXIT();
216 return 0;
217}
218/**---------------------------------------------------------------------------
219
220 \brief hdd_hostapd_uninit() - HDD uninit function
221
222 This is called during the netdev unregister to uninitialize all data
223associated with the device
224
225 \param - dev Pointer to net_device structure
226
227 \return - void
228
229 --------------------------------------------------------------------------*/
230static void hdd_hostapd_uninit (struct net_device *dev)
231{
232 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
233
234 ENTER();
235
236 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
237 {
238 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
239
240 /* after uninit our adapter structure will no longer be valid */
241 pHostapdAdapter->dev = NULL;
242 }
243
244 EXIT();
245}
246
247
248/**============================================================================
249 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
250 transmitting packets. There are 2 versions of this function. One that uses
251 locked queue and other that uses lockless queues. Both have been retained to
252 do some performance testing
253 @param skb : [in] pointer to OS packet (sk_buff)
254 @param dev : [in] pointer to Libra network device
255
256 @return : NET_XMIT_DROP if packets are dropped
257 : NET_XMIT_SUCCESS if packet is enqueued succesfully
258 ===========================================================================*/
259int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
260{
261 return 0;
262}
263int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
264{
265 return 0;
266}
267
268int hdd_hostapd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
269{
270 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
271 hdd_priv_data_t priv_data;
272 tANI_U8 *command = NULL;
273 int ret = 0;
274
275 if (NULL == pAdapter)
276 {
277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700278 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 ret = -ENODEV;
280 goto exit;
281 }
282
Jeff Johnsone7245742012-09-05 17:12:55 -0700283 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 {
285 ret = -EINVAL;
286 goto exit;
287 }
288
289 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
290 {
291 ret = -EFAULT;
292 goto exit;
293 }
294
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800295 if (priv_data.total_len <= 0 ||
296 priv_data.total_len == INT_MAX)
297 {
298 /* below we allocate one more byte for command buffer.
299 * To avoid addition overflow total_len should be
300 * smaller than INT_MAX. */
301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800302 "%s: integer out of range", __func__);
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800303 ret = -EFAULT;
304 goto exit;
305 }
306
307 command = kmalloc((priv_data.total_len + 1), GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 if (!command)
309 {
310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800311 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 ret = -ENOMEM;
313 goto exit;
314 }
315
316 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
317 {
318 ret = -EFAULT;
319 goto exit;
320 }
321
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800322 command[priv_data.total_len] = '\0';
323
Jeff Johnson295189b2012-06-20 16:38:30 -0700324 if ((SIOCDEVPRIVATE + 1) == cmd)
325 {
Agarwal Ashish8518d5d2013-12-05 20:16:44 +0530326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
328
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 if(strncmp(command, "P2P_SET_NOA", 11) == 0 )
330 {
331 hdd_setP2pNoa(dev, command);
332 }
333 else if( strncmp(command, "P2P_SET_PS", 10) == 0 )
334 {
335 hdd_setP2pOpps(dev, command);
336 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700337
338 /*
339 command should be a string having format
340 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
341 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700342 if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700343 {
344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700345 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700346
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -0800347 ret = sapSetPreferredChannel(command);
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700348 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 }
350exit:
351 if (command)
352 {
353 kfree(command);
354 }
355 return ret;
356}
357
358/**---------------------------------------------------------------------------
359
360 \brief hdd_hostapd_set_mac_address() -
361 This function sets the user specified mac address using
362 the command ifconfig wlanX hw ether <mac adress>.
363
364 \param - dev - Pointer to the net device.
365 - addr - Pointer to the sockaddr.
366 \return - 0 for success, non zero for failure
367
368 --------------------------------------------------------------------------*/
369
370static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
371{
372 struct sockaddr *psta_mac_addr = addr;
373 ENTER();
374 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
375 EXIT();
376 return 0;
377}
378void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
379{
380 struct net_device *dev = (struct net_device *)usrDataForCallback;
381 v_BYTE_t we_custom_event[64];
382 union iwreq_data wrqu;
383#ifdef DISABLE_CONCURRENCY_AUTOSAVE
384 VOS_STATUS vos_status;
385 hdd_adapter_t *pHostapdAdapter;
386 hdd_ap_ctx_t *pHddApCtx;
387#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
388
389 /* event_name space-delimiter driver_module_name */
390 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
391 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
392 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
393
394 ENTER();
395
396#ifdef DISABLE_CONCURRENCY_AUTOSAVE
397 if (vos_concurrent_sessions_running())
398 {
399 /*
400 This timer routine is going to be called only when AP
401 persona is up.
402 If there are concurrent sessions running we do not want
403 to shut down the Bss.Instead we run the timer again so
404 that if Autosave is enabled next time and other session
405 was down only then we bring down AP
406 */
407 pHostapdAdapter = netdev_priv(dev);
408 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
409 vos_status = vos_timer_start(
410 &pHddApCtx->hdd_ap_inactivity_timer,
411 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
412 * 1000);
413 if (!VOS_IS_STATUS_SUCCESS(vos_status))
414 {
415 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
416 }
417 EXIT();
418 return;
419 }
420#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
421 memset(&we_custom_event, '\0', sizeof(we_custom_event));
422 memcpy(&we_custom_event, autoShutEvent, event_len);
423
424 memset(&wrqu, 0, sizeof(wrqu));
425 wrqu.data.length = event_len;
426
427 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
428 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
429
430 EXIT();
431}
432
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800433VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
434{
435 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
436 ptSapContext pSapCtx = NULL;
437 eHalStatus halStatus = eHAL_STATUS_FAILURE;
438 v_PVOID_t hHal = NULL;
439
440 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
441 "%s: UPDATE Beacon Params", __func__);
442
443 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
444 pSapCtx = VOS_GET_SAP_CB(pVosContext);
445 if ( NULL == pSapCtx )
446 {
447 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
448 "%s: Invalid SAP pointer from pvosGCtx", __func__);
449 return VOS_STATUS_E_FAULT;
450 }
451
452 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
453 if ( NULL == hHal ){
454 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
455 "%s: Invalid HAL pointer from pvosGCtx", __func__);
456 return VOS_STATUS_E_FAULT;
457 }
458 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
459 if(halStatus == eHAL_STATUS_FAILURE ){
460 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
461 "%s: Failed to update Beacon Params", __func__);
462 return VOS_STATUS_E_FAILURE;
463 }
464 }
465 return VOS_STATUS_SUCCESS;
466}
467
468void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
469{
470 v_U8_t staId = 0;
471 struct net_device *dev;
472 dev = (struct net_device *)usrDataForCallback;
473
Arif Hussain6d2a3322013-11-17 19:50:10 -0800474 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800475 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
476 {
477 if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
478 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
479 {
480 //Disconnect all the stations
481 hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
482 }
483 }
484}
485
486static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
487{
488 struct net_device *dev;
489 VOS_STATUS status = VOS_STATUS_SUCCESS;
490 dev = (struct net_device *)usrDataForCallback;
491 ENTER();
492 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
493 {
494 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
495 {
496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
497 }
498 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
499 }
500 EXIT();
501 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
502}
Jeff Johnson295189b2012-06-20 16:38:30 -0700503
504VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
505{
506 hdd_adapter_t *pHostapdAdapter;
507 hdd_ap_ctx_t *pHddApCtx;
508 hdd_hostapd_state_t *pHostapdState;
509 struct net_device *dev;
510 eSapHddEvent sapEvent;
511 union iwreq_data wrqu;
512 v_BYTE_t *we_custom_event_generic = NULL;
513 int we_event = 0;
514 int i = 0;
515 v_U8_t staId;
516 VOS_STATUS vos_status;
517 v_BOOL_t bWPSState;
518 v_BOOL_t bApActive = FALSE;
519 v_BOOL_t bAuthRequired = TRUE;
520 tpSap_AssocMacAddr pAssocStasArray = NULL;
521 char unknownSTAEvent[IW_CUSTOM_MAX+1];
522 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
523 v_BYTE_t we_custom_start_event[64];
524 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800525 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800526 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700527 struct iw_michaelmicfailure msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700528
529 dev = (struct net_device *)usrDataForCallback;
530 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530531
532 if ((NULL == pHostapdAdapter) ||
533 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
534 {
535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
536 "invalid adapter or adapter has invalid magic");
537 return eHAL_STATUS_FAILURE;
538 }
539
Jeff Johnson295189b2012-06-20 16:38:30 -0700540 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
541 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
542 sapEvent = pSapEvent->sapHddEventCode;
543 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800544 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700545
546 switch(sapEvent)
547 {
548 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800549 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700550 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
551 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
552 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
553
554 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
555 vos_status = vos_event_set(&pHostapdState->vosEvent);
556
557 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
558 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700560 goto stopbss;
561 }
562 else
563 {
564 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
565 //@@@ need wep logic here to set privacy bit
566 hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
567 }
568
569 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
570 {
571 // AP Inactivity timer init and start
572 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
573 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
574 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800575 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700576
577 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
578 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800579 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700580
581 }
582 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
583 pHostapdState->bssState = BSS_START;
584
585 // Send current operating channel of SoftAP to BTC-ES
586 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
587
Jeff Johnson295189b2012-06-20 16:38:30 -0700588 //Check if there is any group key pending to set.
589 if( pHddApCtx->groupKey.keyLength )
590 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700591 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700592 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
593 &pHddApCtx->groupKey ) )
594 {
595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
596 "%s: WLANSAP_SetKeySta failed", __func__);
597 }
598 pHddApCtx->groupKey.keyLength = 0;
599 }
600 else if ( pHddApCtx->wepKey[0].keyLength )
601 {
602 int i=0;
603 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
604 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700605 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700606 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
607 &pHddApCtx->wepKey[i] ) )
608 {
609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
611 }
612 pHddApCtx->wepKey[i].keyLength = 0;
613 }
614 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700615 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
616 startBssEvent = "SOFTAP.enabled";
617 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
618 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
619 memset(&wrqu, 0, sizeof(wrqu));
620 wrqu.data.length = strlen(startBssEvent);
621 we_event = IWEVCUSTOM;
622 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700623 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 break; //Event will be sent after Switch-Case stmt
625
626 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800627 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700628 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
629
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700630 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700631 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700632
Jeff Johnson295189b2012-06-20 16:38:30 -0700633 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 goto stopbss;
635 case eSAP_STA_SET_KEY_EVENT:
636 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800637 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
639 return VOS_STATUS_SUCCESS;
640 case eSAP_STA_DEL_KEY_EVENT:
641 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800642 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700643 return VOS_STATUS_SUCCESS;
644 case eSAP_STA_MIC_FAILURE_EVENT:
645 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700646 memset(&msg, '\0', sizeof(msg));
647 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800648 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800649 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700650 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700651 msg.flags = IW_MICFAILURE_GROUP;
652 else
653 msg.flags = IW_MICFAILURE_PAIRWISE;
654 memset(&wrqu, 0, sizeof(wrqu));
655 wrqu.data.length = sizeof(msg);
656 we_event = IWEVMICHAELMICFAILURE;
657 we_custom_event_generic = (v_BYTE_t *)&msg;
658 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 /* inform mic failure to nl80211 */
660 cfg80211_michael_mic_failure(dev,
661 pSapEvent->sapevt.
662 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700663 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 NL80211_KEYTYPE_GROUP :
665 NL80211_KEYTYPE_PAIRWISE),
666 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
667 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
668 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700669 break;
670
671 case eSAP_STA_ASSOC_EVENT:
672 case eSAP_STA_REASSOC_EVENT:
673 wrqu.addr.sa_family = ARPHRD_ETHER;
674 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800675 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800676 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 we_event = IWEVREGISTERED;
678
679 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
680
681 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
682 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
683 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
684 {
685 bAuthRequired = FALSE;
686 }
687
688 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
689 {
690 hdd_softap_RegisterSTA( pHostapdAdapter,
691 TRUE,
692 pHddApCtx->uPrivacy,
693 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
694 0,
695 0,
696 (v_MACADDR_t *)wrqu.addr.sa_data,
697 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
698 }
699 else
700 {
701 hdd_softap_RegisterSTA( pHostapdAdapter,
702 FALSE,
703 pHddApCtx->uPrivacy,
704 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
705 0,
706 0,
707 (v_MACADDR_t *)wrqu.addr.sa_data,
708 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
Amar Singhal6144c002013-05-03 16:11:42 -0700709 }
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 // Stop AP inactivity timer
712 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
713 {
714 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
715 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800716 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700717 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800718#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800719 if (wake_lock_active(&pHddCtx->sap_wake_lock))
720 {
721 wake_unlock(&pHddCtx->sap_wake_lock);
722 }
Amar Singhal6144c002013-05-03 16:11:42 -0700723 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
726 {
727 struct station_info staInfo;
728 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
729
730 memset(&staInfo, 0, sizeof(staInfo));
731 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
732 {
733 staInfo.assoc_req_ies =
734 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
735 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700737 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
738#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700739 cfg80211_new_sta(dev,
740 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
741 &staInfo, GFP_KERNEL);
742 }
743 else
744 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800745 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 }
747 }
748#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800749 pScanInfo = &pHddCtx->scan_info;
750 // Lets do abort scan to ensure smooth authentication for client
751 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
752 {
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +0530753 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800754 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700755
756 break;
757 case eSAP_STA_DISASSOC_EVENT:
758 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800759 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800760 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700761 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
762 hddLog(LOG1," User initiated disassociation");
763 else
764 hddLog(LOG1," MAC initiated disassociation");
765 we_event = IWEVEXPIRED;
766 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
767 if (!VOS_IS_STATUS_SUCCESS(vos_status))
768 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700769 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 -0700770 return VOS_STATUS_E_FAILURE;
771 }
772 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
773
774 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
775 {
776 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
777 // Start AP inactivity timer if no stations associated with it
778 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
779 {
780 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
781 {
782 bApActive = TRUE;
783 break;
784 }
785 }
786 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
787
788 if (bApActive == FALSE)
789 {
790 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
791 {
792 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
793 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800794 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 }
796 else
797 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
798 }
799 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
801 cfg80211_del_sta(dev,
802 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
803 GFP_KERNEL);
804#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800805 //Update the beacon Interval if it is P2P GO
806 hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 break;
808 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
809 {
810 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
811 union iwreq_data wreq;
812
813 down(&pHddApCtx->semWpsPBCOverlapInd);
814 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
815
816 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
817 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
818
819 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800820 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700821 memset(&wreq, 0, sizeof(wreq));
822 wreq.data.length = strlen(message); // This is length of message
823 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
824
825 return VOS_STATUS_SUCCESS;
826 }
827 case eSAP_ASSOC_STA_CALLBACK_EVENT:
828 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
829 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
830 { // List of associated stations
831 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
832 {
833 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
834 i+1,
835 pAssocStasArray->assocId,
836 pAssocStasArray->staId,
837 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
838 pAssocStasArray++;
839 }
840 }
841 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800842 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700843 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 case eSAP_INDICATE_MGMT_FRAME:
845 hdd_indicateMgmtFrame( pHostapdAdapter,
846 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
847 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
848 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530849 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700850 return VOS_STATUS_SUCCESS;
851 case eSAP_REMAIN_CHAN_READY:
852 hdd_remainChanReadyHandler( pHostapdAdapter );
853 return VOS_STATUS_SUCCESS;
854 case eSAP_SEND_ACTION_CNF:
855 hdd_sendActionCnf( pHostapdAdapter,
856 ( eSAP_STATUS_SUCCESS ==
857 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
858 TRUE : FALSE );
859 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700860 case eSAP_UNKNOWN_STA_JOIN:
861 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
862 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
863 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
864 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
865 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
866 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
867 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
868 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
869 wrqu.data.pointer = unknownSTAEvent;
870 wrqu.data.length = strlen(unknownSTAEvent);
871 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -0800872 hddLog(LOG1,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 break;
874
875 case eSAP_MAX_ASSOC_EXCEEDED:
876 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
877 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
878 " one or more devices to enable the new device connection",
879 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
880 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
881 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
882 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
883 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
884 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
885 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
886 wrqu.data.pointer = maxAssocExceededEvent;
887 wrqu.data.length = strlen(maxAssocExceededEvent);
888 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -0800889 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 break;
891 case eSAP_STA_ASSOC_IND:
892 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800893
894 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800895 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800896 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
897 return VOS_STATUS_SUCCESS;
898
899 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
900 hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
901 return VOS_STATUS_SUCCESS;
902
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800904 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -0700905 goto stopbss;
906 return VOS_STATUS_SUCCESS;
907 }
908 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
909 return VOS_STATUS_SUCCESS;
910
911stopbss :
912 {
913 v_BYTE_t we_custom_event[64];
914 char *stopBssEvent = "STOP-BSS.response";//17
915 int event_len = strlen(stopBssEvent);
916
917 hddLog(LOG1, FL("BSS stop status = %s"),
918 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
919 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
920
921 /* Change the BSS state now since, as we are shutting things down,
922 * we don't want interfaces to become re-enabled */
923 pHostapdState->bssState = BSS_STOP;
924
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +0530925 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
926 {
927 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
928 {
929 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
930 if (!VOS_IS_STATUS_SUCCESS(vos_status))
931 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
932 }
933
934 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
935 if (!VOS_IS_STATUS_SUCCESS(vos_status))
936 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
937 }
938
Jeff Johnson295189b2012-06-20 16:38:30 -0700939 /* Stop the pkts from n/w stack as we are going to free all of
940 * the TX WMM queues for all STAID's */
941 hdd_hostapd_stop(dev);
942
943 /* reclaim all resources allocated to the BSS */
944 hdd_softap_stop_bss(pHostapdAdapter);
945
Amar Singhal37e6f052013-03-05 16:16:54 -0800946 /* once the event is set, structure dev/pHostapdAdapter should
947 * not be touched since they are now subject to being deleted
948 * by another thread */
949 if (eSAP_STOP_BSS_EVENT == sapEvent)
950 vos_event_set(&pHostapdState->vosEvent);
951
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 /* notify userspace that the BSS has stopped */
953 memset(&we_custom_event, '\0', sizeof(we_custom_event));
954 memcpy(&we_custom_event, stopBssEvent, event_len);
955 memset(&wrqu, 0, sizeof(wrqu));
956 wrqu.data.length = event_len;
957 we_event = IWEVCUSTOM;
958 we_custom_event_generic = we_custom_event;
959 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700960 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700961 }
962 return VOS_STATUS_SUCCESS;
963}
964int hdd_softap_unpackIE(
965 tHalHandle halHandle,
966 eCsrEncryptionType *pEncryptType,
967 eCsrEncryptionType *mcEncryptType,
968 eCsrAuthType *pAuthType,
969 u_int16_t gen_ie_len,
970 u_int8_t *gen_ie )
971{
972 tDot11fIERSN dot11RSNIE;
973 tDot11fIEWPA dot11WPAIE;
974
975 tANI_U8 *pRsnIe;
976 tANI_U16 RSNIeLen;
977
978 if (NULL == halHandle)
979 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800980 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 return -EINVAL;
982 }
983
984 // Validity checks
985 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
986 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
987 return -EINVAL;
988 // Type check
989 if ( gen_ie[0] == DOT11F_EID_RSN)
990 {
991 // Validity checks
992 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
993 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
994 {
995 return VOS_STATUS_E_FAILURE;
996 }
997 // Skip past the EID byte and length byte
998 pRsnIe = gen_ie + 2;
999 RSNIeLen = gen_ie_len - 2;
1000 // Unpack the RSN IE
1001 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1002 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1003 pRsnIe,
1004 RSNIeLen,
1005 &dot11RSNIE);
1006 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001007 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001008 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001009 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001010 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 /*Here we have followed the apple base code,
1012 but probably I suspect we can do something different*/
1013 //dot11RSNIE.akm_suite_count
1014 // Just translate the FIRST one
1015 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1016 //dot11RSNIE.pwise_cipher_suite_count
1017 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1018 //dot11RSNIE.gp_cipher_suite_count
1019 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1020 // Set the PMKSA ID Cache for this interface
1021
1022 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1023 } else
1024 if (gen_ie[0] == DOT11F_EID_WPA)
1025 {
1026 // Validity checks
1027 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1028 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1029 {
1030 return VOS_STATUS_E_FAILURE;
1031 }
1032 // Skip past the EID byte and length byte - and four byte WiFi OUI
1033 pRsnIe = gen_ie + 2 + 4;
1034 RSNIeLen = gen_ie_len - (2 + 4);
1035 // Unpack the WPA IE
1036 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1037 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1038 pRsnIe,
1039 RSNIeLen,
1040 &dot11WPAIE);
1041 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001042 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001043 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001044 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001045 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 //dot11WPAIE.auth_suite_count
1047 // Just translate the FIRST one
1048 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1049 //dot11WPAIE.unicast_cipher_count
1050 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1051 //dot11WPAIE.unicast_cipher_count
1052 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
1053 }
1054 else
1055 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001056 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001057 return VOS_STATUS_E_FAILURE;
1058 }
1059 return VOS_STATUS_SUCCESS;
1060}
Leo Chang614d2072013-08-22 14:59:44 -07001061
Leo Chang0b0e45a2013-12-15 15:18:55 -08001062#ifdef FEATURE_WLAN_CH_AVOID
1063/**---------------------------------------------------------------------------
1064
1065 \brief hdd_hostapd_freq_to_chn() -
1066
1067 Input frequency translated into channel number
1068
1069 \param - freq input frequency with order of kHz
1070
1071 \return - corresponding channel number.
1072 incannot find correct channel number, return 0
1073
1074 --------------------------------------------------------------------------*/
1075v_U16_t hdd_hostapd_freq_to_chn
1076(
1077 v_U16_t freq
1078)
1079{
1080 int loop;
1081
1082 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1083 {
1084 if (rfChannels[loop].targetFreq == freq)
1085 {
1086 return rfChannels[loop].channelNum;
1087 }
1088 }
1089
1090 return (0);
1091}
1092
1093/*==========================================================================
1094 FUNCTION sapUpdateUnsafeChannelList
1095
1096 DESCRIPTION
1097 Function Undate unsafe channel list table
1098
1099 DEPENDENCIES
1100 NA.
1101
1102 PARAMETERS
1103
1104 IN
1105 pSapCtx : SAP context pointer, include unsafe channel list
1106
1107 RETURN VALUE
1108 NONE
1109============================================================================*/
1110void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1111 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1112{
1113 v_U16_t i, j;
1114
1115 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1116 sizeof(pHddCtx->unsafeChannelList));
1117 if (0 == unsafeChannelCount)
1118 {
1119 pHddCtx->unsafeChannelCount = 0;
1120 }
1121 else
1122 {
1123 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1124 unsafeChannelList,
1125 unsafeChannelCount * sizeof(tANI_U16));
1126 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1127 }
1128
1129 /* Flush, default set all channel safe */
1130 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1131 {
1132 safeChannels[i].isSafe = VOS_TRUE;
1133 }
1134
1135 /* Try to find unsafe channel */
1136 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1137 {
1138 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1139 {
1140 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1141 {
1142 /* Found unsafe channel, update it */
1143 safeChannels[j].isSafe = VOS_FALSE;
1144 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1145 "%s : CH %d is not safe",
1146 __func__, pHddCtx->unsafeChannelList[i]);
1147 break;
1148 }
1149 }
1150 }
1151
1152 return;
1153}
1154
1155/**---------------------------------------------------------------------------
1156
1157 \brief hdd_hostapd_ch_avoid_cb() -
1158
1159 Avoid channel notification from FW handler.
1160 FW will send un-safe channle list to avoid overwrapping.
1161 hostapd should not use notified channel
1162
1163 \param - pAdapter HDD adapter pointer
1164 indParam channel avoid notification parameter
1165
1166 \return - None
1167
1168 --------------------------------------------------------------------------*/
1169void hdd_hostapd_ch_avoid_cb
1170(
1171 void *pAdapter,
1172 void *indParam
1173)
1174{
1175 hdd_adapter_t *pHostapdAdapter = NULL;
1176 hdd_context_t *hddCtxt;
1177 tSirChAvoidIndType *chAvoidInd;
1178 v_U8_t rangeLoop;
1179 v_U16_t channelLoop;
1180 v_U16_t dupCheck;
1181 v_U16_t startChannel;
1182 v_U16_t endChannel;
1183 v_U16_t unsafeChannelCount = 0;
1184 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1185 v_CONTEXT_t pVosContext;
1186
1187 /* Basic sanity */
1188 if ((NULL == pAdapter) || (NULL == indParam))
1189 {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1191 "%s : Invalid arguments", __func__);
1192 return;
1193 }
1194
1195 hddCtxt = (hdd_context_t *)pAdapter;
1196 chAvoidInd = (tSirChAvoidIndType *)indParam;
1197 pVosContext = hddCtxt->pvosContext;
1198
1199 /* Make unsafe channel list */
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1201 "%s : band count %d",
1202 __func__, chAvoidInd->avoidRangeCount);
1203 vos_mem_zero((void *)unsafeChannelList,
1204 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1205 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1206 {
1207 startChannel = hdd_hostapd_freq_to_chn(
1208 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1209 endChannel = hdd_hostapd_freq_to_chn(
1210 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1212 "%s : start %d : %d, end %d : %d",
1213 __func__,
1214 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1215 startChannel,
1216 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1217 endChannel);
1218 for (channelLoop = startChannel;
1219 channelLoop < (endChannel + 1);
1220 channelLoop++)
1221 {
1222 /* Channel duplicate check routine */
1223 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1224 {
1225 if (unsafeChannelList[dupCheck] == channelLoop)
1226 {
1227 /* This channel is duplicated */
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1229 "%s : found duplicated channel %d",
1230 __func__, channelLoop);
1231 break;
1232 }
1233 }
1234 if (dupCheck == unsafeChannelCount)
1235 {
1236 unsafeChannelList[unsafeChannelCount] = channelLoop;
1237 unsafeChannelCount++;
1238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1239 "%s : unsafe channel %d, count %d",
1240 __func__,
1241 channelLoop, unsafeChannelCount);
1242 }
1243 else
1244 {
1245 /* DUP, do nothing */
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1247 "%s : duplicated channel %d",
1248 __func__, channelLoop);
1249 }
1250 }
1251 }
1252 /* Update unsafe channel cache
1253 * WCN Platform Driver cache */
1254 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1255 unsafeChannelCount);
1256
1257 /* Store into local cache
1258 * Start with STA and later start SAP
1259 * in this scenario, local cache will be used */
1260 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1261 unsafeChannelList,
1262 unsafeChannelCount);
1263
1264 /* Get SAP context first
1265 * SAP and P2PGO would not concurrent */
1266 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
1267 if ((pHostapdAdapter) && (unsafeChannelCount))
1268 {
1269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1270 "%s : Current operation channel %d",
1271 __func__,
1272 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1273 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1274 {
1275 if (((unsafeChannelList[channelLoop] ==
1276 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1277 (AUTO_CHANNEL_SELECT ==
1278 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1279 {
1280 /* current operating channel is un-safe channel
1281 * restart driver */
1282 hdd_hostapd_stop(pHostapdAdapter->dev);
1283 break;
1284 }
1285 }
1286 }
1287
1288 return;
1289}
1290
1291#endif /* FEATURE_WLAN_CH_AVOID */
1292
Jeff Johnson295189b2012-06-20 16:38:30 -07001293int
1294static iw_softap_setparam(struct net_device *dev,
1295 struct iw_request_info *info,
1296 union iwreq_data *wrqu, char *extra)
1297{
1298 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1299 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1300 int *value = (int *)extra;
1301 int sub_cmd = value[0];
1302 int set_value = value[1];
1303 eHalStatus status;
1304 int ret = 0; /* success */
1305 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1306
1307 switch(sub_cmd)
1308 {
1309
1310 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001311 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001312 {
1313 ret = -EIO;
1314 }
1315 break;
1316
1317 case QCSAP_PARAM_ACL_MODE:
1318 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1319 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1320 {
1321 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1322 ret = -EINVAL;
1323 }
1324 else
1325 {
1326 WLANSAP_SetMode(pVosContext, set_value);
1327 }
1328 break;
1329 case QCSAP_PARAM_MAX_ASSOC:
1330 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1331 {
1332 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1333 ret = -EINVAL;
1334 }
1335 else
1336 {
1337 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1338 {
1339 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1340 "Setting it to max allowed and continuing"),
1341 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1342 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1343 }
1344 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1345 set_value, NULL, eANI_BOOLEAN_FALSE);
1346 if ( status != eHAL_STATUS_SUCCESS )
1347 {
1348 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1349 status);
1350 ret = -EIO;
1351 }
1352 }
1353 break;
1354
1355 case QCSAP_PARAM_HIDE_SSID:
1356 {
1357 eHalStatus status = eHAL_STATUS_SUCCESS;
1358 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1359 if(eHAL_STATUS_SUCCESS != status)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
1362 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001363 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001364 return status;
1365 }
1366 break;
1367 }
1368
Leo Chang614d2072013-08-22 14:59:44 -07001369 case QCSAP_PARAM_SET_MC_RATE:
1370 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001371 tSirRateUpdateInd *rateUpdate;
1372
1373 rateUpdate = (tSirRateUpdateInd *)
1374 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1375 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001376 {
1377 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001378 "%s: SET_MC_RATE indication alloc fail", __func__);
1379 ret = -1;
1380 break;
1381 }
1382 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1383
1384 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1385 /* Ignore unicast */
1386 rateUpdate->ucastDataRate = -1;
1387 rateUpdate->mcastDataRate24GHz = set_value;
1388 rateUpdate->mcastDataRate5GHz = set_value;
1389 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1390 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1391 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1392 if (eHAL_STATUS_SUCCESS != status)
1393 {
1394 hddLog(VOS_TRACE_LEVEL_ERROR,
1395 "%s: SET_MC_RATE failed", __func__);
1396 vos_mem_free(rateUpdate);
1397 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001398 }
1399 break;
1400 }
1401
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 default:
1403 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1404 sub_cmd, set_value);
1405 ret = -EINVAL;
1406 break;
1407 }
1408
1409 return ret;
1410}
1411
1412
1413int
1414static iw_softap_getparam(struct net_device *dev,
1415 struct iw_request_info *info,
1416 union iwreq_data *wrqu, char *extra)
1417{
1418 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1419 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1420 int *value = (int *)extra;
1421 int sub_cmd = value[0];
1422 eHalStatus status;
1423 int ret = 0; /* success */
1424 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1425
1426 switch (sub_cmd)
1427 {
1428 case QCSAP_PARAM_MAX_ASSOC:
1429 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1430 if (eHAL_STATUS_SUCCESS != status)
1431 {
1432 ret = -EIO;
1433 }
1434 break;
1435
1436 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001437 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 {
1439 ret = -EIO;
1440 }
1441 *value = 0;
1442 break;
1443
1444 case QCSAP_PARAM_MODULE_DOWN_IND:
1445 {
1446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001447 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1449#ifdef WLAN_BTAMP_FEATURE
1450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001451 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1453#endif
1454 *value = 0;
1455 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001456 }
1457
1458 case QCSAP_PARAM_GET_WLAN_DBG:
1459 {
1460 vos_trace_display();
1461 *value = 0;
1462 break;
1463 }
1464
1465 case QCSAP_PARAM_AUTO_CHANNEL:
1466 {
1467 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1468 break;
1469 }
1470
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 default:
1472 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1473 ret = -EINVAL;
1474 break;
1475
1476 }
1477
1478 return ret;
1479}
1480
1481/* Usage:
1482 BLACK_LIST = 0
1483 WHITE_LIST = 1
1484 ADD MAC = 0
1485 REMOVE MAC = 1
1486
1487 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1488 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1489 while using this ioctl
1490
1491 Syntax:
1492 iwpriv softap.0 modify_acl
1493 <6 octet mac addr> <list type> <cmd type>
1494
1495 Examples:
1496 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1497 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1498 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1499 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1500*/
1501int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1502 union iwreq_data *wrqu, char *extra)
1503{
1504 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1505 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1506 v_BYTE_t *value = (v_BYTE_t*)extra;
1507 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1508 int listType, cmd, i;
1509 int ret = 0; /* success */
1510
1511 ENTER();
1512 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1513 {
1514 pPeerStaMac[i] = *(value+i);
1515 }
1516 listType = (int)(*(value+i));
1517 i++;
1518 cmd = (int)(*(value+i));
1519
Arif Hussain24bafea2013-11-15 15:10:03 -08001520 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1521 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001522
1523 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1524 != VOS_STATUS_SUCCESS)
1525 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001526 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 ret = -EIO;
1528 }
1529 EXIT();
1530 return ret;
1531}
1532
1533int
1534static iw_softap_getchannel(struct net_device *dev,
1535 struct iw_request_info *info,
1536 union iwreq_data *wrqu, char *extra)
1537{
1538 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1539
Jeff Johnson43971f52012-07-17 12:26:56 -07001540 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001541
Jeff Johnson43971f52012-07-17 12:26:56 -07001542 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 return 0;
1544}
1545
Jeff Johnsone7245742012-09-05 17:12:55 -07001546int
schang86c22c42013-03-13 18:41:24 -07001547static iw_softap_set_max_tx_power(struct net_device *dev,
Jeff Johnsone7245742012-09-05 17:12:55 -07001548 struct iw_request_info *info,
1549 union iwreq_data *wrqu, char *extra)
1550{
1551 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1552 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001553 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001554 int set_value;
1555 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1556 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1557
schang86c22c42013-03-13 18:41:24 -07001558 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001559 return -ENOMEM;
1560
Leo Changd37675a2013-08-01 13:19:45 -07001561 /* Assign correct slef MAC address */
1562 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1563 VOS_MAC_ADDR_SIZE);
1564 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1565 VOS_MAC_ADDR_SIZE);
1566
schang86c22c42013-03-13 18:41:24 -07001567 set_value = value[0];
1568 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1569 {
1570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001571 __func__);
schang86c22c42013-03-13 18:41:24 -07001572 return -EIO;
1573 }
1574
1575 return 0;
1576}
1577
1578int
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301579static iw_display_data_path_snapshot(struct net_device *dev,
1580 struct iw_request_info *info,
1581 union iwreq_data *wrqu, char *extra)
1582{
1583
1584 /* Function intitiating dumping states of
1585 * HDD(WMM Tx Queues)
1586 * TL State (with Per Client infor)
1587 * DXE Snapshot (Called at the end of TL Snapshot)
1588 */
1589 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1590 hddLog(LOGE, "%s: called for SAP",__func__);
1591 hdd_wmm_tx_snapshot(pHostapdAdapter);
1592 WLANTL_TLDebugMessage(VOS_TRUE);
1593 return 0;
1594}
1595
1596int
schang86c22c42013-03-13 18:41:24 -07001597static iw_softap_set_tx_power(struct net_device *dev,
1598 struct iw_request_info *info,
1599 union iwreq_data *wrqu, char *extra)
1600{
1601 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1602 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1603 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1604 int *value = (int *)extra;
1605 int set_value;
1606 ptSapContext pSapCtx = NULL;
1607
1608 if (NULL == value)
1609 return -ENOMEM;
1610
1611 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1612 if (NULL == pSapCtx)
1613 {
1614 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1615 "%s: Invalid SAP pointer from pvosGCtx", __func__);
1616 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07001617 }
1618
1619 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07001620 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07001621 {
schang86c22c42013-03-13 18:41:24 -07001622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07001623 __func__);
1624 return -EIO;
1625 }
1626
1627 return 0;
1628}
1629
Kiet Lambcf38522013-10-26 18:28:27 +05301630/**---------------------------------------------------------------------------
1631
1632 \brief iw_softap_set_trafficmonitor() -
1633 This function dynamically enable/disable traffic monitor functonality
1634 the command iwpriv wlanX setTrafficMon <value>.
1635
1636 \param - dev - Pointer to the net device.
1637 - addr - Pointer to the sockaddr.
1638 \return - 0 for success, non zero for failure
1639
1640 --------------------------------------------------------------------------*/
1641
1642static int iw_softap_set_trafficmonitor(struct net_device *dev,
1643 struct iw_request_info *info,
1644 union iwreq_data *wrqu, char *extra)
1645{
1646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1647 int *isSetTrafficMon = (int *)wrqu->data.pointer;
1648 hdd_context_t *pHddCtx;
1649 int status;
1650
1651 if (NULL == pAdapter)
1652 {
1653 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1654 "%s: HDD adapter is Null", __func__);
1655 return -ENODEV;
1656 }
1657
1658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1659
1660 status = wlan_hdd_validate_context(pHddCtx);
1661
1662 if (0 != status)
1663 {
1664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: HDD context is not valid", __func__);
1666 return status;
1667 }
1668
1669 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
1670
1671 if (NULL == isSetTrafficMon)
1672 {
1673 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1674 "%s: Invalid SAP pointer from extra", __func__);
1675 return -ENOMEM;
1676 }
1677
1678 if (TRUE == *isSetTrafficMon)
1679 {
1680 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
1681 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
1682 {
1683 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1684 "%s: failed to Start Traffic Monitor timer ", __func__ );
1685 return -EIO;
1686 }
1687 }
1688 else if (FALSE == *isSetTrafficMon)
1689 {
1690 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
1691 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
1692 {
1693 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1694 "%s: failed to Stop Traffic Monitor timer ", __func__ );
1695 return -EIO;
1696 }
1697
1698 }
1699 return 0;
1700}
1701
Jeff Johnson295189b2012-06-20 16:38:30 -07001702#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1703
1704int
1705static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1706 struct iw_request_info *info,
1707 union iwreq_data *wrqu, char *extra)
1708{
1709 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07001710 unsigned int maclist_index;
Jeff Johnson295189b2012-06-20 16:38:30 -07001711 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
Arif Hussained667642013-10-27 23:01:14 -07001712 char maclist_null = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -07001713 int cnt = 0, len;
1714
1715
Arif Hussained667642013-10-27 23:01:14 -07001716 maclist_index = sizeof(unsigned long int);
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 len = wrqu->data.length;
1718
1719 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
1720 while((cnt < WLAN_MAX_STA_COUNT) && (len > (sizeof(v_MACADDR_t)+1))) {
1721 if (TRUE == pStaInfo[cnt].isUsed) {
1722
1723 if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
Arif Hussained667642013-10-27 23:01:14 -07001724 if (copy_to_user((void *)wrqu->data.pointer + maclist_index,
1725 (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t)))
1726 {
1727 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1728 return -EFAULT;
1729 }
1730 maclist_index += sizeof(v_MACADDR_t);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 len -= sizeof(v_MACADDR_t);
1732 }
1733 }
1734 cnt++;
1735 }
1736 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
1737
Arif Hussained667642013-10-27 23:01:14 -07001738 if (copy_to_user((void *)wrqu->data.pointer + maclist_index,
1739 (void *)&maclist_null, sizeof(maclist_null)) ||
1740 copy_to_user((void *)wrqu->data.pointer,
1741 (void *)&wrqu->data.length, sizeof(wrqu->data.length)))
1742 {
1743 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1744 return -EFAULT;
1745 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 wrqu->data.length -= len;
1747
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 return 0;
1749}
1750
1751/* Usage:
1752 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1753 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1754 while using this ioctl
1755
1756 Syntax:
1757 iwpriv softap.0 disassoc_sta <6 octet mac address>
1758
1759 e.g.
1760 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1761 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1762*/
1763
1764int
1765static iw_softap_disassoc_sta(struct net_device *dev,
1766 struct iw_request_info *info,
1767 union iwreq_data *wrqu, char *extra)
1768{
1769 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1770 v_U8_t *peerMacAddr;
1771
1772 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301773 /* iwpriv tool or framework calls this ioctl with
1774 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301776 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07001777
Arif Hussain24bafea2013-11-15 15:10:03 -08001778 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
1779 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001780 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1781 EXIT();
1782 return 0;
1783}
1784
1785int
1786static iw_softap_ap_stats(struct net_device *dev,
1787 struct iw_request_info *info,
1788 union iwreq_data *wrqu, char *extra)
1789{
1790 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1791 WLANTL_TRANSFER_STA_TYPE statBuffer;
1792 char *pstatbuf;
1793 int len = wrqu->data.length;
1794 pstatbuf = wrqu->data.pointer;
1795
Arif Hussained667642013-10-27 23:01:14 -07001796 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
1797 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07001798
Arif Hussained667642013-10-27 23:01:14 -07001799 pstatbuf = kmalloc(wrqu->data.length, GFP_KERNEL);
1800 if(NULL == pstatbuf) {
1801 hddLog(LOG1, "unable to allocate memory");
1802 return -ENOMEM;
1803 }
1804 len = scnprintf(pstatbuf, wrqu->data.length,
1805 "RUF=%d RMF=%d RBF=%d "
1806 "RUB=%d RMB=%d RBB=%d "
1807 "TUF=%d TMF=%d TBF=%d "
1808 "TUB=%d TMB=%d TBB=%d",
1809 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
1810 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
1811 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1812 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
1813 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
1814 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07001815
Arif Hussained667642013-10-27 23:01:14 -07001816 if (len > wrqu->data.length ||
1817 copy_to_user((void *)wrqu->data.pointer, (void *)pstatbuf, len))
1818 {
1819 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1820 kfree(pstatbuf);
1821 return -EFAULT;
1822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 wrqu->data.length -= len;
Arif Hussained667642013-10-27 23:01:14 -07001824 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 return 0;
1826}
1827
1828int
1829static iw_softap_commit(struct net_device *dev,
1830 struct iw_request_info *info,
1831 union iwreq_data *wrqu, char *extra)
1832{
1833 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1834 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1835 hdd_hostapd_state_t *pHostapdState;
1836 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1837 tpWLAN_SAPEventCB pSapEventCallback;
1838 tsap_Config_t *pConfig;
1839 s_CommitConfig_t *pCommitConfig;
1840 struct qc_mac_acl_entry *acl_entry = NULL;
1841 v_SINT_t i = 0, num_mac = 0;
1842 v_U32_t status = 0;
1843 eCsrAuthType RSNAuthType;
1844 eCsrEncryptionType RSNEncryptType;
1845 eCsrEncryptionType mcRSNEncryptType;
1846
1847 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1848 pCommitConfig = (s_CommitConfig_t *)extra;
1849
1850 pConfig = kmalloc(sizeof(tsap_Config_t), GFP_KERNEL);
1851 if(NULL == pConfig) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001852 hddLog(LOG1, "VOS unable to allocate memory");
Jeff Johnson295189b2012-06-20 16:38:30 -07001853 return -ENOMEM;
1854 }
1855 pConfig->beacon_int = pCommitConfig->beacon_int;
1856 pConfig->channel = pCommitConfig->channel;
1857
1858 /*Protection parameter to enable or disable*/
1859 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1860 pConfig->dtim_period = pCommitConfig->dtim_period;
1861 switch(pCommitConfig->hw_mode )
1862 {
1863 case eQC_DOT11_MODE_11A:
1864 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
1865 break;
1866 case eQC_DOT11_MODE_11B:
1867 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
1868 break;
1869 case eQC_DOT11_MODE_11G:
1870 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
1871 break;
1872
1873 case eQC_DOT11_MODE_11N:
1874 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1875 break;
1876 case eQC_DOT11_MODE_11G_ONLY:
1877 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1878 break;
1879 case eQC_DOT11_MODE_11N_ONLY:
1880 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
1881 break;
1882 default:
1883 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1884 break;
1885
1886 }
1887
1888 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
1889 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
1890 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
1891 pConfig->authType = eSAP_SHARED_KEY;
1892 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
1893 pConfig->authType = eSAP_OPEN_SYSTEM;
1894 else
1895 pConfig->authType = eSAP_AUTO_SWITCH;
1896
1897 pConfig->privacy = pCommitConfig->privacy;
1898 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
1899 pConfig->wps_state = pCommitConfig->wps_state;
1900 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1901 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
1902 if(pConfig->RSNWPAReqIELength){
1903 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
1904 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
1905 // The actual processing may eventually be more extensive than this.
1906 // Right now, just consume any PMKIDs that are sent in by the app.
1907 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001908 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
Jeff Johnson295189b2012-06-20 16:38:30 -07001909 &RSNEncryptType,
1910 &mcRSNEncryptType,
1911 &RSNAuthType,
1912 pConfig->pRSNWPAReqIE[1]+2,
1913 pConfig->pRSNWPAReqIE );
1914
1915 if( VOS_STATUS_SUCCESS == status )
1916 {
1917 // Now copy over all the security attributes you have parsed out
1918 //TODO: Need to handle mixed mode
1919 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1920 pConfig->mcRSNEncryptType = mcRSNEncryptType;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001921 hddLog( LOG1, FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1923 }
1924 }
1925 }
1926 else
1927 {
1928 /* If no RSNIE, set encrypt type to NONE*/
1929 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1930 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001931 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001932 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
1933 }
1934
Chilam Ngc4244af2013-04-01 15:37:32 -07001935 if (pConfig->RSNWPAReqIELength > QCSAP_MAX_OPT_IE) {
1936 hddLog(LOGE, FL("RSNWPAReqIELength: %d too large"), pConfig->RSNWPAReqIELength);
1937 kfree(pConfig);
1938 return -EIO;
1939 }
1940
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
1942 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
1943 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
1944 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1945
1946 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
1947
1948 // ht_capab is not what the name conveys,this is used for protection bitmap
1949 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1950
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301951 if (pCommitConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1952 num_mac = pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 else
1954 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
1955 acl_entry = pCommitConfig->accept_mac;
1956 for (i = 0; i < num_mac; i++)
1957 {
1958 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1959 acl_entry++;
1960 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301961 if (pCommitConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1962 num_mac = pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 else
1964 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
1965 acl_entry = pCommitConfig->deny_mac;
1966 for (i = 0; i < num_mac; i++)
1967 {
1968 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1969 acl_entry++;
1970 }
1971 //Uapsd Enabled Bit
1972 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1973 //Enable OBSS protection
1974 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1975 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
1976
Arif Hussain6d2a3322013-11-17 19:50:10 -08001977 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1978 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
1979 pConfig->SSIDinfo.ssid.ssId,
1980 (int)pConfig->beacon_int, (int)pConfig->channel);
1981 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
1982 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
1983 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
1984 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
1985 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d, DisableIntraBssFwd = %d"),
1986 pConfig->protEnabled, pConfig->obssProtEnabled,
1987 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001988
1989 pSapEventCallback = hdd_hostapd_SAPEventCB;
1990 pConfig->persona = pHostapdAdapter->device_mode;
1991 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
1992 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001993 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 }
1995
1996 kfree(pConfig);
1997
1998 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1999 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2000
2001 if (!VOS_IS_STATUS_SUCCESS(vos_status))
2002 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 VOS_ASSERT(0);
2005 }
2006
2007 pHostapdState->bCommit = TRUE;
2008 if(pHostapdState->vosStatus)
2009 {
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002010 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 }
2012 else
2013 {
2014 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2015 WLANSAP_Update_WpsIe ( pVosContext );
2016 return 0;
2017 }
2018}
2019static
2020int iw_softap_setmlme(struct net_device *dev,
2021 struct iw_request_info *info,
2022 union iwreq_data *wrqu, char *extra)
2023{
2024 struct sQcSapreq_mlme *pmlme;
2025 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
2026 v_MACADDR_t destAddress;
2027 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
2028 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
2029 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
2030 switch(pmlme->im_op)
2031 {
2032 case QCSAP_MLME_AUTHORIZE:
2033 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
2034 break;
2035 case QCSAP_MLME_ASSOC:
2036 //TODO:inform to TL after associating (not needed as we do in sapCallback)
2037 break;
2038 case QCSAP_MLME_UNAUTHORIZE:
2039 //TODO: send the disassoc to station
2040 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
2041 break;
2042 case QCSAP_MLME_DISASSOC:
2043 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
2044 break;
2045 case QCSAP_MLME_DEAUTH:
2046 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
2047 break;
2048 case QCSAP_MLME_MICFAILURE:
2049 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
2050 break;
2051 default:
2052 break;
2053 }
2054 return 0;
2055}
2056
2057static int iw_softap_set_channel_range(struct net_device *dev,
2058 struct iw_request_info *info,
2059 union iwreq_data *wrqu, char *extra)
2060{
2061 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2062 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002063 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002064
2065 int *value = (int *)extra;
2066 int startChannel = value[0];
2067 int endChannel = value[1];
2068 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002069 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 int ret = 0; /* success */
2071
2072 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2073 if(status != VOS_STATUS_SUCCESS)
2074 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002075 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 startChannel,endChannel, band);
2077 ret = -EINVAL;
2078 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002079
2080 pHddCtx->is_dynamic_channel_range_set = 1;
2081
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 return ret;
2083}
2084
2085int iw_softap_get_channel_list(struct net_device *dev,
2086 struct iw_request_info *info,
2087 union iwreq_data *wrqu, char *extra)
2088{
2089 v_U32_t num_channels = 0;
2090 v_U8_t i = 0;
2091 v_U8_t bandStartChannel = RF_CHAN_1;
2092 v_U8_t bandEndChannel = RF_CHAN_165;
2093 v_U32_t temp_num_channels = 0;
2094 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2095 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2096 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002098 eCsrBand curBand = eCSR_BAND_ALL;
2099
2100 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2101 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002102 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002103 return -EIO;
2104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002105 wrqu->data.length = sizeof(tChannelListInfo);
2106 ENTER();
2107
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002108 if (eCSR_BAND_24 == curBand)
2109 {
2110 bandStartChannel = RF_CHAN_1;
2111 bandEndChannel = RF_CHAN_14;
2112 }
2113 else if (eCSR_BAND_5G == curBand)
2114 {
2115 bandStartChannel = RF_CHAN_36;
2116 bandEndChannel = RF_CHAN_165;
2117 }
2118
Arif Hussain6d2a3322013-11-17 19:50:10 -08002119 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302120 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002121 bandStartChannel, bandEndChannel );
2122
Jeff Johnson295189b2012-06-20 16:38:30 -07002123 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2124 {
2125 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2126 {
2127 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2128 num_channels++;
2129 }
2130 }
2131
2132 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2133
2134 temp_num_channels = num_channels;
2135
2136 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2137 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002138 hddLog(LOG1,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002139 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 }
2141
2142 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
2143 {
2144 for(i = 0; i < temp_num_channels; i++)
2145 {
2146
2147 if((channel_list->channels[i] > 35) &&
2148 (channel_list->channels[i] < 49))
2149 {
2150 vos_mem_move(&channel_list->channels[i],
2151 &channel_list->channels[i+1],
2152 temp_num_channels - (i-1));
2153 num_channels--;
2154 temp_num_channels--;
2155 i--;
2156 }
2157 }
2158 }
2159
Arif Hussain6d2a3322013-11-17 19:50:10 -08002160 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002161
2162 if (num_channels > IW_MAX_FREQUENCIES)
2163 {
2164 num_channels = IW_MAX_FREQUENCIES;
2165 }
2166
2167 channel_list->num_channels = num_channels;
2168 EXIT();
2169
2170 return 0;
2171}
2172
2173static
2174int iw_get_genie(struct net_device *dev,
2175 struct iw_request_info *info,
2176 union iwreq_data *wrqu, char *extra)
2177{
2178 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2179 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2180 eHalStatus status;
2181 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2182 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2183 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002184 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002185 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2186 status = WLANSap_getstationIE_information(pVosContext,
2187 &length,
2188 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002189 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2190 if (wrqu->data.length < length ||
2191 copy_to_user(wrqu->data.pointer,
2192 (v_VOID_t*)genIeBytes, length))
2193 {
2194 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2195 return -EFAULT;
2196 }
2197 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002198
Arif Hussain6d2a3322013-11-17 19:50:10 -08002199 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002200
2201
2202 EXIT();
2203 return 0;
2204}
2205static
2206int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2207 struct iw_request_info *info,
2208 union iwreq_data *wrqu, char *extra)
2209{
2210 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002211 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2213 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002214
Arif Hussain6d2a3322013-11-17 19:50:10 -08002215 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002216 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2217
2218 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2219 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2220 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2221 WPSPBCProbeReqIEs.probeReqIELen);
2222 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2223 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2224 sizeof(v_MACADDR_t));
2225 if (copy_to_user(wrqu->data.pointer,
2226 (void *)&WPSPBCProbeReqIEs,
2227 sizeof(WPSPBCProbeReqIEs)))
2228 {
2229 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2230 return -EFAULT;
2231 }
2232 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002233 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002234 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 up(&pHddApCtx->semWpsPBCOverlapInd);
2236 EXIT();
2237 return 0;
2238}
2239
2240/**---------------------------------------------------------------------------
2241
2242 \brief iw_set_auth_hostap() -
2243 This function sets the auth type received from the wpa_supplicant.
2244
2245 \param - dev - Pointer to the net device.
2246 - info - Pointer to the iw_request_info.
2247 - wrqu - Pointer to the iwreq_data.
2248 - extra - Pointer to the data.
2249 \return - 0 for success, non zero for failure
2250
2251 --------------------------------------------------------------------------*/
2252int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
2253 union iwreq_data *wrqu,char *extra)
2254{
2255 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2256 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2257
2258 ENTER();
2259 switch(wrqu->param.flags & IW_AUTH_INDEX)
2260 {
2261 case IW_AUTH_TKIP_COUNTERMEASURES:
2262 {
2263 if(wrqu->param.value) {
2264 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2265 "Counter Measure started %d", wrqu->param.value);
2266 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2267 }
2268 else {
2269 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2270 "Counter Measure stopped=%d", wrqu->param.value);
2271 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2272 }
2273
2274 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2275 wrqu->param.value);
2276 }
2277 break;
2278
2279 default:
2280
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002281 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 wrqu->param.flags & IW_AUTH_INDEX);
2283 break;
2284 }
2285
2286 EXIT();
2287 return 0;
2288}
2289
2290static int iw_set_ap_encodeext(struct net_device *dev,
2291 struct iw_request_info *info,
2292 union iwreq_data *wrqu, char *extra)
2293{
2294 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2295 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2296 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002297 int retval = 0;
2298 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002299 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2300 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2301 int key_index;
2302 struct iw_point *encoding = &wrqu->encoding;
2303 tCsrRoamSetKey setKey;
2304// tCsrRoamRemoveKey RemoveKey;
2305 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 ENTER();
2308
2309 key_index = encoding->flags & IW_ENCODE_INDEX;
2310
2311 if(key_index > 0) {
2312
2313 /*Convert from 1-based to 0-based keying*/
2314 key_index--;
2315 }
2316 if(!ext->key_len) {
2317#if 0
2318 /*Set the encrytion type to NONE*/
2319#if 0
2320 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2321#endif
2322
2323 RemoveKey.keyId = key_index;
2324 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2325 /*Key direction for group is RX only*/
2326 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2327 }
2328 else {
2329 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2330 }
2331 switch(ext->alg)
2332 {
2333 case IW_ENCODE_ALG_NONE:
2334 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2335 break;
2336 case IW_ENCODE_ALG_WEP:
2337 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2338 break;
2339 case IW_ENCODE_ALG_TKIP:
2340 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002341 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002342 case IW_ENCODE_ALG_CCMP:
2343 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2344 break;
2345 default:
2346 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2347 break;
2348 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002349 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 -07002350 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002352 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002353 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002354 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2355 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002356 {
2357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002358 __LINE__, vstatus );
2359 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002361#endif
2362 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002363
Jeff Johnson43971f52012-07-17 12:26:56 -07002364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002365
2366 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2367
2368 setKey.keyId = key_index;
2369 setKey.keyLength = ext->key_len;
2370
2371 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2372 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2373 }
2374
2375 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2376 /*Key direction for group is RX only*/
2377 setKey.keyDirection = eSIR_RX_ONLY;
2378 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2379 }
2380 else {
2381
2382 setKey.keyDirection = eSIR_TX_RX;
2383 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2384 }
2385 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2386 {
2387 setKey.keyDirection = eSIR_TX_DEFAULT;
2388 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2389 }
2390
2391 /*For supplicant pae role is zero*/
2392 setKey.paeRole = 0;
2393
2394 switch(ext->alg)
2395 {
2396 case IW_ENCODE_ALG_NONE:
2397 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2398 break;
2399
2400 case IW_ENCODE_ALG_WEP:
2401 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2402 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002403 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002404 break;
2405
2406 case IW_ENCODE_ALG_TKIP:
2407 {
2408 v_U8_t *pKey = &setKey.Key[0];
2409
2410 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2411
2412 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2413
2414 /*Supplicant sends the 32bytes key in this order
2415
2416 |--------------|----------|----------|
2417 | Tk1 |TX-MIC | RX Mic |
2418 |--------------|----------|----------|
2419 <---16bytes---><--8bytes--><--8bytes-->
2420
2421 */
2422 /*Sme expects the 32 bytes key to be in the below order
2423
2424 |--------------|----------|----------|
2425 | Tk1 |RX-MIC | TX Mic |
2426 |--------------|----------|----------|
2427 <---16bytes---><--8bytes--><--8bytes-->
2428 */
2429 /* Copy the Temporal Key 1 (TK1) */
2430 vos_mem_copy(pKey,ext->key,16);
2431
2432 /*Copy the rx mic first*/
2433 vos_mem_copy(&pKey[16],&ext->key[24],8);
2434
2435 /*Copy the tx mic */
2436 vos_mem_copy(&pKey[24],&ext->key[16],8);
2437
2438 }
2439 break;
2440
2441 case IW_ENCODE_ALG_CCMP:
2442 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2443 break;
2444
2445 default:
2446 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2447 break;
2448 }
2449
2450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302451 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002452 setKey.keyId);
2453 for(i=0; i< ext->key_len; i++)
2454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2455 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002456
2457 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2458 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002459 {
2460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002461 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2462 retval = -EINVAL;
2463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002464
Jeff Johnson43971f52012-07-17 12:26:56 -07002465 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002466}
Jeff Johnson43971f52012-07-17 12:26:56 -07002467
2468
Jeff Johnson295189b2012-06-20 16:38:30 -07002469static int iw_set_ap_mlme(struct net_device *dev,
2470 struct iw_request_info *info,
2471 union iwreq_data *wrqu,
2472 char *extra)
2473{
2474#if 0
2475 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2476 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2477
2478 ENTER();
2479
2480 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2481 switch (mlme->cmd) {
2482 case IW_MLME_DISASSOC:
2483 case IW_MLME_DEAUTH:
2484 hddLog(LOG1, "Station disassociate");
2485 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2486 {
2487 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2488
2489 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2490 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2491
2492 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2493
2494 //clear all the reason codes
2495 if (status != 0)
2496 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002497 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002498 }
2499
2500 netif_stop_queue(dev);
2501 netif_carrier_off(dev);
2502 }
2503 else
2504 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002505 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 -07002506 }
2507 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002508 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 return -EINVAL;
2510 }//end of switch
2511 EXIT();
2512#endif
2513 return 0;
2514// return status;
2515}
2516
2517static int iw_get_ap_rts_threshold(struct net_device *dev,
2518 struct iw_request_info *info,
2519 union iwreq_data *wrqu, char *extra)
2520{
2521 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2522 v_U32_t status = 0;
2523
2524 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2525
2526 return status;
2527}
2528
2529static int iw_get_ap_frag_threshold(struct net_device *dev,
2530 struct iw_request_info *info,
2531 union iwreq_data *wrqu, char *extra)
2532{
2533 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2534 v_U32_t status = 0;
2535
2536 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2537
2538 return status;
2539}
2540
2541static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2542 struct iw_freq *fwrq, char *extra)
2543{
Jeff Johnsone7245742012-09-05 17:12:55 -07002544 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2546 tHalHandle hHal;
2547 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002548 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002549
2550 ENTER();
2551
2552 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2554 "%s:LOGP in Progress. Ignore!!!",__func__);
2555 return status;
2556 }
2557
2558 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2559 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2560
2561 if(pHostapdState->bssState == BSS_STOP )
2562 {
2563 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2564 != eHAL_STATUS_SUCCESS)
2565 {
2566 return -EIO;
2567 }
2568 else
2569 {
2570 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002571 if( TRUE == status)
2572 {
2573 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2574 * iwlist & iwconfig command shows frequency into proper
2575 * format (2.412 GHz instead of 246.2 MHz)*/
2576 fwrq->m = freq;
2577 fwrq->e = MHZ;
2578 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002579 }
2580 }
2581 else
2582 {
2583 channel = pHddApCtx->operatingChannel;
2584 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002585 if( TRUE == status)
2586 {
2587 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2588 * iwlist & iwconfig command shows frequency into proper
2589 * format (2.412 GHz instead of 246.2 MHz)*/
2590 fwrq->m = freq;
2591 fwrq->e = MHZ;
2592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002594 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002595}
2596
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302597static int iw_get_mode(struct net_device *dev,
2598 struct iw_request_info *info,
2599 union iwreq_data *wrqu,
2600 char *extra)
2601{
2602 int status = 0;
2603
2604 wrqu->mode = IW_MODE_MASTER;
2605
2606 return status;
2607}
2608
Jeff Johnson295189b2012-06-20 16:38:30 -07002609static int iw_softap_setwpsie(struct net_device *dev,
2610 struct iw_request_info *info,
2611 union iwreq_data *wrqu,
2612 char *extra)
2613{
2614 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2615 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2616 hdd_hostapd_state_t *pHostapdState;
2617 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002618 u_int8_t *wps_genie;
2619 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07002620 u_int8_t *pos;
2621 tpSap_WPSIE pSap_WPSIe;
2622 u_int8_t WPSIeType;
2623 u_int16_t length;
2624 ENTER();
2625
Arif Hussained667642013-10-27 23:01:14 -07002626 if(!wrqu->data.length || wrqu->data.length <= QCSAP_MAX_WSC_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002627 return 0;
2628
Arif Hussained667642013-10-27 23:01:14 -07002629 wps_genie = kmalloc(wrqu->data.length, GFP_KERNEL);
2630
2631 if(NULL == wps_genie) {
2632 hddLog(LOG1, "unable to allocate memory");
2633 return -ENOMEM;
2634 }
2635 fwps_genie = wps_genie;
2636 if (copy_from_user((void *)wps_genie,
2637 wrqu->data.pointer, wrqu->data.length))
2638 {
2639 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2640 kfree(fwps_genie);
2641 return -EFAULT;
2642 }
2643
Jeff Johnson295189b2012-06-20 16:38:30 -07002644 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2645 if (NULL == pSap_WPSIe)
2646 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002647 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07002648 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002649 return -ENOMEM;
2650 }
2651 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2652
Arif Hussain6d2a3322013-11-17 19:50:10 -08002653 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 -07002654 WPSIeType = wps_genie[0];
2655 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2656 {
2657 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2658 wps_genie = wps_genie + 1;
2659 switch ( wps_genie[0] )
2660 {
2661 case DOT11F_EID_WPA:
2662 if (wps_genie[1] < 2 + 4)
2663 {
2664 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002665 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002666 return -EINVAL;
2667 }
2668 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2669 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002670 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002671 pos = &wps_genie[6];
2672 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2673 {
2674 switch((u_int16_t)(*pos<<8) | *(pos+1))
2675 {
2676 case HDD_WPS_ELEM_VERSION:
2677 pos += 4;
2678 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002679 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2681 pos += 1;
2682 break;
2683
2684 case HDD_WPS_ELEM_WPS_STATE:
2685 pos +=4;
2686 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002687 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002688 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2689 pos += 1;
2690 break;
2691 case HDD_WPS_ELEM_APSETUPLOCK:
2692 pos += 4;
2693 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002694 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2696 pos += 1;
2697 break;
2698 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2699 pos += 4;
2700 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002701 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002702 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2703 pos += 1;
2704 break;
2705 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2706 pos += 4;
2707 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002708 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002709 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2710 pos += 2;
2711 break;
2712 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2713 pos += 4;
2714 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002715 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002716 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2717 pos += 2;
2718 break;
2719
2720 case HDD_WPS_ELEM_UUID_E:
2721 pos += 2;
2722 length = *pos<<8 | *(pos+1);
2723 pos += 2;
2724 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2725 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2726 pos += length;
2727 break;
2728 case HDD_WPS_ELEM_RF_BANDS:
2729 pos += 4;
2730 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002731 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002732 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2733 pos += 1;
2734 break;
2735
2736 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002737 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07002738 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002739 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002740 return -EINVAL;
2741 }
2742 }
2743 }
2744 else {
2745 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002746 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002747 }
2748 break;
2749
2750 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002751 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002752 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002753 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002754 return 0;
2755 }
2756 }
2757 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2758 {
2759 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2760 wps_genie = wps_genie + 1;
2761 switch ( wps_genie[0] )
2762 {
2763 case DOT11F_EID_WPA:
2764 if (wps_genie[1] < 2 + 4)
2765 {
2766 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002767 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002768 return -EINVAL;
2769 }
2770 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2771 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002772 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002773 pos = &wps_genie[6];
2774 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2775 {
2776 switch((u_int16_t)(*pos<<8) | *(pos+1))
2777 {
2778 case HDD_WPS_ELEM_VERSION:
2779 pos += 4;
2780 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002781 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002782 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2783 pos += 1;
2784 break;
2785
2786 case HDD_WPS_ELEM_WPS_STATE:
2787 pos +=4;
2788 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002789 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002790 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2791 pos += 1;
2792 break;
2793 case HDD_WPS_ELEM_APSETUPLOCK:
2794 pos += 4;
2795 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002796 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2798 pos += 1;
2799 break;
2800 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2801 pos += 4;
2802 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002803 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2805 pos += 1;
2806 break;
2807 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2808 pos += 4;
2809 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002810 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002811 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2812 pos += 2;
2813 break;
2814 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2815 pos += 4;
2816 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002817 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002818 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2819 pos += 2;
2820 break;
2821 case HDD_WPS_ELEM_RSP_TYPE:
2822 pos += 4;
2823 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002824 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002825 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2826 pos += 1;
2827 break;
2828 case HDD_WPS_ELEM_UUID_E:
2829 pos += 2;
2830 length = *pos<<8 | *(pos+1);
2831 pos += 2;
2832 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2833 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2834 pos += length;
2835 break;
2836
2837 case HDD_WPS_ELEM_MANUFACTURER:
2838 pos += 2;
2839 length = *pos<<8 | *(pos+1);
2840 pos += 2;
2841 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2842 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2843 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2844 pos += length;
2845 break;
2846
2847 case HDD_WPS_ELEM_MODEL_NAME:
2848 pos += 2;
2849 length = *pos<<8 | *(pos+1);
2850 pos += 2;
2851 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2852 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2853 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2854 pos += length;
2855 break;
2856 case HDD_WPS_ELEM_MODEL_NUM:
2857 pos += 2;
2858 length = *pos<<8 | *(pos+1);
2859 pos += 2;
2860 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2861 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2862 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2863 pos += length;
2864 break;
2865 case HDD_WPS_ELEM_SERIAL_NUM:
2866 pos += 2;
2867 length = *pos<<8 | *(pos+1);
2868 pos += 2;
2869 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2870 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2871 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2872 pos += length;
2873 break;
2874 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2875 pos += 4;
2876 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002877 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002878 pos += 2;
2879
2880 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002881 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002882 pos += 4;
2883 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002884 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002885 pos += 2;
2886 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2887 break;
2888 case HDD_WPS_ELEM_DEVICE_NAME:
2889 pos += 2;
2890 length = *pos<<8 | *(pos+1);
2891 pos += 2;
2892 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2893 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2894 pos += length;
2895 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2896 break;
2897 case HDD_WPS_ELEM_CONFIG_METHODS:
2898 pos += 4;
2899 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002900 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002901 pos += 2;
2902 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2903 break;
2904
2905 case HDD_WPS_ELEM_RF_BANDS:
2906 pos += 4;
2907 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002908 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 pos += 1;
2910 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2911 break;
2912 } // switch
2913 }
2914 }
2915 else
2916 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002917 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002918 }
2919
2920 } // switch
2921 }
2922 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2923 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2924 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2925 {
2926 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2927 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2928 WLANSAP_Update_WpsIe ( pVosContext );
2929 }
2930
2931 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002932 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 EXIT();
2934 return halStatus;
2935}
2936
2937static int iw_softap_stopbss(struct net_device *dev,
2938 struct iw_request_info *info,
2939 union iwreq_data *wrqu,
2940 char *extra)
2941{
2942 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2943 VOS_STATUS status = VOS_STATUS_SUCCESS;
2944 ENTER();
2945 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2946 {
2947 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2948 {
2949 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2950
2951 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2952
2953 if (!VOS_IS_STATUS_SUCCESS(status))
2954 {
2955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002956 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002957 VOS_ASSERT(0);
2958 }
2959 }
2960 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2961 }
2962 EXIT();
2963 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2964}
2965
2966static int iw_softap_version(struct net_device *dev,
2967 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002968 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 char *extra)
2970{
Jeff Johnson295189b2012-06-20 16:38:30 -07002971 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002972
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002974 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002976 return 0;
2977}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002978
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002979VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002980{
2981 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002982 int len = 0;
2983 const char sta_info_header[] = "staId staAddress\n";
2984
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002985 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002986 pBuf += len;
2987 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002988
2989 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2990 {
2991 if(pAdapter->aStaInfo[i].isUsed)
2992 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08002993 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002994 pAdapter->aStaInfo[i].ucSTAId,
2995 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
2996 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
2997 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
2998 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
2999 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
3000 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003001 pBuf += len;
3002 buf_len -= len;
3003 }
3004 if(WE_GET_STA_INFO_SIZE > buf_len)
3005 {
3006 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003007 }
3008 }
3009 return VOS_STATUS_SUCCESS;
3010}
3011
3012static int iw_softap_get_sta_info(struct net_device *dev,
3013 struct iw_request_info *info,
3014 union iwreq_data *wrqu,
3015 char *extra)
3016{
3017 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3018 VOS_STATUS status;
3019 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003020 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003021 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003023 return -EINVAL;
3024 }
3025 wrqu->data.length = strlen(extra);
3026 EXIT();
3027 return 0;
3028}
3029
Jeff Johnson295189b2012-06-20 16:38:30 -07003030static int iw_set_ap_genie(struct net_device *dev,
3031 struct iw_request_info *info,
3032 union iwreq_data *wrqu,
3033 char *extra)
3034{
3035
3036 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3037 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3038 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003039 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003040
3041 ENTER();
3042
3043 if(!wrqu->data.length)
3044 {
3045 EXIT();
3046 return 0;
3047 }
Arif Hussained667642013-10-27 23:01:14 -07003048
Jeff Johnson295189b2012-06-20 16:38:30 -07003049 switch (genie[0])
3050 {
3051 case DOT11F_EID_WPA:
3052 case DOT11F_EID_RSN:
3053 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3054 {
3055 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3056 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3057 }
3058 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003059 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003060 break;
3061
3062 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003063 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003064 halStatus = 0;
3065 }
3066
3067 EXIT();
3068 return halStatus;
3069}
3070
3071static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3072{
3073 eHalStatus hstatus;
3074 long lrc;
3075 struct statsContext context;
3076
3077 if (NULL == pAdapter)
3078 {
3079 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Padapter is NULL", __func__);
3080 return VOS_STATUS_E_FAULT;
3081 }
3082
3083 init_completion(&context.completion);
3084 context.pAdapter = pAdapter;
3085 context.magic = STATS_CONTEXT_MAGIC;
3086 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3087 eCSR_HDD,
3088 SME_GLOBAL_CLASSA_STATS,
3089 hdd_GetClassA_statisticsCB,
3090 0, // not periodic
3091 FALSE, //non-cached results
3092 staid,
3093 &context);
3094 if (eHAL_STATUS_SUCCESS != hstatus)
3095 {
3096 hddLog(VOS_TRACE_LEVEL_ERROR,
3097 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003098 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003099 }
3100 else
3101 {
3102 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3103 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003104 if (lrc <= 0)
3105 {
3106 hddLog(VOS_TRACE_LEVEL_ERROR,
3107 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003108 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 }
3110 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003111
3112 /* either we never sent a request, we sent a request and received a
3113 response or we sent a request and timed out. if we never sent a
3114 request or if we sent a request and got a response, we want to
3115 clear the magic out of paranoia. if we timed out there is a
3116 race condition such that the callback function could be
3117 executing at the same time we are. of primary concern is if the
3118 callback function had already verified the "magic" but had not
3119 yet set the completion variable when a timeout occurred. we
3120 serialize these activities by invalidating the magic while
3121 holding a shared spinlock which will cause us to block if the
3122 callback is currently executing */
3123 spin_lock(&hdd_context_lock);
3124 context.magic = 0;
3125 spin_unlock(&hdd_context_lock);
3126
Jeff Johnson295189b2012-06-20 16:38:30 -07003127 return VOS_STATUS_SUCCESS;
3128}
3129
3130int iw_get_softap_linkspeed(struct net_device *dev,
3131 struct iw_request_info *info,
3132 union iwreq_data *wrqu,
3133 char *extra)
3134
3135{
3136 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303137 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003138 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003139 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303140 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003141 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303142 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003143 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
3144 VOS_STATUS status;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303145 int rc, valid;
3146
3147 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3148
3149 valid = wlan_hdd_validate_context(pHddCtx);
3150
3151 if (0 != valid)
3152 {
3153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3154 return valid;
3155 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003156
Arif Hussain6d2a3322013-11-17 19:50:10 -08003157 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussained667642013-10-27 23:01:14 -07003158 if (wrqu->data.length != MAC_ADDRESS_STR_LEN)
3159 {
3160 hddLog(LOG1, "Invalid length");
3161 return -EINVAL;
3162 }
3163 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3164 if(NULL == pmacAddress) {
3165 hddLog(LOG1, "unable to allocate memory");
3166 return -ENOMEM;
3167 }
3168 if (copy_from_user((void *)pmacAddress,
3169 wrqu->data.pointer, wrqu->data.length))
3170 {
3171 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3172 kfree(pmacAddress);
3173 return -EFAULT;
3174 }
3175
3176 status = hdd_string_to_hex (pmacAddress, wrqu->data.length, macAddress );
3177 kfree(pmacAddress);
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303178
3179 if (!VOS_IS_STATUS_SUCCESS(status ))
Jeff Johnson295189b2012-06-20 16:38:30 -07003180 {
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003182 }
3183
Kiet Lam61589852013-09-19 17:10:58 +05303184 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303185 * link speed for first connected client will be returned.
3186 */
Kiet Lam61589852013-09-19 17:10:58 +05303187 if (!VOS_IS_STATUS_SUCCESS(status ) || wrqu->data.length < 17)
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303188 {
3189 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3190 }
3191 else
3192 {
3193 status = hdd_softap_GetStaId(pHostapdAdapter,
3194 (v_MACADDR_t *)macAddress, (void *)(&staId));
3195 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003196
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303197 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003198 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003200 link_speed = 0;
3201 }
3202 else
3203 {
3204 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303205
Jeff Johnson295189b2012-06-20 16:38:30 -07003206 if (!VOS_IS_STATUS_SUCCESS(status ))
3207 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003209 return -EINVAL;
3210 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303211
3212 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3213 staId, &link_speed);
3214
3215 link_speed = link_speed / 10;
3216
3217 if (0 == link_speed)
3218 {
3219 /* The linkspeed returned by HAL is in units of 500kbps.
3220 * converting it to mbps.
3221 * This is required to support legacy firmware which does
3222 * not return link capacity.
3223 */
3224 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003226 }
3227
3228 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003229 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303230
Jeff Johnson295189b2012-06-20 16:38:30 -07003231 if ((rc < 0) || (rc >= len))
3232 {
3233 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303234 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003235 return -EIO;
3236 }
3237
3238 return 0;
3239}
3240
3241static const iw_handler hostapd_handler[] =
3242{
3243 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3244 (iw_handler) NULL, /* SIOCGIWNAME */
3245 (iw_handler) NULL, /* SIOCSIWNWID */
3246 (iw_handler) NULL, /* SIOCGIWNWID */
3247 (iw_handler) NULL, /* SIOCSIWFREQ */
3248 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3249 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303250 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003251 (iw_handler) NULL, /* SIOCSIWSENS */
3252 (iw_handler) NULL, /* SIOCGIWSENS */
3253 (iw_handler) NULL, /* SIOCSIWRANGE */
3254 (iw_handler) NULL, /* SIOCGIWRANGE */
3255 (iw_handler) NULL, /* SIOCSIWPRIV */
3256 (iw_handler) NULL, /* SIOCGIWPRIV */
3257 (iw_handler) NULL, /* SIOCSIWSTATS */
3258 (iw_handler) NULL, /* SIOCGIWSTATS */
3259 (iw_handler) NULL, /* SIOCSIWSPY */
3260 (iw_handler) NULL, /* SIOCGIWSPY */
3261 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3262 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3263 (iw_handler) NULL, /* SIOCSIWAP */
3264 (iw_handler) NULL, /* SIOCGIWAP */
3265 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3266 (iw_handler) NULL, /* SIOCGIWAPLIST */
3267 (iw_handler) NULL, /* SIOCSIWSCAN */
3268 (iw_handler) NULL, /* SIOCGIWSCAN */
3269 (iw_handler) NULL, /* SIOCSIWESSID */
3270 (iw_handler) NULL, /* SIOCGIWESSID */
3271 (iw_handler) NULL, /* SIOCSIWNICKN */
3272 (iw_handler) NULL, /* SIOCGIWNICKN */
3273 (iw_handler) NULL, /* -- hole -- */
3274 (iw_handler) NULL, /* -- hole -- */
3275 (iw_handler) NULL, /* SIOCSIWRATE */
3276 (iw_handler) NULL, /* SIOCGIWRATE */
3277 (iw_handler) NULL, /* SIOCSIWRTS */
3278 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3279 (iw_handler) NULL, /* SIOCSIWFRAG */
3280 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3281 (iw_handler) NULL, /* SIOCSIWTXPOW */
3282 (iw_handler) NULL, /* SIOCGIWTXPOW */
3283 (iw_handler) NULL, /* SIOCSIWRETRY */
3284 (iw_handler) NULL, /* SIOCGIWRETRY */
3285 (iw_handler) NULL, /* SIOCSIWENCODE */
3286 (iw_handler) NULL, /* SIOCGIWENCODE */
3287 (iw_handler) NULL, /* SIOCSIWPOWER */
3288 (iw_handler) NULL, /* SIOCGIWPOWER */
3289 (iw_handler) NULL, /* -- hole -- */
3290 (iw_handler) NULL, /* -- hole -- */
3291 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3292 (iw_handler) NULL, /* SIOCGIWGENIE */
3293 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3294 (iw_handler) NULL, /* SIOCGIWAUTH */
3295 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3296 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3297 (iw_handler) NULL, /* SIOCSIWPMKSA */
3298};
3299
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08003300#define IW_PRIV_TYPE_OPTIE (IW_PRIV_TYPE_BYTE | QCSAP_MAX_OPT_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07003301#define IW_PRIV_TYPE_MLME \
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08003302 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
Jeff Johnson295189b2012-06-20 16:38:30 -07003303
3304static const struct iw_priv_args hostapd_private_args[] = {
3305 { QCSAP_IOCTL_SETPARAM,
3306 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3307 { QCSAP_IOCTL_SETPARAM,
3308 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3309 { QCSAP_PARAM_MAX_ASSOC,
3310 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3311 { QCSAP_PARAM_HIDE_SSID,
3312 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003313 { QCSAP_PARAM_SET_MC_RATE,
3314 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003315 { QCSAP_IOCTL_GETPARAM,
3316 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3317 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3318 { QCSAP_IOCTL_GETPARAM, 0,
3319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3320 { QCSAP_PARAM_MAX_ASSOC, 0,
3321 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003322 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3323 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3324 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003326 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
3327 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
3328 { QCSAP_PARAM_CLR_ACL, 0,
3329 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3330 { QCSAP_PARAM_ACL_MODE,
3331 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
3332 { QCSAP_IOCTL_COMMIT,
3333 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
3334 { QCSAP_IOCTL_SETMLME,
3335 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
3336 { QCSAP_IOCTL_GET_STAWPAIE,
3337 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3338 { QCSAP_IOCTL_SETWPAIE,
3339 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3340 { QCSAP_IOCTL_STOPBSS,
3341 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3342 { QCSAP_IOCTL_VERSION, 0,
3343 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003344 { QCSAP_IOCTL_GET_STA_INFO, 0,
3345 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003346 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003347 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003348 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003349 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003350 { QCSAP_IOCTL_ASSOC_STA_MACADDR, 0,
3351 IW_PRIV_TYPE_BYTE | /*((WLAN_MAX_STA_COUNT*6)+100)*/1 , "get_assoc_stamac" },
3352 { QCSAP_IOCTL_DISASSOC_STA,
3353 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
3354 { QCSAP_IOCTL_AP_STATS,
3355 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
3356 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3357 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303358 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003359
3360 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3361 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3362 /* handlers for sub-ioctl */
3363 { WE_SET_WLAN_DBG,
3364 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3365 0,
3366 "setwlandbg" },
3367
3368 /* handlers for main ioctl */
3369 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3370 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3371 0,
3372 "" },
3373
3374 /* handlers for sub-ioctl */
3375 { WE_LOG_DUMP_CMD,
3376 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3377 0,
3378 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003379 { WE_P2P_NOA_CMD,
3380 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3381 0,
3382 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003383 /* handlers for sub ioctl */
3384 {
3385 WE_MCC_CONFIG_CREDENTIAL,
3386 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3387 0,
3388 "setMccCrdnl" },
3389
3390 /* handlers for sub ioctl */
3391 {
3392 WE_MCC_CONFIG_PARAMS,
3393 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3394 0,
3395 "setMccConfig" },
3396
Jeff Johnson295189b2012-06-20 16:38:30 -07003397 /* handlers for main ioctl */
3398 { QCSAP_IOCTL_MODIFY_ACL,
3399 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3400 0,
3401 "modify_acl" },
3402
3403 /* handlers for main ioctl */
3404 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3405 0,
3406 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3407 "getChannelList" },
3408
Jeff Johnsone7245742012-09-05 17:12:55 -07003409 /* handlers for main ioctl */
3410 { QCSAP_IOCTL_SET_TX_POWER,
3411 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3412 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303413 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003414
3415 /* handlers for main ioctl */
3416 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3417 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3418 0,
3419 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303420
3421 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3422 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3423 0,
3424 "dataSnapshot" },
3425
3426 /* handlers for main ioctl */
3427 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3428 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3429 0,
3430 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003431};
Jeff Johnsone7245742012-09-05 17:12:55 -07003432
Jeff Johnson295189b2012-06-20 16:38:30 -07003433static const iw_handler hostapd_private[] = {
3434 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3435 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
3436 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
3437 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
3438 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3439 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3440 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3441 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3442 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3443 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3444 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3445 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3446 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3447 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3448 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3449 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3450 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3451 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003452 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003453 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3454 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003455 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303456 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303457 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003458};
3459const struct iw_handler_def hostapd_handler_def = {
3460 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3461 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3462 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3463 .standard = (iw_handler *)hostapd_handler,
3464 .private = (iw_handler *)hostapd_private,
3465 .private_args = hostapd_private_args,
3466 .get_wireless_stats = NULL,
3467};
3468#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3469struct net_device_ops net_ops_struct = {
3470 .ndo_open = hdd_hostapd_open,
3471 .ndo_stop = hdd_hostapd_stop,
3472 .ndo_uninit = hdd_hostapd_uninit,
3473 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3474 .ndo_tx_timeout = hdd_softap_tx_timeout,
3475 .ndo_get_stats = hdd_softap_stats,
3476 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3477 .ndo_do_ioctl = hdd_hostapd_ioctl,
3478 .ndo_change_mtu = hdd_hostapd_change_mtu,
3479 .ndo_select_queue = hdd_hostapd_select_queue,
3480 };
3481#endif
3482
3483int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3484{
3485 return VOS_STATUS_SUCCESS;
3486}
3487
3488void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3489{
3490#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3491 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3492#else
3493 pWlanHostapdDev->open = hdd_hostapd_open;
3494 pWlanHostapdDev->stop = hdd_hostapd_stop;
3495 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3496 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3497 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3498 pWlanHostapdDev->get_stats = hdd_softap_stats;
3499 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3500 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3501#endif
3502}
3503
3504VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
3505{
3506 hdd_hostapd_state_t * phostapdBuf;
3507 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003508 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003509 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08003510#ifdef FEATURE_WLAN_CH_AVOID
3511 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3512 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
3513 v_U16_t unsafeChannelCount;
3514#endif /* FEATURE_WLAN_CH_AVOID */
3515
Jeff Johnson295189b2012-06-20 16:38:30 -07003516 ENTER();
3517 // Allocate the Wireless Extensions state structure
3518 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
3519
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003520 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
3521
Leo Chang0b0e45a2013-12-15 15:18:55 -08003522#ifdef FEATURE_WLAN_CH_AVOID
3523 /* Get unsafe cahnnel list from cached location */
3524 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
3525 sizeof(unsafeChannelList),
3526 &unsafeChannelCount);
3527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3528 "%s : Unsafe Channel count %d",
3529 __func__, unsafeChannelCount);
3530 hdd_hostapd_update_unsafe_channel_list(pVosContext,
3531 unsafeChannelList,
3532 unsafeChannelCount);
3533#endif /* FEATURE_WLAN_CH_AVOID */
3534
Jeff Johnson295189b2012-06-20 16:38:30 -07003535 // Zero the memory. This zeros the profile structure.
3536 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
3537
3538 // Set up the pointer to the Wireless Extensions state structure
3539 // NOP
3540 status = hdd_set_hostapd(pAdapter);
3541 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003543 return status;
3544 }
3545
3546 status = vos_event_init(&phostapdBuf->vosEvent);
3547 if (!VOS_IS_STATUS_SUCCESS(status))
3548 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003550 return status;
3551 }
3552
3553 init_completion(&pAdapter->session_close_comp_var);
3554 init_completion(&pAdapter->session_open_comp_var);
3555
3556 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
3557
3558 // Register as a wireless device
3559 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
3560
3561 //Initialize the data path module
3562 status = hdd_softap_init_tx_rx(pAdapter);
3563 if ( !VOS_IS_STATUS_SUCCESS( status ))
3564 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003565 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003566 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303567
3568 status = hdd_wmm_adapter_init( pAdapter );
3569 if (!VOS_IS_STATUS_SUCCESS(status))
3570 {
3571 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003572 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303573 status, status );
3574 goto error_wmm_init;
3575 }
3576
3577 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3578
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303580
3581 return status;
3582
3583error_wmm_init:
3584 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003585 EXIT();
3586 return status;
3587}
3588
3589hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
3590{
3591 struct net_device *pWlanHostapdDev = NULL;
3592 hdd_adapter_t *pHostapdAdapter = NULL;
3593 v_CONTEXT_t pVosContext= NULL;
3594
Jeff Johnson295189b2012-06-20 16:38:30 -07003595 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07003596
3597 if (pWlanHostapdDev != NULL)
3598 {
3599 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
3600
3601 //Init the net_device structure
3602 ether_setup(pWlanHostapdDev);
3603
3604 //Initialize the adapter context to zeros.
3605 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
3606 pHostapdAdapter->dev = pWlanHostapdDev;
3607 pHostapdAdapter->pHddCtx = pHddCtx;
3608 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3609
3610 //Get the Global VOSS context.
3611 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3612 //Save the adapter context in global context for future.
3613 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3614
3615 //Init the net_device structure
3616 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3617
3618 hdd_set_ap_ops( pHostapdAdapter->dev );
3619
Jeff Johnson295189b2012-06-20 16:38:30 -07003620 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3621 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3622
3623 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3624 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3625
3626 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3628 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3629 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3630 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003631 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3632 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
3633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3634 init_completion(&pHostapdAdapter->offchannel_tx_event);
3635#endif
3636
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3638 }
3639 return pHostapdAdapter;
3640}
3641
3642VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3643{
3644 struct net_device *dev = pAdapter->dev;
3645 VOS_STATUS status = VOS_STATUS_SUCCESS;
3646
3647 ENTER();
3648
3649 if( rtnl_lock_held )
3650 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003651 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003652 if( dev_alloc_name(dev, dev->name) < 0 )
3653 {
3654 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3655 return VOS_STATUS_E_FAILURE;
3656 }
3657 }
3658 if (register_netdevice(dev))
3659 {
3660 hddLog(VOS_TRACE_LEVEL_FATAL,
3661 "%s:Failed:register_netdevice", __func__);
3662 return VOS_STATUS_E_FAILURE;
3663 }
3664 }
3665 else
3666 {
3667 if (register_netdev(dev))
3668 {
3669 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3670 return VOS_STATUS_E_FAILURE;
3671 }
3672 }
3673 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3674
3675 EXIT();
3676 return status;
3677}
3678
3679VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3680{
3681 ENTER();
3682
3683 hdd_softap_deinit_tx_rx(pAdapter);
3684
3685 /* if we are being called during driver unload, then the dev has already
3686 been invalidated. if we are being called at other times, then we can
3687 detatch the wireless device handlers */
3688 if (pAdapter->dev)
3689 {
3690 pAdapter->dev->wireless_handlers = NULL;
3691 }
3692 EXIT();
3693 return 0;
3694}