blob: 688ce1735c02492b5f9adc87798e96fd25c3ce57 [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
97#define IS_UP(_dev) \
98 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
99#define IS_UP_AUTO(_ic) \
100 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
101#define WE_WLAN_VERSION 1
102#define STATS_CONTEXT_MAGIC 0x53544154
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -0700103#define WE_GET_STA_INFO_SIZE 30
104/* WEXT limition: MAX allowed buf len for any *
105 * IW_PRIV_TYPE_CHAR is 2Kbytes *
106 */
107#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700110
Jeff Johnson295189b2012-06-20 16:38:30 -0700111/*---------------------------------------------------------------------------
112 * Function definitions
113 *-------------------------------------------------------------------------*/
114/**---------------------------------------------------------------------------
115
116 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
117
118 This is called in response to ifconfig up
119
120 \param - dev Pointer to net_device structure
121
122 \return - 0 for success non-zero for failure
123
124 --------------------------------------------------------------------------*/
125int hdd_hostapd_open (struct net_device *dev)
126{
127 ENTER();
128
129 //Turn ON carrier state
130 netif_carrier_on(dev);
131 //Enable all Tx queues
132 netif_tx_start_all_queues(dev);
133
134 EXIT();
135 return 0;
136}
137/**---------------------------------------------------------------------------
138
139 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
140
141 This is called in response to ifconfig down
142
143 \param - dev Pointer to net_device structure
144
145 \return - 0 for success non-zero for failure
146
147 --------------------------------------------------------------------------*/
148int hdd_hostapd_stop (struct net_device *dev)
149{
150 ENTER();
151
152 //Stop all tx queues
153 netif_tx_disable(dev);
154
155 //Turn OFF carrier state
156 netif_carrier_off(dev);
157
158 EXIT();
159 return 0;
160}
161/**---------------------------------------------------------------------------
162
163 \brief hdd_hostapd_uninit() - HDD uninit function
164
165 This is called during the netdev unregister to uninitialize all data
166associated with the device
167
168 \param - dev Pointer to net_device structure
169
170 \return - void
171
172 --------------------------------------------------------------------------*/
173static void hdd_hostapd_uninit (struct net_device *dev)
174{
175 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
176
177 ENTER();
178
179 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
180 {
181 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
182
183 /* after uninit our adapter structure will no longer be valid */
184 pHostapdAdapter->dev = NULL;
185 }
186
187 EXIT();
188}
189
190
191/**============================================================================
192 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
193 transmitting packets. There are 2 versions of this function. One that uses
194 locked queue and other that uses lockless queues. Both have been retained to
195 do some performance testing
196 @param skb : [in] pointer to OS packet (sk_buff)
197 @param dev : [in] pointer to Libra network device
198
199 @return : NET_XMIT_DROP if packets are dropped
200 : NET_XMIT_SUCCESS if packet is enqueued succesfully
201 ===========================================================================*/
202int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
203{
204 return 0;
205}
206int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
207{
208 return 0;
209}
210
211int hdd_hostapd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
212{
213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
214 hdd_priv_data_t priv_data;
215 tANI_U8 *command = NULL;
216 int ret = 0;
217
218 if (NULL == pAdapter)
219 {
220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700221 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 ret = -ENODEV;
223 goto exit;
224 }
225
Jeff Johnsone7245742012-09-05 17:12:55 -0700226 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -0700227 {
228 ret = -EINVAL;
229 goto exit;
230 }
231
232 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
233 {
234 ret = -EFAULT;
235 goto exit;
236 }
237
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800238 if (priv_data.total_len <= 0 ||
239 priv_data.total_len == INT_MAX)
240 {
241 /* below we allocate one more byte for command buffer.
242 * To avoid addition overflow total_len should be
243 * smaller than INT_MAX. */
244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800245 "%s: integer out of range", __func__);
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800246 ret = -EFAULT;
247 goto exit;
248 }
249
250 command = kmalloc((priv_data.total_len + 1), GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700251 if (!command)
252 {
253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800254 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 ret = -ENOMEM;
256 goto exit;
257 }
258
259 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
260 {
261 ret = -EFAULT;
262 goto exit;
263 }
264
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800265 command[priv_data.total_len] = '\0';
266
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 if ((SIOCDEVPRIVATE + 1) == cmd)
268 {
Agarwal Ashish8518d5d2013-12-05 20:16:44 +0530269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if(strncmp(command, "P2P_SET_NOA", 11) == 0 )
273 {
274 hdd_setP2pNoa(dev, command);
275 }
276 else if( strncmp(command, "P2P_SET_PS", 10) == 0 )
277 {
278 hdd_setP2pOpps(dev, command);
279 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700280
281 /*
282 command should be a string having format
283 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
284 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700285 if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700286 {
287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700288 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700289
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -0800290 ret = sapSetPreferredChannel(command);
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700291 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700292 }
293exit:
294 if (command)
295 {
296 kfree(command);
297 }
298 return ret;
299}
300
301/**---------------------------------------------------------------------------
302
303 \brief hdd_hostapd_set_mac_address() -
304 This function sets the user specified mac address using
305 the command ifconfig wlanX hw ether <mac adress>.
306
307 \param - dev - Pointer to the net device.
308 - addr - Pointer to the sockaddr.
309 \return - 0 for success, non zero for failure
310
311 --------------------------------------------------------------------------*/
312
313static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
314{
315 struct sockaddr *psta_mac_addr = addr;
316 ENTER();
317 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
318 EXIT();
319 return 0;
320}
321void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
322{
323 struct net_device *dev = (struct net_device *)usrDataForCallback;
324 v_BYTE_t we_custom_event[64];
325 union iwreq_data wrqu;
326#ifdef DISABLE_CONCURRENCY_AUTOSAVE
327 VOS_STATUS vos_status;
328 hdd_adapter_t *pHostapdAdapter;
329 hdd_ap_ctx_t *pHddApCtx;
330#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
331
332 /* event_name space-delimiter driver_module_name */
333 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
334 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
335 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
336
337 ENTER();
338
339#ifdef DISABLE_CONCURRENCY_AUTOSAVE
340 if (vos_concurrent_sessions_running())
341 {
342 /*
343 This timer routine is going to be called only when AP
344 persona is up.
345 If there are concurrent sessions running we do not want
346 to shut down the Bss.Instead we run the timer again so
347 that if Autosave is enabled next time and other session
348 was down only then we bring down AP
349 */
350 pHostapdAdapter = netdev_priv(dev);
351 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
352 vos_status = vos_timer_start(
353 &pHddApCtx->hdd_ap_inactivity_timer,
354 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
355 * 1000);
356 if (!VOS_IS_STATUS_SUCCESS(vos_status))
357 {
358 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
359 }
360 EXIT();
361 return;
362 }
363#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
364 memset(&we_custom_event, '\0', sizeof(we_custom_event));
365 memcpy(&we_custom_event, autoShutEvent, event_len);
366
367 memset(&wrqu, 0, sizeof(wrqu));
368 wrqu.data.length = event_len;
369
370 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
371 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
372
373 EXIT();
374}
375
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800376VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
377{
378 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
379 ptSapContext pSapCtx = NULL;
380 eHalStatus halStatus = eHAL_STATUS_FAILURE;
381 v_PVOID_t hHal = NULL;
382
383 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
384 "%s: UPDATE Beacon Params", __func__);
385
386 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
387 pSapCtx = VOS_GET_SAP_CB(pVosContext);
388 if ( NULL == pSapCtx )
389 {
390 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
391 "%s: Invalid SAP pointer from pvosGCtx", __func__);
392 return VOS_STATUS_E_FAULT;
393 }
394
395 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
396 if ( NULL == hHal ){
397 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
398 "%s: Invalid HAL pointer from pvosGCtx", __func__);
399 return VOS_STATUS_E_FAULT;
400 }
401 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
402 if(halStatus == eHAL_STATUS_FAILURE ){
403 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
404 "%s: Failed to update Beacon Params", __func__);
405 return VOS_STATUS_E_FAILURE;
406 }
407 }
408 return VOS_STATUS_SUCCESS;
409}
410
411void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
412{
413 v_U8_t staId = 0;
414 struct net_device *dev;
415 dev = (struct net_device *)usrDataForCallback;
416
Arif Hussain6d2a3322013-11-17 19:50:10 -0800417 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800418 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
419 {
420 if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
421 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
422 {
423 //Disconnect all the stations
424 hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
425 }
426 }
427}
428
429static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
430{
431 struct net_device *dev;
432 VOS_STATUS status = VOS_STATUS_SUCCESS;
433 dev = (struct net_device *)usrDataForCallback;
434 ENTER();
435 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
436 {
437 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
438 {
439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
440 }
441 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
442 }
443 EXIT();
444 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
445}
Jeff Johnson295189b2012-06-20 16:38:30 -0700446
447VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
448{
449 hdd_adapter_t *pHostapdAdapter;
450 hdd_ap_ctx_t *pHddApCtx;
451 hdd_hostapd_state_t *pHostapdState;
452 struct net_device *dev;
453 eSapHddEvent sapEvent;
454 union iwreq_data wrqu;
455 v_BYTE_t *we_custom_event_generic = NULL;
456 int we_event = 0;
457 int i = 0;
458 v_U8_t staId;
459 VOS_STATUS vos_status;
460 v_BOOL_t bWPSState;
461 v_BOOL_t bApActive = FALSE;
462 v_BOOL_t bAuthRequired = TRUE;
463 tpSap_AssocMacAddr pAssocStasArray = NULL;
464 char unknownSTAEvent[IW_CUSTOM_MAX+1];
465 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
466 v_BYTE_t we_custom_start_event[64];
467 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800468 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800469 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700470 struct iw_michaelmicfailure msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700471
472 dev = (struct net_device *)usrDataForCallback;
473 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530474
475 if ((NULL == pHostapdAdapter) ||
476 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
477 {
478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
479 "invalid adapter or adapter has invalid magic");
480 return eHAL_STATUS_FAILURE;
481 }
482
Jeff Johnson295189b2012-06-20 16:38:30 -0700483 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
484 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
485 sapEvent = pSapEvent->sapHddEventCode;
486 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800487 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700488
489 switch(sapEvent)
490 {
491 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800492 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700493 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
494 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
495 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
496
497 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
498 vos_status = vos_event_set(&pHostapdState->vosEvent);
499
500 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
501 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700503 goto stopbss;
504 }
505 else
506 {
507 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
508 //@@@ need wep logic here to set privacy bit
509 hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
510 }
511
512 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
513 {
514 // AP Inactivity timer init and start
515 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
516 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
517 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800518 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700519
520 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
521 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800522 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700523
524 }
525 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
526 pHostapdState->bssState = BSS_START;
527
528 // Send current operating channel of SoftAP to BTC-ES
529 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
530
Jeff Johnson295189b2012-06-20 16:38:30 -0700531 //Check if there is any group key pending to set.
532 if( pHddApCtx->groupKey.keyLength )
533 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700534 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700535 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
536 &pHddApCtx->groupKey ) )
537 {
538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
539 "%s: WLANSAP_SetKeySta failed", __func__);
540 }
541 pHddApCtx->groupKey.keyLength = 0;
542 }
543 else if ( pHddApCtx->wepKey[0].keyLength )
544 {
545 int i=0;
546 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
547 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700548 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700549 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
550 &pHddApCtx->wepKey[i] ) )
551 {
552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
553 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
554 }
555 pHddApCtx->wepKey[i].keyLength = 0;
556 }
557 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700558 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
559 startBssEvent = "SOFTAP.enabled";
560 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
561 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
562 memset(&wrqu, 0, sizeof(wrqu));
563 wrqu.data.length = strlen(startBssEvent);
564 we_event = IWEVCUSTOM;
565 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700566 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700567 break; //Event will be sent after Switch-Case stmt
568
569 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800570 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700571 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
572
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700573 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700574 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700575
Jeff Johnson295189b2012-06-20 16:38:30 -0700576 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700577 goto stopbss;
578 case eSAP_STA_SET_KEY_EVENT:
579 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800580 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700581 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
582 return VOS_STATUS_SUCCESS;
583 case eSAP_STA_DEL_KEY_EVENT:
584 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800585 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700586 return VOS_STATUS_SUCCESS;
587 case eSAP_STA_MIC_FAILURE_EVENT:
588 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700589 memset(&msg, '\0', sizeof(msg));
590 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800591 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800592 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700593 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700594 msg.flags = IW_MICFAILURE_GROUP;
595 else
596 msg.flags = IW_MICFAILURE_PAIRWISE;
597 memset(&wrqu, 0, sizeof(wrqu));
598 wrqu.data.length = sizeof(msg);
599 we_event = IWEVMICHAELMICFAILURE;
600 we_custom_event_generic = (v_BYTE_t *)&msg;
601 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 /* inform mic failure to nl80211 */
603 cfg80211_michael_mic_failure(dev,
604 pSapEvent->sapevt.
605 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700606 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700607 NL80211_KEYTYPE_GROUP :
608 NL80211_KEYTYPE_PAIRWISE),
609 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
610 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
611 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 break;
613
614 case eSAP_STA_ASSOC_EVENT:
615 case eSAP_STA_REASSOC_EVENT:
616 wrqu.addr.sa_family = ARPHRD_ETHER;
617 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800618 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800619 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700620 we_event = IWEVREGISTERED;
621
622 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
623
624 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
625 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
626 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
627 {
628 bAuthRequired = FALSE;
629 }
630
631 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
632 {
633 hdd_softap_RegisterSTA( pHostapdAdapter,
634 TRUE,
635 pHddApCtx->uPrivacy,
636 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
637 0,
638 0,
639 (v_MACADDR_t *)wrqu.addr.sa_data,
640 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
641 }
642 else
643 {
644 hdd_softap_RegisterSTA( pHostapdAdapter,
645 FALSE,
646 pHddApCtx->uPrivacy,
647 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
648 0,
649 0,
650 (v_MACADDR_t *)wrqu.addr.sa_data,
651 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
Amar Singhal6144c002013-05-03 16:11:42 -0700652 }
653
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 // Stop AP inactivity timer
655 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
656 {
657 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
658 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800659 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700660 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800661#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800662 if (wake_lock_active(&pHddCtx->sap_wake_lock))
663 {
664 wake_unlock(&pHddCtx->sap_wake_lock);
665 }
Amar Singhal6144c002013-05-03 16:11:42 -0700666 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800667#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
669 {
670 struct station_info staInfo;
671 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
672
673 memset(&staInfo, 0, sizeof(staInfo));
674 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
675 {
676 staInfo.assoc_req_ies =
677 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
678 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700679#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700680 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
681#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700682 cfg80211_new_sta(dev,
683 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
684 &staInfo, GFP_KERNEL);
685 }
686 else
687 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800688 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 }
690 }
691#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800692 pScanInfo = &pHddCtx->scan_info;
693 // Lets do abort scan to ensure smooth authentication for client
694 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
695 {
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +0530696 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800697 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700698
699 break;
700 case eSAP_STA_DISASSOC_EVENT:
701 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800702 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800703 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
705 hddLog(LOG1," User initiated disassociation");
706 else
707 hddLog(LOG1," MAC initiated disassociation");
708 we_event = IWEVEXPIRED;
709 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
710 if (!VOS_IS_STATUS_SUCCESS(vos_status))
711 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700712 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 -0700713 return VOS_STATUS_E_FAILURE;
714 }
715 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
716
717 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
718 {
719 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
720 // Start AP inactivity timer if no stations associated with it
721 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
722 {
723 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
724 {
725 bApActive = TRUE;
726 break;
727 }
728 }
729 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
730
731 if (bApActive == FALSE)
732 {
733 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
734 {
735 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
736 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800737 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 }
739 else
740 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
741 }
742 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
744 cfg80211_del_sta(dev,
745 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
746 GFP_KERNEL);
747#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800748 //Update the beacon Interval if it is P2P GO
749 hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700750 break;
751 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
752 {
753 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
754 union iwreq_data wreq;
755
756 down(&pHddApCtx->semWpsPBCOverlapInd);
757 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
758
759 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
760 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
761
762 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800763 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 memset(&wreq, 0, sizeof(wreq));
765 wreq.data.length = strlen(message); // This is length of message
766 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
767
768 return VOS_STATUS_SUCCESS;
769 }
770 case eSAP_ASSOC_STA_CALLBACK_EVENT:
771 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
772 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
773 { // List of associated stations
774 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
775 {
776 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
777 i+1,
778 pAssocStasArray->assocId,
779 pAssocStasArray->staId,
780 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
781 pAssocStasArray++;
782 }
783 }
784 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800785 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700787 case eSAP_INDICATE_MGMT_FRAME:
788 hdd_indicateMgmtFrame( pHostapdAdapter,
789 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
790 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
791 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530792 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 return VOS_STATUS_SUCCESS;
794 case eSAP_REMAIN_CHAN_READY:
795 hdd_remainChanReadyHandler( pHostapdAdapter );
796 return VOS_STATUS_SUCCESS;
797 case eSAP_SEND_ACTION_CNF:
798 hdd_sendActionCnf( pHostapdAdapter,
799 ( eSAP_STATUS_SUCCESS ==
800 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
801 TRUE : FALSE );
802 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700803 case eSAP_UNKNOWN_STA_JOIN:
804 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
805 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
806 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
807 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
808 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
809 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
810 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
811 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
812 wrqu.data.pointer = unknownSTAEvent;
813 wrqu.data.length = strlen(unknownSTAEvent);
814 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -0800815 hddLog(LOG1,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700816 break;
817
818 case eSAP_MAX_ASSOC_EXCEEDED:
819 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
820 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
821 " one or more devices to enable the new device connection",
822 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
823 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
824 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
825 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
826 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
827 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
828 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
829 wrqu.data.pointer = maxAssocExceededEvent;
830 wrqu.data.length = strlen(maxAssocExceededEvent);
831 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -0800832 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 break;
834 case eSAP_STA_ASSOC_IND:
835 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800836
837 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800838 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800839 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
840 return VOS_STATUS_SUCCESS;
841
842 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
843 hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
844 return VOS_STATUS_SUCCESS;
845
Jeff Johnson295189b2012-06-20 16:38:30 -0700846 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800847 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 goto stopbss;
849 return VOS_STATUS_SUCCESS;
850 }
851 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
852 return VOS_STATUS_SUCCESS;
853
854stopbss :
855 {
856 v_BYTE_t we_custom_event[64];
857 char *stopBssEvent = "STOP-BSS.response";//17
858 int event_len = strlen(stopBssEvent);
859
860 hddLog(LOG1, FL("BSS stop status = %s"),
861 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
862 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
863
864 /* Change the BSS state now since, as we are shutting things down,
865 * we don't want interfaces to become re-enabled */
866 pHostapdState->bssState = BSS_STOP;
867
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +0530868 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
869 {
870 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
871 {
872 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
873 if (!VOS_IS_STATUS_SUCCESS(vos_status))
874 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
875 }
876
877 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
878 if (!VOS_IS_STATUS_SUCCESS(vos_status))
879 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
880 }
881
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 /* Stop the pkts from n/w stack as we are going to free all of
883 * the TX WMM queues for all STAID's */
884 hdd_hostapd_stop(dev);
885
886 /* reclaim all resources allocated to the BSS */
887 hdd_softap_stop_bss(pHostapdAdapter);
888
Amar Singhal37e6f052013-03-05 16:16:54 -0800889 /* once the event is set, structure dev/pHostapdAdapter should
890 * not be touched since they are now subject to being deleted
891 * by another thread */
892 if (eSAP_STOP_BSS_EVENT == sapEvent)
893 vos_event_set(&pHostapdState->vosEvent);
894
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 /* notify userspace that the BSS has stopped */
896 memset(&we_custom_event, '\0', sizeof(we_custom_event));
897 memcpy(&we_custom_event, stopBssEvent, event_len);
898 memset(&wrqu, 0, sizeof(wrqu));
899 wrqu.data.length = event_len;
900 we_event = IWEVCUSTOM;
901 we_custom_event_generic = we_custom_event;
902 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700903 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700904 }
905 return VOS_STATUS_SUCCESS;
906}
907int hdd_softap_unpackIE(
908 tHalHandle halHandle,
909 eCsrEncryptionType *pEncryptType,
910 eCsrEncryptionType *mcEncryptType,
911 eCsrAuthType *pAuthType,
912 u_int16_t gen_ie_len,
913 u_int8_t *gen_ie )
914{
915 tDot11fIERSN dot11RSNIE;
916 tDot11fIEWPA dot11WPAIE;
917
918 tANI_U8 *pRsnIe;
919 tANI_U16 RSNIeLen;
920
921 if (NULL == halHandle)
922 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800923 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 return -EINVAL;
925 }
926
927 // Validity checks
928 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
929 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
930 return -EINVAL;
931 // Type check
932 if ( gen_ie[0] == DOT11F_EID_RSN)
933 {
934 // Validity checks
935 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
936 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
937 {
938 return VOS_STATUS_E_FAILURE;
939 }
940 // Skip past the EID byte and length byte
941 pRsnIe = gen_ie + 2;
942 RSNIeLen = gen_ie_len - 2;
943 // Unpack the RSN IE
944 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
945 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
946 pRsnIe,
947 RSNIeLen,
948 &dot11RSNIE);
949 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -0800950 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700951 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -0800952 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700953 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 /*Here we have followed the apple base code,
955 but probably I suspect we can do something different*/
956 //dot11RSNIE.akm_suite_count
957 // Just translate the FIRST one
958 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
959 //dot11RSNIE.pwise_cipher_suite_count
960 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
961 //dot11RSNIE.gp_cipher_suite_count
962 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
963 // Set the PMKSA ID Cache for this interface
964
965 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
966 } else
967 if (gen_ie[0] == DOT11F_EID_WPA)
968 {
969 // Validity checks
970 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
971 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
972 {
973 return VOS_STATUS_E_FAILURE;
974 }
975 // Skip past the EID byte and length byte - and four byte WiFi OUI
976 pRsnIe = gen_ie + 2 + 4;
977 RSNIeLen = gen_ie_len - (2 + 4);
978 // Unpack the WPA IE
979 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
980 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
981 pRsnIe,
982 RSNIeLen,
983 &dot11WPAIE);
984 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -0800985 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700986 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -0800987 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700988 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 //dot11WPAIE.auth_suite_count
990 // Just translate the FIRST one
991 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
992 //dot11WPAIE.unicast_cipher_count
993 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
994 //dot11WPAIE.unicast_cipher_count
995 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
996 }
997 else
998 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800999 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 return VOS_STATUS_E_FAILURE;
1001 }
1002 return VOS_STATUS_SUCCESS;
1003}
Leo Chang614d2072013-08-22 14:59:44 -07001004
Jeff Johnson295189b2012-06-20 16:38:30 -07001005int
1006static iw_softap_setparam(struct net_device *dev,
1007 struct iw_request_info *info,
1008 union iwreq_data *wrqu, char *extra)
1009{
1010 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1011 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1012 int *value = (int *)extra;
1013 int sub_cmd = value[0];
1014 int set_value = value[1];
1015 eHalStatus status;
1016 int ret = 0; /* success */
1017 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1018
1019 switch(sub_cmd)
1020 {
1021
1022 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001023 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001024 {
1025 ret = -EIO;
1026 }
1027 break;
1028
1029 case QCSAP_PARAM_ACL_MODE:
1030 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1031 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1032 {
1033 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1034 ret = -EINVAL;
1035 }
1036 else
1037 {
1038 WLANSAP_SetMode(pVosContext, set_value);
1039 }
1040 break;
1041 case QCSAP_PARAM_MAX_ASSOC:
1042 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1043 {
1044 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1045 ret = -EINVAL;
1046 }
1047 else
1048 {
1049 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1050 {
1051 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1052 "Setting it to max allowed and continuing"),
1053 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1054 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1055 }
1056 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1057 set_value, NULL, eANI_BOOLEAN_FALSE);
1058 if ( status != eHAL_STATUS_SUCCESS )
1059 {
1060 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1061 status);
1062 ret = -EIO;
1063 }
1064 }
1065 break;
1066
1067 case QCSAP_PARAM_HIDE_SSID:
1068 {
1069 eHalStatus status = eHAL_STATUS_SUCCESS;
1070 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1071 if(eHAL_STATUS_SUCCESS != status)
1072 {
1073 hddLog(VOS_TRACE_LEVEL_ERROR,
1074 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001075 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001076 return status;
1077 }
1078 break;
1079 }
1080
Leo Chang614d2072013-08-22 14:59:44 -07001081 case QCSAP_PARAM_SET_MC_RATE:
1082 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001083 tSirRateUpdateInd *rateUpdate;
1084
1085 rateUpdate = (tSirRateUpdateInd *)
1086 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1087 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001088 {
1089 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001090 "%s: SET_MC_RATE indication alloc fail", __func__);
1091 ret = -1;
1092 break;
1093 }
1094 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1095
1096 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1097 /* Ignore unicast */
1098 rateUpdate->ucastDataRate = -1;
1099 rateUpdate->mcastDataRate24GHz = set_value;
1100 rateUpdate->mcastDataRate5GHz = set_value;
1101 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1102 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1103 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1104 if (eHAL_STATUS_SUCCESS != status)
1105 {
1106 hddLog(VOS_TRACE_LEVEL_ERROR,
1107 "%s: SET_MC_RATE failed", __func__);
1108 vos_mem_free(rateUpdate);
1109 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001110 }
1111 break;
1112 }
1113
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 default:
1115 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1116 sub_cmd, set_value);
1117 ret = -EINVAL;
1118 break;
1119 }
1120
1121 return ret;
1122}
1123
1124
1125int
1126static iw_softap_getparam(struct net_device *dev,
1127 struct iw_request_info *info,
1128 union iwreq_data *wrqu, char *extra)
1129{
1130 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1131 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1132 int *value = (int *)extra;
1133 int sub_cmd = value[0];
1134 eHalStatus status;
1135 int ret = 0; /* success */
1136 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1137
1138 switch (sub_cmd)
1139 {
1140 case QCSAP_PARAM_MAX_ASSOC:
1141 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1142 if (eHAL_STATUS_SUCCESS != status)
1143 {
1144 ret = -EIO;
1145 }
1146 break;
1147
1148 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001149 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 {
1151 ret = -EIO;
1152 }
1153 *value = 0;
1154 break;
1155
1156 case QCSAP_PARAM_MODULE_DOWN_IND:
1157 {
1158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001159 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001160 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1161#ifdef WLAN_BTAMP_FEATURE
1162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001163 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001164 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1165#endif
1166 *value = 0;
1167 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001168 }
1169
1170 case QCSAP_PARAM_GET_WLAN_DBG:
1171 {
1172 vos_trace_display();
1173 *value = 0;
1174 break;
1175 }
1176
1177 case QCSAP_PARAM_AUTO_CHANNEL:
1178 {
1179 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1180 break;
1181 }
1182
Jeff Johnson295189b2012-06-20 16:38:30 -07001183 default:
1184 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1185 ret = -EINVAL;
1186 break;
1187
1188 }
1189
1190 return ret;
1191}
1192
1193/* Usage:
1194 BLACK_LIST = 0
1195 WHITE_LIST = 1
1196 ADD MAC = 0
1197 REMOVE MAC = 1
1198
1199 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1200 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1201 while using this ioctl
1202
1203 Syntax:
1204 iwpriv softap.0 modify_acl
1205 <6 octet mac addr> <list type> <cmd type>
1206
1207 Examples:
1208 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1209 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1210 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1211 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1212*/
1213int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1214 union iwreq_data *wrqu, char *extra)
1215{
1216 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1217 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1218 v_BYTE_t *value = (v_BYTE_t*)extra;
1219 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1220 int listType, cmd, i;
1221 int ret = 0; /* success */
1222
1223 ENTER();
1224 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1225 {
1226 pPeerStaMac[i] = *(value+i);
1227 }
1228 listType = (int)(*(value+i));
1229 i++;
1230 cmd = (int)(*(value+i));
1231
Arif Hussain24bafea2013-11-15 15:10:03 -08001232 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1233 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001234
1235 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1236 != VOS_STATUS_SUCCESS)
1237 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001238 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 ret = -EIO;
1240 }
1241 EXIT();
1242 return ret;
1243}
1244
1245int
1246static iw_softap_getchannel(struct net_device *dev,
1247 struct iw_request_info *info,
1248 union iwreq_data *wrqu, char *extra)
1249{
1250 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1251
Jeff Johnson43971f52012-07-17 12:26:56 -07001252 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001253
Jeff Johnson43971f52012-07-17 12:26:56 -07001254 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 return 0;
1256}
1257
Jeff Johnsone7245742012-09-05 17:12:55 -07001258int
schang86c22c42013-03-13 18:41:24 -07001259static iw_softap_set_max_tx_power(struct net_device *dev,
Jeff Johnsone7245742012-09-05 17:12:55 -07001260 struct iw_request_info *info,
1261 union iwreq_data *wrqu, char *extra)
1262{
1263 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1264 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001265 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001266 int set_value;
1267 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1268 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1269
schang86c22c42013-03-13 18:41:24 -07001270 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001271 return -ENOMEM;
1272
Leo Changd37675a2013-08-01 13:19:45 -07001273 /* Assign correct slef MAC address */
1274 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1275 VOS_MAC_ADDR_SIZE);
1276 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1277 VOS_MAC_ADDR_SIZE);
1278
schang86c22c42013-03-13 18:41:24 -07001279 set_value = value[0];
1280 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1281 {
1282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001283 __func__);
schang86c22c42013-03-13 18:41:24 -07001284 return -EIO;
1285 }
1286
1287 return 0;
1288}
1289
1290int
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301291static iw_display_data_path_snapshot(struct net_device *dev,
1292 struct iw_request_info *info,
1293 union iwreq_data *wrqu, char *extra)
1294{
1295
1296 /* Function intitiating dumping states of
1297 * HDD(WMM Tx Queues)
1298 * TL State (with Per Client infor)
1299 * DXE Snapshot (Called at the end of TL Snapshot)
1300 */
1301 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1302 hddLog(LOGE, "%s: called for SAP",__func__);
1303 hdd_wmm_tx_snapshot(pHostapdAdapter);
1304 WLANTL_TLDebugMessage(VOS_TRUE);
1305 return 0;
1306}
1307
1308int
schang86c22c42013-03-13 18:41:24 -07001309static iw_softap_set_tx_power(struct net_device *dev,
1310 struct iw_request_info *info,
1311 union iwreq_data *wrqu, char *extra)
1312{
1313 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1314 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1315 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1316 int *value = (int *)extra;
1317 int set_value;
1318 ptSapContext pSapCtx = NULL;
1319
1320 if (NULL == value)
1321 return -ENOMEM;
1322
1323 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1324 if (NULL == pSapCtx)
1325 {
1326 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1327 "%s: Invalid SAP pointer from pvosGCtx", __func__);
1328 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07001329 }
1330
1331 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07001332 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07001333 {
schang86c22c42013-03-13 18:41:24 -07001334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07001335 __func__);
1336 return -EIO;
1337 }
1338
1339 return 0;
1340}
1341
Kiet Lambcf38522013-10-26 18:28:27 +05301342/**---------------------------------------------------------------------------
1343
1344 \brief iw_softap_set_trafficmonitor() -
1345 This function dynamically enable/disable traffic monitor functonality
1346 the command iwpriv wlanX setTrafficMon <value>.
1347
1348 \param - dev - Pointer to the net device.
1349 - addr - Pointer to the sockaddr.
1350 \return - 0 for success, non zero for failure
1351
1352 --------------------------------------------------------------------------*/
1353
1354static int iw_softap_set_trafficmonitor(struct net_device *dev,
1355 struct iw_request_info *info,
1356 union iwreq_data *wrqu, char *extra)
1357{
1358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1359 int *isSetTrafficMon = (int *)wrqu->data.pointer;
1360 hdd_context_t *pHddCtx;
1361 int status;
1362
1363 if (NULL == pAdapter)
1364 {
1365 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1366 "%s: HDD adapter is Null", __func__);
1367 return -ENODEV;
1368 }
1369
1370 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1371
1372 status = wlan_hdd_validate_context(pHddCtx);
1373
1374 if (0 != status)
1375 {
1376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1377 "%s: HDD context is not valid", __func__);
1378 return status;
1379 }
1380
1381 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
1382
1383 if (NULL == isSetTrafficMon)
1384 {
1385 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1386 "%s: Invalid SAP pointer from extra", __func__);
1387 return -ENOMEM;
1388 }
1389
1390 if (TRUE == *isSetTrafficMon)
1391 {
1392 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
1393 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
1394 {
1395 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1396 "%s: failed to Start Traffic Monitor timer ", __func__ );
1397 return -EIO;
1398 }
1399 }
1400 else if (FALSE == *isSetTrafficMon)
1401 {
1402 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
1403 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
1404 {
1405 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1406 "%s: failed to Stop Traffic Monitor timer ", __func__ );
1407 return -EIO;
1408 }
1409
1410 }
1411 return 0;
1412}
1413
Jeff Johnson295189b2012-06-20 16:38:30 -07001414#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1415
1416int
1417static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1418 struct iw_request_info *info,
1419 union iwreq_data *wrqu, char *extra)
1420{
1421 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07001422 unsigned int maclist_index;
Jeff Johnson295189b2012-06-20 16:38:30 -07001423 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
Arif Hussained667642013-10-27 23:01:14 -07001424 char maclist_null = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 int cnt = 0, len;
1426
1427
Arif Hussained667642013-10-27 23:01:14 -07001428 maclist_index = sizeof(unsigned long int);
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 len = wrqu->data.length;
1430
1431 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
1432 while((cnt < WLAN_MAX_STA_COUNT) && (len > (sizeof(v_MACADDR_t)+1))) {
1433 if (TRUE == pStaInfo[cnt].isUsed) {
1434
1435 if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
Arif Hussained667642013-10-27 23:01:14 -07001436 if (copy_to_user((void *)wrqu->data.pointer + maclist_index,
1437 (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t)))
1438 {
1439 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1440 return -EFAULT;
1441 }
1442 maclist_index += sizeof(v_MACADDR_t);
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 len -= sizeof(v_MACADDR_t);
1444 }
1445 }
1446 cnt++;
1447 }
1448 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
1449
Arif Hussained667642013-10-27 23:01:14 -07001450 if (copy_to_user((void *)wrqu->data.pointer + maclist_index,
1451 (void *)&maclist_null, sizeof(maclist_null)) ||
1452 copy_to_user((void *)wrqu->data.pointer,
1453 (void *)&wrqu->data.length, sizeof(wrqu->data.length)))
1454 {
1455 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1456 return -EFAULT;
1457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 wrqu->data.length -= len;
1459
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 return 0;
1461}
1462
1463/* Usage:
1464 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1465 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1466 while using this ioctl
1467
1468 Syntax:
1469 iwpriv softap.0 disassoc_sta <6 octet mac address>
1470
1471 e.g.
1472 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1473 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1474*/
1475
1476int
1477static iw_softap_disassoc_sta(struct net_device *dev,
1478 struct iw_request_info *info,
1479 union iwreq_data *wrqu, char *extra)
1480{
1481 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1482 v_U8_t *peerMacAddr;
1483
1484 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301485 /* iwpriv tool or framework calls this ioctl with
1486 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301488 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07001489
Arif Hussain24bafea2013-11-15 15:10:03 -08001490 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
1491 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1493 EXIT();
1494 return 0;
1495}
1496
1497int
1498static iw_softap_ap_stats(struct net_device *dev,
1499 struct iw_request_info *info,
1500 union iwreq_data *wrqu, char *extra)
1501{
1502 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1503 WLANTL_TRANSFER_STA_TYPE statBuffer;
1504 char *pstatbuf;
1505 int len = wrqu->data.length;
1506 pstatbuf = wrqu->data.pointer;
1507
Arif Hussained667642013-10-27 23:01:14 -07001508 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
1509 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07001510
Arif Hussained667642013-10-27 23:01:14 -07001511 pstatbuf = kmalloc(wrqu->data.length, GFP_KERNEL);
1512 if(NULL == pstatbuf) {
1513 hddLog(LOG1, "unable to allocate memory");
1514 return -ENOMEM;
1515 }
1516 len = scnprintf(pstatbuf, wrqu->data.length,
1517 "RUF=%d RMF=%d RBF=%d "
1518 "RUB=%d RMB=%d RBB=%d "
1519 "TUF=%d TMF=%d TBF=%d "
1520 "TUB=%d TMB=%d TBB=%d",
1521 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
1522 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
1523 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1524 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
1525 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
1526 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07001527
Arif Hussained667642013-10-27 23:01:14 -07001528 if (len > wrqu->data.length ||
1529 copy_to_user((void *)wrqu->data.pointer, (void *)pstatbuf, len))
1530 {
1531 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1532 kfree(pstatbuf);
1533 return -EFAULT;
1534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 wrqu->data.length -= len;
Arif Hussained667642013-10-27 23:01:14 -07001536 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07001537 return 0;
1538}
1539
1540int
1541static iw_softap_commit(struct net_device *dev,
1542 struct iw_request_info *info,
1543 union iwreq_data *wrqu, char *extra)
1544{
1545 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1546 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1547 hdd_hostapd_state_t *pHostapdState;
1548 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1549 tpWLAN_SAPEventCB pSapEventCallback;
1550 tsap_Config_t *pConfig;
1551 s_CommitConfig_t *pCommitConfig;
1552 struct qc_mac_acl_entry *acl_entry = NULL;
1553 v_SINT_t i = 0, num_mac = 0;
1554 v_U32_t status = 0;
1555 eCsrAuthType RSNAuthType;
1556 eCsrEncryptionType RSNEncryptType;
1557 eCsrEncryptionType mcRSNEncryptType;
1558
1559 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1560 pCommitConfig = (s_CommitConfig_t *)extra;
1561
1562 pConfig = kmalloc(sizeof(tsap_Config_t), GFP_KERNEL);
1563 if(NULL == pConfig) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001564 hddLog(LOG1, "VOS unable to allocate memory");
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 return -ENOMEM;
1566 }
1567 pConfig->beacon_int = pCommitConfig->beacon_int;
1568 pConfig->channel = pCommitConfig->channel;
1569
1570 /*Protection parameter to enable or disable*/
1571 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1572 pConfig->dtim_period = pCommitConfig->dtim_period;
1573 switch(pCommitConfig->hw_mode )
1574 {
1575 case eQC_DOT11_MODE_11A:
1576 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
1577 break;
1578 case eQC_DOT11_MODE_11B:
1579 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
1580 break;
1581 case eQC_DOT11_MODE_11G:
1582 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
1583 break;
1584
1585 case eQC_DOT11_MODE_11N:
1586 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1587 break;
1588 case eQC_DOT11_MODE_11G_ONLY:
1589 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1590 break;
1591 case eQC_DOT11_MODE_11N_ONLY:
1592 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
1593 break;
1594 default:
1595 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1596 break;
1597
1598 }
1599
1600 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
1601 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
1602 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
1603 pConfig->authType = eSAP_SHARED_KEY;
1604 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
1605 pConfig->authType = eSAP_OPEN_SYSTEM;
1606 else
1607 pConfig->authType = eSAP_AUTO_SWITCH;
1608
1609 pConfig->privacy = pCommitConfig->privacy;
1610 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
1611 pConfig->wps_state = pCommitConfig->wps_state;
1612 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1613 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
1614 if(pConfig->RSNWPAReqIELength){
1615 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
1616 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
1617 // The actual processing may eventually be more extensive than this.
1618 // Right now, just consume any PMKIDs that are sent in by the app.
1619 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001620 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
Jeff Johnson295189b2012-06-20 16:38:30 -07001621 &RSNEncryptType,
1622 &mcRSNEncryptType,
1623 &RSNAuthType,
1624 pConfig->pRSNWPAReqIE[1]+2,
1625 pConfig->pRSNWPAReqIE );
1626
1627 if( VOS_STATUS_SUCCESS == status )
1628 {
1629 // Now copy over all the security attributes you have parsed out
1630 //TODO: Need to handle mixed mode
1631 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1632 pConfig->mcRSNEncryptType = mcRSNEncryptType;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001633 hddLog( LOG1, FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1635 }
1636 }
1637 }
1638 else
1639 {
1640 /* If no RSNIE, set encrypt type to NONE*/
1641 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1642 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001643 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
1645 }
1646
Chilam Ngc4244af2013-04-01 15:37:32 -07001647 if (pConfig->RSNWPAReqIELength > QCSAP_MAX_OPT_IE) {
1648 hddLog(LOGE, FL("RSNWPAReqIELength: %d too large"), pConfig->RSNWPAReqIELength);
1649 kfree(pConfig);
1650 return -EIO;
1651 }
1652
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
1654 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
1655 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
1656 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1657
1658 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
1659
1660 // ht_capab is not what the name conveys,this is used for protection bitmap
1661 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1662
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301663 if (pCommitConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1664 num_mac = pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 else
1666 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
1667 acl_entry = pCommitConfig->accept_mac;
1668 for (i = 0; i < num_mac; i++)
1669 {
1670 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1671 acl_entry++;
1672 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301673 if (pCommitConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1674 num_mac = pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001675 else
1676 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
1677 acl_entry = pCommitConfig->deny_mac;
1678 for (i = 0; i < num_mac; i++)
1679 {
1680 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1681 acl_entry++;
1682 }
1683 //Uapsd Enabled Bit
1684 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1685 //Enable OBSS protection
1686 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1687 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
1688
Arif Hussain6d2a3322013-11-17 19:50:10 -08001689 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1690 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
1691 pConfig->SSIDinfo.ssid.ssId,
1692 (int)pConfig->beacon_int, (int)pConfig->channel);
1693 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
1694 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
1695 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
1696 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
1697 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d, DisableIntraBssFwd = %d"),
1698 pConfig->protEnabled, pConfig->obssProtEnabled,
1699 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001700
1701 pSapEventCallback = hdd_hostapd_SAPEventCB;
1702 pConfig->persona = pHostapdAdapter->device_mode;
1703 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
1704 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001705 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 }
1707
1708 kfree(pConfig);
1709
1710 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1711 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1712
1713 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1714 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001715 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 -07001716 VOS_ASSERT(0);
1717 }
1718
1719 pHostapdState->bCommit = TRUE;
1720 if(pHostapdState->vosStatus)
1721 {
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001722 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001723 }
1724 else
1725 {
1726 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1727 WLANSAP_Update_WpsIe ( pVosContext );
1728 return 0;
1729 }
1730}
1731static
1732int iw_softap_setmlme(struct net_device *dev,
1733 struct iw_request_info *info,
1734 union iwreq_data *wrqu, char *extra)
1735{
1736 struct sQcSapreq_mlme *pmlme;
1737 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
1738 v_MACADDR_t destAddress;
1739 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
1740 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
1741 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
1742 switch(pmlme->im_op)
1743 {
1744 case QCSAP_MLME_AUTHORIZE:
1745 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
1746 break;
1747 case QCSAP_MLME_ASSOC:
1748 //TODO:inform to TL after associating (not needed as we do in sapCallback)
1749 break;
1750 case QCSAP_MLME_UNAUTHORIZE:
1751 //TODO: send the disassoc to station
1752 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
1753 break;
1754 case QCSAP_MLME_DISASSOC:
1755 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
1756 break;
1757 case QCSAP_MLME_DEAUTH:
1758 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
1759 break;
1760 case QCSAP_MLME_MICFAILURE:
1761 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
1762 break;
1763 default:
1764 break;
1765 }
1766 return 0;
1767}
1768
1769static int iw_softap_set_channel_range(struct net_device *dev,
1770 struct iw_request_info *info,
1771 union iwreq_data *wrqu, char *extra)
1772{
1773 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1774 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001775 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001776
1777 int *value = (int *)extra;
1778 int startChannel = value[0];
1779 int endChannel = value[1];
1780 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07001781 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 int ret = 0; /* success */
1783
1784 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
1785 if(status != VOS_STATUS_SUCCESS)
1786 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001787 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001788 startChannel,endChannel, band);
1789 ret = -EINVAL;
1790 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08001791
1792 pHddCtx->is_dynamic_channel_range_set = 1;
1793
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 return ret;
1795}
1796
1797int iw_softap_get_channel_list(struct net_device *dev,
1798 struct iw_request_info *info,
1799 union iwreq_data *wrqu, char *extra)
1800{
1801 v_U32_t num_channels = 0;
1802 v_U8_t i = 0;
1803 v_U8_t bandStartChannel = RF_CHAN_1;
1804 v_U8_t bandEndChannel = RF_CHAN_165;
1805 v_U32_t temp_num_channels = 0;
1806 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1807 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1808 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001809 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001810 eCsrBand curBand = eCSR_BAND_ALL;
1811
1812 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
1813 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001814 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001815 return -EIO;
1816 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001817 wrqu->data.length = sizeof(tChannelListInfo);
1818 ENTER();
1819
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001820 if (eCSR_BAND_24 == curBand)
1821 {
1822 bandStartChannel = RF_CHAN_1;
1823 bandEndChannel = RF_CHAN_14;
1824 }
1825 else if (eCSR_BAND_5G == curBand)
1826 {
1827 bandStartChannel = RF_CHAN_36;
1828 bandEndChannel = RF_CHAN_165;
1829 }
1830
Arif Hussain6d2a3322013-11-17 19:50:10 -08001831 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05301832 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001833 bandStartChannel, bandEndChannel );
1834
Jeff Johnson295189b2012-06-20 16:38:30 -07001835 for( i = bandStartChannel; i <= bandEndChannel; i++ )
1836 {
1837 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
1838 {
1839 channel_list->channels[num_channels] = rfChannels[i].channelNum;
1840 num_channels++;
1841 }
1842 }
1843
1844 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
1845
1846 temp_num_channels = num_channels;
1847
1848 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
1849 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001850 hddLog(LOG1,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001851 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 }
1853
1854 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
1855 {
1856 for(i = 0; i < temp_num_channels; i++)
1857 {
1858
1859 if((channel_list->channels[i] > 35) &&
1860 (channel_list->channels[i] < 49))
1861 {
1862 vos_mem_move(&channel_list->channels[i],
1863 &channel_list->channels[i+1],
1864 temp_num_channels - (i-1));
1865 num_channels--;
1866 temp_num_channels--;
1867 i--;
1868 }
1869 }
1870 }
1871
Arif Hussain6d2a3322013-11-17 19:50:10 -08001872 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07001873
1874 if (num_channels > IW_MAX_FREQUENCIES)
1875 {
1876 num_channels = IW_MAX_FREQUENCIES;
1877 }
1878
1879 channel_list->num_channels = num_channels;
1880 EXIT();
1881
1882 return 0;
1883}
1884
1885static
1886int iw_get_genie(struct net_device *dev,
1887 struct iw_request_info *info,
1888 union iwreq_data *wrqu, char *extra)
1889{
1890 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1891 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1892 eHalStatus status;
1893 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
1894 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
1895 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08001896 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
1898 status = WLANSap_getstationIE_information(pVosContext,
1899 &length,
1900 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07001901 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
1902 if (wrqu->data.length < length ||
1903 copy_to_user(wrqu->data.pointer,
1904 (v_VOID_t*)genIeBytes, length))
1905 {
1906 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1907 return -EFAULT;
1908 }
1909 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07001910
Arif Hussain6d2a3322013-11-17 19:50:10 -08001911 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07001912
1913
1914 EXIT();
1915 return 0;
1916}
1917static
1918int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
1919 struct iw_request_info *info,
1920 union iwreq_data *wrqu, char *extra)
1921{
1922 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07001923 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07001924 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1925 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07001926
Arif Hussain6d2a3322013-11-17 19:50:10 -08001927 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07001928 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
1929
1930 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
1931 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
1932 pHddApCtx->WPSPBCProbeReq.probeReqIE,
1933 WPSPBCProbeReqIEs.probeReqIELen);
1934 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
1935 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
1936 sizeof(v_MACADDR_t));
1937 if (copy_to_user(wrqu->data.pointer,
1938 (void *)&WPSPBCProbeReqIEs,
1939 sizeof(WPSPBCProbeReqIEs)))
1940 {
1941 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1942 return -EFAULT;
1943 }
1944 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001945 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07001946 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 up(&pHddApCtx->semWpsPBCOverlapInd);
1948 EXIT();
1949 return 0;
1950}
1951
1952/**---------------------------------------------------------------------------
1953
1954 \brief iw_set_auth_hostap() -
1955 This function sets the auth type received from the wpa_supplicant.
1956
1957 \param - dev - Pointer to the net device.
1958 - info - Pointer to the iw_request_info.
1959 - wrqu - Pointer to the iwreq_data.
1960 - extra - Pointer to the data.
1961 \return - 0 for success, non zero for failure
1962
1963 --------------------------------------------------------------------------*/
1964int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
1965 union iwreq_data *wrqu,char *extra)
1966{
1967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1968 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1969
1970 ENTER();
1971 switch(wrqu->param.flags & IW_AUTH_INDEX)
1972 {
1973 case IW_AUTH_TKIP_COUNTERMEASURES:
1974 {
1975 if(wrqu->param.value) {
1976 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1977 "Counter Measure started %d", wrqu->param.value);
1978 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
1979 }
1980 else {
1981 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1982 "Counter Measure stopped=%d", wrqu->param.value);
1983 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
1984 }
1985
1986 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
1987 wrqu->param.value);
1988 }
1989 break;
1990
1991 default:
1992
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001993 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 wrqu->param.flags & IW_AUTH_INDEX);
1995 break;
1996 }
1997
1998 EXIT();
1999 return 0;
2000}
2001
2002static int iw_set_ap_encodeext(struct net_device *dev,
2003 struct iw_request_info *info,
2004 union iwreq_data *wrqu, char *extra)
2005{
2006 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2007 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2008 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002009 int retval = 0;
2010 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2012 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2013 int key_index;
2014 struct iw_point *encoding = &wrqu->encoding;
2015 tCsrRoamSetKey setKey;
2016// tCsrRoamRemoveKey RemoveKey;
2017 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002018
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 ENTER();
2020
2021 key_index = encoding->flags & IW_ENCODE_INDEX;
2022
2023 if(key_index > 0) {
2024
2025 /*Convert from 1-based to 0-based keying*/
2026 key_index--;
2027 }
2028 if(!ext->key_len) {
2029#if 0
2030 /*Set the encrytion type to NONE*/
2031#if 0
2032 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2033#endif
2034
2035 RemoveKey.keyId = key_index;
2036 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2037 /*Key direction for group is RX only*/
2038 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2039 }
2040 else {
2041 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2042 }
2043 switch(ext->alg)
2044 {
2045 case IW_ENCODE_ALG_NONE:
2046 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2047 break;
2048 case IW_ENCODE_ALG_WEP:
2049 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2050 break;
2051 case IW_ENCODE_ALG_TKIP:
2052 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002053 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 case IW_ENCODE_ALG_CCMP:
2055 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2056 break;
2057 default:
2058 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2059 break;
2060 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002061 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 -07002062 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002064 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002066 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2067 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002068 {
2069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002070 __LINE__, vstatus );
2071 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002073#endif
2074 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002075
Jeff Johnson43971f52012-07-17 12:26:56 -07002076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002077
2078 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2079
2080 setKey.keyId = key_index;
2081 setKey.keyLength = ext->key_len;
2082
2083 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2084 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2085 }
2086
2087 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2088 /*Key direction for group is RX only*/
2089 setKey.keyDirection = eSIR_RX_ONLY;
2090 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2091 }
2092 else {
2093
2094 setKey.keyDirection = eSIR_TX_RX;
2095 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2096 }
2097 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2098 {
2099 setKey.keyDirection = eSIR_TX_DEFAULT;
2100 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2101 }
2102
2103 /*For supplicant pae role is zero*/
2104 setKey.paeRole = 0;
2105
2106 switch(ext->alg)
2107 {
2108 case IW_ENCODE_ALG_NONE:
2109 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2110 break;
2111
2112 case IW_ENCODE_ALG_WEP:
2113 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2114 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002115 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 break;
2117
2118 case IW_ENCODE_ALG_TKIP:
2119 {
2120 v_U8_t *pKey = &setKey.Key[0];
2121
2122 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2123
2124 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2125
2126 /*Supplicant sends the 32bytes key in this order
2127
2128 |--------------|----------|----------|
2129 | Tk1 |TX-MIC | RX Mic |
2130 |--------------|----------|----------|
2131 <---16bytes---><--8bytes--><--8bytes-->
2132
2133 */
2134 /*Sme expects the 32 bytes key to be in the below order
2135
2136 |--------------|----------|----------|
2137 | Tk1 |RX-MIC | TX Mic |
2138 |--------------|----------|----------|
2139 <---16bytes---><--8bytes--><--8bytes-->
2140 */
2141 /* Copy the Temporal Key 1 (TK1) */
2142 vos_mem_copy(pKey,ext->key,16);
2143
2144 /*Copy the rx mic first*/
2145 vos_mem_copy(&pKey[16],&ext->key[24],8);
2146
2147 /*Copy the tx mic */
2148 vos_mem_copy(&pKey[24],&ext->key[16],8);
2149
2150 }
2151 break;
2152
2153 case IW_ENCODE_ALG_CCMP:
2154 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2155 break;
2156
2157 default:
2158 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2159 break;
2160 }
2161
2162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302163 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 setKey.keyId);
2165 for(i=0; i< ext->key_len; i++)
2166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2167 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002168
2169 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2170 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002171 {
2172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002173 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2174 retval = -EINVAL;
2175 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002176
Jeff Johnson43971f52012-07-17 12:26:56 -07002177 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002178}
Jeff Johnson43971f52012-07-17 12:26:56 -07002179
2180
Jeff Johnson295189b2012-06-20 16:38:30 -07002181static int iw_set_ap_mlme(struct net_device *dev,
2182 struct iw_request_info *info,
2183 union iwreq_data *wrqu,
2184 char *extra)
2185{
2186#if 0
2187 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2188 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2189
2190 ENTER();
2191
2192 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2193 switch (mlme->cmd) {
2194 case IW_MLME_DISASSOC:
2195 case IW_MLME_DEAUTH:
2196 hddLog(LOG1, "Station disassociate");
2197 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2198 {
2199 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2200
2201 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2202 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2203
2204 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2205
2206 //clear all the reason codes
2207 if (status != 0)
2208 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002209 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002210 }
2211
2212 netif_stop_queue(dev);
2213 netif_carrier_off(dev);
2214 }
2215 else
2216 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002217 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 -07002218 }
2219 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002220 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 return -EINVAL;
2222 }//end of switch
2223 EXIT();
2224#endif
2225 return 0;
2226// return status;
2227}
2228
2229static int iw_get_ap_rts_threshold(struct net_device *dev,
2230 struct iw_request_info *info,
2231 union iwreq_data *wrqu, char *extra)
2232{
2233 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2234 v_U32_t status = 0;
2235
2236 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2237
2238 return status;
2239}
2240
2241static int iw_get_ap_frag_threshold(struct net_device *dev,
2242 struct iw_request_info *info,
2243 union iwreq_data *wrqu, char *extra)
2244{
2245 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2246 v_U32_t status = 0;
2247
2248 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2249
2250 return status;
2251}
2252
2253static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2254 struct iw_freq *fwrq, char *extra)
2255{
Jeff Johnsone7245742012-09-05 17:12:55 -07002256 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002257 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2258 tHalHandle hHal;
2259 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002260 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002261
2262 ENTER();
2263
2264 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2266 "%s:LOGP in Progress. Ignore!!!",__func__);
2267 return status;
2268 }
2269
2270 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2271 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2272
2273 if(pHostapdState->bssState == BSS_STOP )
2274 {
2275 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2276 != eHAL_STATUS_SUCCESS)
2277 {
2278 return -EIO;
2279 }
2280 else
2281 {
2282 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002283 if( TRUE == status)
2284 {
2285 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2286 * iwlist & iwconfig command shows frequency into proper
2287 * format (2.412 GHz instead of 246.2 MHz)*/
2288 fwrq->m = freq;
2289 fwrq->e = MHZ;
2290 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002291 }
2292 }
2293 else
2294 {
2295 channel = pHddApCtx->operatingChannel;
2296 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002297 if( TRUE == status)
2298 {
2299 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2300 * iwlist & iwconfig command shows frequency into proper
2301 * format (2.412 GHz instead of 246.2 MHz)*/
2302 fwrq->m = freq;
2303 fwrq->e = MHZ;
2304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002306 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002307}
2308
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302309static int iw_get_mode(struct net_device *dev,
2310 struct iw_request_info *info,
2311 union iwreq_data *wrqu,
2312 char *extra)
2313{
2314 int status = 0;
2315
2316 wrqu->mode = IW_MODE_MASTER;
2317
2318 return status;
2319}
2320
Jeff Johnson295189b2012-06-20 16:38:30 -07002321static int iw_softap_setwpsie(struct net_device *dev,
2322 struct iw_request_info *info,
2323 union iwreq_data *wrqu,
2324 char *extra)
2325{
2326 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2327 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2328 hdd_hostapd_state_t *pHostapdState;
2329 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002330 u_int8_t *wps_genie;
2331 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07002332 u_int8_t *pos;
2333 tpSap_WPSIE pSap_WPSIe;
2334 u_int8_t WPSIeType;
2335 u_int16_t length;
2336 ENTER();
2337
Arif Hussained667642013-10-27 23:01:14 -07002338 if(!wrqu->data.length || wrqu->data.length <= QCSAP_MAX_WSC_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002339 return 0;
2340
Arif Hussained667642013-10-27 23:01:14 -07002341 wps_genie = kmalloc(wrqu->data.length, GFP_KERNEL);
2342
2343 if(NULL == wps_genie) {
2344 hddLog(LOG1, "unable to allocate memory");
2345 return -ENOMEM;
2346 }
2347 fwps_genie = wps_genie;
2348 if (copy_from_user((void *)wps_genie,
2349 wrqu->data.pointer, wrqu->data.length))
2350 {
2351 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2352 kfree(fwps_genie);
2353 return -EFAULT;
2354 }
2355
Jeff Johnson295189b2012-06-20 16:38:30 -07002356 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2357 if (NULL == pSap_WPSIe)
2358 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002359 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07002360 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 return -ENOMEM;
2362 }
2363 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2364
Arif Hussain6d2a3322013-11-17 19:50:10 -08002365 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 -07002366 WPSIeType = wps_genie[0];
2367 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2368 {
2369 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2370 wps_genie = wps_genie + 1;
2371 switch ( wps_genie[0] )
2372 {
2373 case DOT11F_EID_WPA:
2374 if (wps_genie[1] < 2 + 4)
2375 {
2376 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002377 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002378 return -EINVAL;
2379 }
2380 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2381 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002382 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002383 pos = &wps_genie[6];
2384 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2385 {
2386 switch((u_int16_t)(*pos<<8) | *(pos+1))
2387 {
2388 case HDD_WPS_ELEM_VERSION:
2389 pos += 4;
2390 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002391 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002392 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2393 pos += 1;
2394 break;
2395
2396 case HDD_WPS_ELEM_WPS_STATE:
2397 pos +=4;
2398 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002399 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002400 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2401 pos += 1;
2402 break;
2403 case HDD_WPS_ELEM_APSETUPLOCK:
2404 pos += 4;
2405 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002406 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002407 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2408 pos += 1;
2409 break;
2410 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2411 pos += 4;
2412 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002413 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2415 pos += 1;
2416 break;
2417 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2418 pos += 4;
2419 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002420 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2422 pos += 2;
2423 break;
2424 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2425 pos += 4;
2426 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002427 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002428 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2429 pos += 2;
2430 break;
2431
2432 case HDD_WPS_ELEM_UUID_E:
2433 pos += 2;
2434 length = *pos<<8 | *(pos+1);
2435 pos += 2;
2436 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2437 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2438 pos += length;
2439 break;
2440 case HDD_WPS_ELEM_RF_BANDS:
2441 pos += 4;
2442 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002443 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002444 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2445 pos += 1;
2446 break;
2447
2448 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002449 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07002450 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002451 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002452 return -EINVAL;
2453 }
2454 }
2455 }
2456 else {
2457 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002458 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002459 }
2460 break;
2461
2462 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002463 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002464 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002465 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002466 return 0;
2467 }
2468 }
2469 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2470 {
2471 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2472 wps_genie = wps_genie + 1;
2473 switch ( wps_genie[0] )
2474 {
2475 case DOT11F_EID_WPA:
2476 if (wps_genie[1] < 2 + 4)
2477 {
2478 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002479 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002480 return -EINVAL;
2481 }
2482 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2483 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002484 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002485 pos = &wps_genie[6];
2486 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2487 {
2488 switch((u_int16_t)(*pos<<8) | *(pos+1))
2489 {
2490 case HDD_WPS_ELEM_VERSION:
2491 pos += 4;
2492 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002493 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002494 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2495 pos += 1;
2496 break;
2497
2498 case HDD_WPS_ELEM_WPS_STATE:
2499 pos +=4;
2500 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002501 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002502 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2503 pos += 1;
2504 break;
2505 case HDD_WPS_ELEM_APSETUPLOCK:
2506 pos += 4;
2507 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002508 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2510 pos += 1;
2511 break;
2512 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2513 pos += 4;
2514 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002515 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002516 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2517 pos += 1;
2518 break;
2519 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2520 pos += 4;
2521 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002522 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2524 pos += 2;
2525 break;
2526 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2527 pos += 4;
2528 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002529 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2531 pos += 2;
2532 break;
2533 case HDD_WPS_ELEM_RSP_TYPE:
2534 pos += 4;
2535 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002536 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002537 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2538 pos += 1;
2539 break;
2540 case HDD_WPS_ELEM_UUID_E:
2541 pos += 2;
2542 length = *pos<<8 | *(pos+1);
2543 pos += 2;
2544 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2545 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2546 pos += length;
2547 break;
2548
2549 case HDD_WPS_ELEM_MANUFACTURER:
2550 pos += 2;
2551 length = *pos<<8 | *(pos+1);
2552 pos += 2;
2553 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2554 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2555 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2556 pos += length;
2557 break;
2558
2559 case HDD_WPS_ELEM_MODEL_NAME:
2560 pos += 2;
2561 length = *pos<<8 | *(pos+1);
2562 pos += 2;
2563 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2564 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2565 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2566 pos += length;
2567 break;
2568 case HDD_WPS_ELEM_MODEL_NUM:
2569 pos += 2;
2570 length = *pos<<8 | *(pos+1);
2571 pos += 2;
2572 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2573 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2574 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2575 pos += length;
2576 break;
2577 case HDD_WPS_ELEM_SERIAL_NUM:
2578 pos += 2;
2579 length = *pos<<8 | *(pos+1);
2580 pos += 2;
2581 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2582 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2583 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2584 pos += length;
2585 break;
2586 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2587 pos += 4;
2588 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002589 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002590 pos += 2;
2591
2592 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002593 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002594 pos += 4;
2595 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002596 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 pos += 2;
2598 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2599 break;
2600 case HDD_WPS_ELEM_DEVICE_NAME:
2601 pos += 2;
2602 length = *pos<<8 | *(pos+1);
2603 pos += 2;
2604 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2605 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2606 pos += length;
2607 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2608 break;
2609 case HDD_WPS_ELEM_CONFIG_METHODS:
2610 pos += 4;
2611 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002612 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002613 pos += 2;
2614 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2615 break;
2616
2617 case HDD_WPS_ELEM_RF_BANDS:
2618 pos += 4;
2619 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002620 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002621 pos += 1;
2622 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2623 break;
2624 } // switch
2625 }
2626 }
2627 else
2628 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002629 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002630 }
2631
2632 } // switch
2633 }
2634 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2635 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2636 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2637 {
2638 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2639 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2640 WLANSAP_Update_WpsIe ( pVosContext );
2641 }
2642
2643 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002644 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002645 EXIT();
2646 return halStatus;
2647}
2648
2649static int iw_softap_stopbss(struct net_device *dev,
2650 struct iw_request_info *info,
2651 union iwreq_data *wrqu,
2652 char *extra)
2653{
2654 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2655 VOS_STATUS status = VOS_STATUS_SUCCESS;
2656 ENTER();
2657 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2658 {
2659 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2660 {
2661 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2662
2663 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2664
2665 if (!VOS_IS_STATUS_SUCCESS(status))
2666 {
2667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002668 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002669 VOS_ASSERT(0);
2670 }
2671 }
2672 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2673 }
2674 EXIT();
2675 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2676}
2677
2678static int iw_softap_version(struct net_device *dev,
2679 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002680 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07002681 char *extra)
2682{
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002684
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002686 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002688 return 0;
2689}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002690
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002691VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002692{
2693 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002694 int len = 0;
2695 const char sta_info_header[] = "staId staAddress\n";
2696
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002697 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002698 pBuf += len;
2699 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002700
2701 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2702 {
2703 if(pAdapter->aStaInfo[i].isUsed)
2704 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08002705 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002706 pAdapter->aStaInfo[i].ucSTAId,
2707 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
2708 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
2709 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
2710 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
2711 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
2712 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002713 pBuf += len;
2714 buf_len -= len;
2715 }
2716 if(WE_GET_STA_INFO_SIZE > buf_len)
2717 {
2718 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002719 }
2720 }
2721 return VOS_STATUS_SUCCESS;
2722}
2723
2724static int iw_softap_get_sta_info(struct net_device *dev,
2725 struct iw_request_info *info,
2726 union iwreq_data *wrqu,
2727 char *extra)
2728{
2729 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2730 VOS_STATUS status;
2731 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07002732 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002733 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002735 return -EINVAL;
2736 }
2737 wrqu->data.length = strlen(extra);
2738 EXIT();
2739 return 0;
2740}
2741
Jeff Johnson295189b2012-06-20 16:38:30 -07002742static int iw_set_ap_genie(struct net_device *dev,
2743 struct iw_request_info *info,
2744 union iwreq_data *wrqu,
2745 char *extra)
2746{
2747
2748 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2749 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2750 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002751 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07002752
2753 ENTER();
2754
2755 if(!wrqu->data.length)
2756 {
2757 EXIT();
2758 return 0;
2759 }
Arif Hussained667642013-10-27 23:01:14 -07002760
Jeff Johnson295189b2012-06-20 16:38:30 -07002761 switch (genie[0])
2762 {
2763 case DOT11F_EID_WPA:
2764 case DOT11F_EID_RSN:
2765 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
2766 {
2767 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
2768 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
2769 }
2770 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07002771 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07002772 break;
2773
2774 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002775 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002776 halStatus = 0;
2777 }
2778
2779 EXIT();
2780 return halStatus;
2781}
2782
2783static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
2784{
2785 eHalStatus hstatus;
2786 long lrc;
2787 struct statsContext context;
2788
2789 if (NULL == pAdapter)
2790 {
2791 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Padapter is NULL", __func__);
2792 return VOS_STATUS_E_FAULT;
2793 }
2794
2795 init_completion(&context.completion);
2796 context.pAdapter = pAdapter;
2797 context.magic = STATS_CONTEXT_MAGIC;
2798 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
2799 eCSR_HDD,
2800 SME_GLOBAL_CLASSA_STATS,
2801 hdd_GetClassA_statisticsCB,
2802 0, // not periodic
2803 FALSE, //non-cached results
2804 staid,
2805 &context);
2806 if (eHAL_STATUS_SUCCESS != hstatus)
2807 {
2808 hddLog(VOS_TRACE_LEVEL_ERROR,
2809 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002810 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002811 }
2812 else
2813 {
2814 lrc = wait_for_completion_interruptible_timeout(&context.completion,
2815 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2816 context.magic = 0;
2817 if (lrc <= 0)
2818 {
2819 hddLog(VOS_TRACE_LEVEL_ERROR,
2820 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002821 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 msleep(50);
2823 }
2824 }
2825 return VOS_STATUS_SUCCESS;
2826}
2827
2828int iw_get_softap_linkspeed(struct net_device *dev,
2829 struct iw_request_info *info,
2830 union iwreq_data *wrqu,
2831 char *extra)
2832
2833{
2834 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302835 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07002837 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302838 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07002839 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302840 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002841 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
2842 VOS_STATUS status;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302843 int rc, valid;
2844
2845 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2846
2847 valid = wlan_hdd_validate_context(pHddCtx);
2848
2849 if (0 != valid)
2850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
2852 return valid;
2853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002854
Arif Hussain6d2a3322013-11-17 19:50:10 -08002855 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussained667642013-10-27 23:01:14 -07002856 if (wrqu->data.length != MAC_ADDRESS_STR_LEN)
2857 {
2858 hddLog(LOG1, "Invalid length");
2859 return -EINVAL;
2860 }
2861 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
2862 if(NULL == pmacAddress) {
2863 hddLog(LOG1, "unable to allocate memory");
2864 return -ENOMEM;
2865 }
2866 if (copy_from_user((void *)pmacAddress,
2867 wrqu->data.pointer, wrqu->data.length))
2868 {
2869 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2870 kfree(pmacAddress);
2871 return -EFAULT;
2872 }
2873
2874 status = hdd_string_to_hex (pmacAddress, wrqu->data.length, macAddress );
2875 kfree(pmacAddress);
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302876
2877 if (!VOS_IS_STATUS_SUCCESS(status ))
Jeff Johnson295189b2012-06-20 16:38:30 -07002878 {
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002880 }
2881
Kiet Lam61589852013-09-19 17:10:58 +05302882 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302883 * link speed for first connected client will be returned.
2884 */
Kiet Lam61589852013-09-19 17:10:58 +05302885 if (!VOS_IS_STATUS_SUCCESS(status ) || wrqu->data.length < 17)
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302886 {
2887 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
2888 }
2889 else
2890 {
2891 status = hdd_softap_GetStaId(pHostapdAdapter,
2892 (v_MACADDR_t *)macAddress, (void *)(&staId));
2893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002894
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302895 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002896 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002898 link_speed = 0;
2899 }
2900 else
2901 {
2902 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302903
Jeff Johnson295189b2012-06-20 16:38:30 -07002904 if (!VOS_IS_STATUS_SUCCESS(status ))
2905 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002907 return -EINVAL;
2908 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302909
2910 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
2911 staId, &link_speed);
2912
2913 link_speed = link_speed / 10;
2914
2915 if (0 == link_speed)
2916 {
2917 /* The linkspeed returned by HAL is in units of 500kbps.
2918 * converting it to mbps.
2919 * This is required to support legacy firmware which does
2920 * not return link capacity.
2921 */
2922 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
2923 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002924 }
2925
2926 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07002927 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302928
Jeff Johnson295189b2012-06-20 16:38:30 -07002929 if ((rc < 0) || (rc >= len))
2930 {
2931 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302932 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 return -EIO;
2934 }
2935
2936 return 0;
2937}
2938
2939static const iw_handler hostapd_handler[] =
2940{
2941 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2942 (iw_handler) NULL, /* SIOCGIWNAME */
2943 (iw_handler) NULL, /* SIOCSIWNWID */
2944 (iw_handler) NULL, /* SIOCGIWNWID */
2945 (iw_handler) NULL, /* SIOCSIWFREQ */
2946 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
2947 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302948 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07002949 (iw_handler) NULL, /* SIOCSIWSENS */
2950 (iw_handler) NULL, /* SIOCGIWSENS */
2951 (iw_handler) NULL, /* SIOCSIWRANGE */
2952 (iw_handler) NULL, /* SIOCGIWRANGE */
2953 (iw_handler) NULL, /* SIOCSIWPRIV */
2954 (iw_handler) NULL, /* SIOCGIWPRIV */
2955 (iw_handler) NULL, /* SIOCSIWSTATS */
2956 (iw_handler) NULL, /* SIOCGIWSTATS */
2957 (iw_handler) NULL, /* SIOCSIWSPY */
2958 (iw_handler) NULL, /* SIOCGIWSPY */
2959 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2960 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2961 (iw_handler) NULL, /* SIOCSIWAP */
2962 (iw_handler) NULL, /* SIOCGIWAP */
2963 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
2964 (iw_handler) NULL, /* SIOCGIWAPLIST */
2965 (iw_handler) NULL, /* SIOCSIWSCAN */
2966 (iw_handler) NULL, /* SIOCGIWSCAN */
2967 (iw_handler) NULL, /* SIOCSIWESSID */
2968 (iw_handler) NULL, /* SIOCGIWESSID */
2969 (iw_handler) NULL, /* SIOCSIWNICKN */
2970 (iw_handler) NULL, /* SIOCGIWNICKN */
2971 (iw_handler) NULL, /* -- hole -- */
2972 (iw_handler) NULL, /* -- hole -- */
2973 (iw_handler) NULL, /* SIOCSIWRATE */
2974 (iw_handler) NULL, /* SIOCGIWRATE */
2975 (iw_handler) NULL, /* SIOCSIWRTS */
2976 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
2977 (iw_handler) NULL, /* SIOCSIWFRAG */
2978 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
2979 (iw_handler) NULL, /* SIOCSIWTXPOW */
2980 (iw_handler) NULL, /* SIOCGIWTXPOW */
2981 (iw_handler) NULL, /* SIOCSIWRETRY */
2982 (iw_handler) NULL, /* SIOCGIWRETRY */
2983 (iw_handler) NULL, /* SIOCSIWENCODE */
2984 (iw_handler) NULL, /* SIOCGIWENCODE */
2985 (iw_handler) NULL, /* SIOCSIWPOWER */
2986 (iw_handler) NULL, /* SIOCGIWPOWER */
2987 (iw_handler) NULL, /* -- hole -- */
2988 (iw_handler) NULL, /* -- hole -- */
2989 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
2990 (iw_handler) NULL, /* SIOCGIWGENIE */
2991 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
2992 (iw_handler) NULL, /* SIOCGIWAUTH */
2993 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
2994 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
2995 (iw_handler) NULL, /* SIOCSIWPMKSA */
2996};
2997
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002998#define IW_PRIV_TYPE_OPTIE (IW_PRIV_TYPE_BYTE | QCSAP_MAX_OPT_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002999#define IW_PRIV_TYPE_MLME \
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08003000 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
Jeff Johnson295189b2012-06-20 16:38:30 -07003001
3002static const struct iw_priv_args hostapd_private_args[] = {
3003 { QCSAP_IOCTL_SETPARAM,
3004 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3005 { QCSAP_IOCTL_SETPARAM,
3006 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3007 { QCSAP_PARAM_MAX_ASSOC,
3008 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3009 { QCSAP_PARAM_HIDE_SSID,
3010 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003011 { QCSAP_PARAM_SET_MC_RATE,
3012 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003013 { QCSAP_IOCTL_GETPARAM,
3014 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3015 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3016 { QCSAP_IOCTL_GETPARAM, 0,
3017 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3018 { QCSAP_PARAM_MAX_ASSOC, 0,
3019 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003020 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3021 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3022 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003024 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
3025 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
3026 { QCSAP_PARAM_CLR_ACL, 0,
3027 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3028 { QCSAP_PARAM_ACL_MODE,
3029 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
3030 { QCSAP_IOCTL_COMMIT,
3031 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
3032 { QCSAP_IOCTL_SETMLME,
3033 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
3034 { QCSAP_IOCTL_GET_STAWPAIE,
3035 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3036 { QCSAP_IOCTL_SETWPAIE,
3037 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3038 { QCSAP_IOCTL_STOPBSS,
3039 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3040 { QCSAP_IOCTL_VERSION, 0,
3041 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003042 { QCSAP_IOCTL_GET_STA_INFO, 0,
3043 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003044 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003045 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003046 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003047 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003048 { QCSAP_IOCTL_ASSOC_STA_MACADDR, 0,
3049 IW_PRIV_TYPE_BYTE | /*((WLAN_MAX_STA_COUNT*6)+100)*/1 , "get_assoc_stamac" },
3050 { QCSAP_IOCTL_DISASSOC_STA,
3051 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
3052 { QCSAP_IOCTL_AP_STATS,
3053 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
3054 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3055 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303056 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003057
3058 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3059 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3060 /* handlers for sub-ioctl */
3061 { WE_SET_WLAN_DBG,
3062 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3063 0,
3064 "setwlandbg" },
3065
3066 /* handlers for main ioctl */
3067 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3068 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3069 0,
3070 "" },
3071
3072 /* handlers for sub-ioctl */
3073 { WE_LOG_DUMP_CMD,
3074 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3075 0,
3076 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003077 { WE_P2P_NOA_CMD,
3078 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3079 0,
3080 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003081 /* handlers for sub ioctl */
3082 {
3083 WE_MCC_CONFIG_CREDENTIAL,
3084 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3085 0,
3086 "setMccCrdnl" },
3087
3088 /* handlers for sub ioctl */
3089 {
3090 WE_MCC_CONFIG_PARAMS,
3091 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3092 0,
3093 "setMccConfig" },
3094
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 /* handlers for main ioctl */
3096 { QCSAP_IOCTL_MODIFY_ACL,
3097 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3098 0,
3099 "modify_acl" },
3100
3101 /* handlers for main ioctl */
3102 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3103 0,
3104 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3105 "getChannelList" },
3106
Jeff Johnsone7245742012-09-05 17:12:55 -07003107 /* handlers for main ioctl */
3108 { QCSAP_IOCTL_SET_TX_POWER,
3109 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3110 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303111 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003112
3113 /* handlers for main ioctl */
3114 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3115 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3116 0,
3117 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303118
3119 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3120 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3121 0,
3122 "dataSnapshot" },
3123
3124 /* handlers for main ioctl */
3125 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3126 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3127 0,
3128 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003129};
Jeff Johnsone7245742012-09-05 17:12:55 -07003130
Jeff Johnson295189b2012-06-20 16:38:30 -07003131static const iw_handler hostapd_private[] = {
3132 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3133 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
3134 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
3135 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
3136 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3137 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3138 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3139 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3140 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3141 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3142 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3143 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3144 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3145 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3146 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3147 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3148 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3149 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003150 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003151 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3152 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003153 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303154 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303155 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003156};
3157const struct iw_handler_def hostapd_handler_def = {
3158 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3159 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3160 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3161 .standard = (iw_handler *)hostapd_handler,
3162 .private = (iw_handler *)hostapd_private,
3163 .private_args = hostapd_private_args,
3164 .get_wireless_stats = NULL,
3165};
3166#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3167struct net_device_ops net_ops_struct = {
3168 .ndo_open = hdd_hostapd_open,
3169 .ndo_stop = hdd_hostapd_stop,
3170 .ndo_uninit = hdd_hostapd_uninit,
3171 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3172 .ndo_tx_timeout = hdd_softap_tx_timeout,
3173 .ndo_get_stats = hdd_softap_stats,
3174 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3175 .ndo_do_ioctl = hdd_hostapd_ioctl,
3176 .ndo_change_mtu = hdd_hostapd_change_mtu,
3177 .ndo_select_queue = hdd_hostapd_select_queue,
3178 };
3179#endif
3180
3181int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3182{
3183 return VOS_STATUS_SUCCESS;
3184}
3185
3186void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3187{
3188#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3189 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3190#else
3191 pWlanHostapdDev->open = hdd_hostapd_open;
3192 pWlanHostapdDev->stop = hdd_hostapd_stop;
3193 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3194 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3195 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3196 pWlanHostapdDev->get_stats = hdd_softap_stats;
3197 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3198 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3199#endif
3200}
3201
3202VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
3203{
3204 hdd_hostapd_state_t * phostapdBuf;
3205 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003207 VOS_STATUS status;
3208 ENTER();
3209 // Allocate the Wireless Extensions state structure
3210 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
3211
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003212 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
3213
Jeff Johnson295189b2012-06-20 16:38:30 -07003214 // Zero the memory. This zeros the profile structure.
3215 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
3216
3217 // Set up the pointer to the Wireless Extensions state structure
3218 // NOP
3219 status = hdd_set_hostapd(pAdapter);
3220 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003222 return status;
3223 }
3224
3225 status = vos_event_init(&phostapdBuf->vosEvent);
3226 if (!VOS_IS_STATUS_SUCCESS(status))
3227 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 return status;
3230 }
3231
3232 init_completion(&pAdapter->session_close_comp_var);
3233 init_completion(&pAdapter->session_open_comp_var);
3234
3235 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
3236
3237 // Register as a wireless device
3238 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
3239
3240 //Initialize the data path module
3241 status = hdd_softap_init_tx_rx(pAdapter);
3242 if ( !VOS_IS_STATUS_SUCCESS( status ))
3243 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003244 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003245 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303246
3247 status = hdd_wmm_adapter_init( pAdapter );
3248 if (!VOS_IS_STATUS_SUCCESS(status))
3249 {
3250 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003251 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303252 status, status );
3253 goto error_wmm_init;
3254 }
3255
3256 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3257
Jeff Johnson295189b2012-06-20 16:38:30 -07003258 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303259
3260 return status;
3261
3262error_wmm_init:
3263 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003264 EXIT();
3265 return status;
3266}
3267
3268hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
3269{
3270 struct net_device *pWlanHostapdDev = NULL;
3271 hdd_adapter_t *pHostapdAdapter = NULL;
3272 v_CONTEXT_t pVosContext= NULL;
3273
Jeff Johnson295189b2012-06-20 16:38:30 -07003274 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07003275
3276 if (pWlanHostapdDev != NULL)
3277 {
3278 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
3279
3280 //Init the net_device structure
3281 ether_setup(pWlanHostapdDev);
3282
3283 //Initialize the adapter context to zeros.
3284 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
3285 pHostapdAdapter->dev = pWlanHostapdDev;
3286 pHostapdAdapter->pHddCtx = pHddCtx;
3287 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3288
3289 //Get the Global VOSS context.
3290 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3291 //Save the adapter context in global context for future.
3292 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3293
3294 //Init the net_device structure
3295 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3296
3297 hdd_set_ap_ops( pHostapdAdapter->dev );
3298
Jeff Johnson295189b2012-06-20 16:38:30 -07003299 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3300 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3301
3302 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3303 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3304
3305 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3307 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3308 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3309 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003310 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3311 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
3312#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3313 init_completion(&pHostapdAdapter->offchannel_tx_event);
3314#endif
3315
Jeff Johnson295189b2012-06-20 16:38:30 -07003316 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3317 }
3318 return pHostapdAdapter;
3319}
3320
3321VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3322{
3323 struct net_device *dev = pAdapter->dev;
3324 VOS_STATUS status = VOS_STATUS_SUCCESS;
3325
3326 ENTER();
3327
3328 if( rtnl_lock_held )
3329 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003330 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 if( dev_alloc_name(dev, dev->name) < 0 )
3332 {
3333 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3334 return VOS_STATUS_E_FAILURE;
3335 }
3336 }
3337 if (register_netdevice(dev))
3338 {
3339 hddLog(VOS_TRACE_LEVEL_FATAL,
3340 "%s:Failed:register_netdevice", __func__);
3341 return VOS_STATUS_E_FAILURE;
3342 }
3343 }
3344 else
3345 {
3346 if (register_netdev(dev))
3347 {
3348 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3349 return VOS_STATUS_E_FAILURE;
3350 }
3351 }
3352 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3353
3354 EXIT();
3355 return status;
3356}
3357
3358VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3359{
3360 ENTER();
3361
3362 hdd_softap_deinit_tx_rx(pAdapter);
3363
3364 /* if we are being called during driver unload, then the dev has already
3365 been invalidated. if we are being called at other times, then we can
3366 detatch the wireless device handlers */
3367 if (pAdapter->dev)
3368 {
3369 pAdapter->dev->wireless_handlers = NULL;
3370 }
3371 EXIT();
3372 return 0;
3373}