blob: aabedd87fd9963f842b58e9152233c8cc58b7c3b [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"
Jeff Johnson295189b2012-06-20 16:38:30 -070094
95#define IS_UP(_dev) \
96 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
97#define IS_UP_AUTO(_ic) \
98 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
99#define WE_WLAN_VERSION 1
100#define STATS_CONTEXT_MAGIC 0x53544154
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -0700101#define WE_GET_STA_INFO_SIZE 30
102/* WEXT limition: MAX allowed buf len for any *
103 * IW_PRIV_TYPE_CHAR is 2Kbytes *
104 */
105#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700106
107struct statsContext
108{
109 struct completion completion;
110 hdd_adapter_t *pAdapter;
111 unsigned int magic;
112};
113#define SAP_24GHZ_CH_COUNT (14)
114/*---------------------------------------------------------------------------
115 * Function definitions
116 *-------------------------------------------------------------------------*/
117/**---------------------------------------------------------------------------
118
119 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
120
121 This is called in response to ifconfig up
122
123 \param - dev Pointer to net_device structure
124
125 \return - 0 for success non-zero for failure
126
127 --------------------------------------------------------------------------*/
128int hdd_hostapd_open (struct net_device *dev)
129{
130 ENTER();
131
132 //Turn ON carrier state
133 netif_carrier_on(dev);
134 //Enable all Tx queues
135 netif_tx_start_all_queues(dev);
136
137 EXIT();
138 return 0;
139}
140/**---------------------------------------------------------------------------
141
142 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
143
144 This is called in response to ifconfig down
145
146 \param - dev Pointer to net_device structure
147
148 \return - 0 for success non-zero for failure
149
150 --------------------------------------------------------------------------*/
151int hdd_hostapd_stop (struct net_device *dev)
152{
153 ENTER();
154
155 //Stop all tx queues
156 netif_tx_disable(dev);
157
158 //Turn OFF carrier state
159 netif_carrier_off(dev);
160
161 EXIT();
162 return 0;
163}
164/**---------------------------------------------------------------------------
165
166 \brief hdd_hostapd_uninit() - HDD uninit function
167
168 This is called during the netdev unregister to uninitialize all data
169associated with the device
170
171 \param - dev Pointer to net_device structure
172
173 \return - void
174
175 --------------------------------------------------------------------------*/
176static void hdd_hostapd_uninit (struct net_device *dev)
177{
178 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
179
180 ENTER();
181
182 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
183 {
184 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
185
186 /* after uninit our adapter structure will no longer be valid */
187 pHostapdAdapter->dev = NULL;
188 }
189
190 EXIT();
191}
192
193
194/**============================================================================
195 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
196 transmitting packets. There are 2 versions of this function. One that uses
197 locked queue and other that uses lockless queues. Both have been retained to
198 do some performance testing
199 @param skb : [in] pointer to OS packet (sk_buff)
200 @param dev : [in] pointer to Libra network device
201
202 @return : NET_XMIT_DROP if packets are dropped
203 : NET_XMIT_SUCCESS if packet is enqueued succesfully
204 ===========================================================================*/
205int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
206{
207 return 0;
208}
209int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
210{
211 return 0;
212}
213
214int hdd_hostapd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
215{
216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
217 hdd_priv_data_t priv_data;
218 tANI_U8 *command = NULL;
219 int ret = 0;
220
221 if (NULL == pAdapter)
222 {
223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700224 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700225 ret = -ENODEV;
226 goto exit;
227 }
228
Jeff Johnsone7245742012-09-05 17:12:55 -0700229 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -0700230 {
231 ret = -EINVAL;
232 goto exit;
233 }
234
235 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
236 {
237 ret = -EFAULT;
238 goto exit;
239 }
240
241 command = kmalloc(priv_data.total_len, GFP_KERNEL);
242 if (!command)
243 {
244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700245 "%s: failed to allocate memory\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700246 ret = -ENOMEM;
247 goto exit;
248 }
249
250 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
251 {
252 ret = -EFAULT;
253 goto exit;
254 }
255
256 if ((SIOCDEVPRIVATE + 1) == cmd)
257 {
258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
259 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
260
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 if(strncmp(command, "P2P_SET_NOA", 11) == 0 )
262 {
263 hdd_setP2pNoa(dev, command);
264 }
265 else if( strncmp(command, "P2P_SET_PS", 10) == 0 )
266 {
267 hdd_setP2pOpps(dev, command);
268 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700269
270 /*
271 command should be a string having format
272 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
273 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700274 if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700275 {
276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700277 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700278
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -0800279 ret = sapSetPreferredChannel(command);
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700280 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 }
282exit:
283 if (command)
284 {
285 kfree(command);
286 }
287 return ret;
288}
289
290/**---------------------------------------------------------------------------
291
292 \brief hdd_hostapd_set_mac_address() -
293 This function sets the user specified mac address using
294 the command ifconfig wlanX hw ether <mac adress>.
295
296 \param - dev - Pointer to the net device.
297 - addr - Pointer to the sockaddr.
298 \return - 0 for success, non zero for failure
299
300 --------------------------------------------------------------------------*/
301
302static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
303{
304 struct sockaddr *psta_mac_addr = addr;
305 ENTER();
306 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
307 EXIT();
308 return 0;
309}
310void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
311{
312 struct net_device *dev = (struct net_device *)usrDataForCallback;
313 v_BYTE_t we_custom_event[64];
314 union iwreq_data wrqu;
315#ifdef DISABLE_CONCURRENCY_AUTOSAVE
316 VOS_STATUS vos_status;
317 hdd_adapter_t *pHostapdAdapter;
318 hdd_ap_ctx_t *pHddApCtx;
319#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
320
321 /* event_name space-delimiter driver_module_name */
322 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
323 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
324 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
325
326 ENTER();
327
328#ifdef DISABLE_CONCURRENCY_AUTOSAVE
329 if (vos_concurrent_sessions_running())
330 {
331 /*
332 This timer routine is going to be called only when AP
333 persona is up.
334 If there are concurrent sessions running we do not want
335 to shut down the Bss.Instead we run the timer again so
336 that if Autosave is enabled next time and other session
337 was down only then we bring down AP
338 */
339 pHostapdAdapter = netdev_priv(dev);
340 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
341 vos_status = vos_timer_start(
342 &pHddApCtx->hdd_ap_inactivity_timer,
343 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
344 * 1000);
345 if (!VOS_IS_STATUS_SUCCESS(vos_status))
346 {
347 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
348 }
349 EXIT();
350 return;
351 }
352#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
353 memset(&we_custom_event, '\0', sizeof(we_custom_event));
354 memcpy(&we_custom_event, autoShutEvent, event_len);
355
356 memset(&wrqu, 0, sizeof(wrqu));
357 wrqu.data.length = event_len;
358
359 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
360 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
361
362 EXIT();
363}
364
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800365VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
366{
367 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
368 ptSapContext pSapCtx = NULL;
369 eHalStatus halStatus = eHAL_STATUS_FAILURE;
370 v_PVOID_t hHal = NULL;
371
372 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
373 "%s: UPDATE Beacon Params", __func__);
374
375 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
376 pSapCtx = VOS_GET_SAP_CB(pVosContext);
377 if ( NULL == pSapCtx )
378 {
379 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
380 "%s: Invalid SAP pointer from pvosGCtx", __func__);
381 return VOS_STATUS_E_FAULT;
382 }
383
384 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
385 if ( NULL == hHal ){
386 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
387 "%s: Invalid HAL pointer from pvosGCtx", __func__);
388 return VOS_STATUS_E_FAULT;
389 }
390 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
391 if(halStatus == eHAL_STATUS_FAILURE ){
392 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
393 "%s: Failed to update Beacon Params", __func__);
394 return VOS_STATUS_E_FAILURE;
395 }
396 }
397 return VOS_STATUS_SUCCESS;
398}
399
400void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
401{
402 v_U8_t staId = 0;
403 struct net_device *dev;
404 dev = (struct net_device *)usrDataForCallback;
405
406 hddLog(LOGE, FL("Clearing all the STA entry....\n"));
407 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
408 {
409 if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
410 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
411 {
412 //Disconnect all the stations
413 hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
414 }
415 }
416}
417
418static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
419{
420 struct net_device *dev;
421 VOS_STATUS status = VOS_STATUS_SUCCESS;
422 dev = (struct net_device *)usrDataForCallback;
423 ENTER();
424 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
425 {
426 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
427 {
428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
429 }
430 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
431 }
432 EXIT();
433 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
434}
Jeff Johnson295189b2012-06-20 16:38:30 -0700435
436VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
437{
438 hdd_adapter_t *pHostapdAdapter;
439 hdd_ap_ctx_t *pHddApCtx;
440 hdd_hostapd_state_t *pHostapdState;
441 struct net_device *dev;
442 eSapHddEvent sapEvent;
443 union iwreq_data wrqu;
444 v_BYTE_t *we_custom_event_generic = NULL;
445 int we_event = 0;
446 int i = 0;
447 v_U8_t staId;
448 VOS_STATUS vos_status;
449 v_BOOL_t bWPSState;
450 v_BOOL_t bApActive = FALSE;
451 v_BOOL_t bAuthRequired = TRUE;
452 tpSap_AssocMacAddr pAssocStasArray = NULL;
453 char unknownSTAEvent[IW_CUSTOM_MAX+1];
454 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
455 v_BYTE_t we_custom_start_event[64];
456 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800457 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800458 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700459 struct iw_michaelmicfailure msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700460
461 dev = (struct net_device *)usrDataForCallback;
462 pHostapdAdapter = netdev_priv(dev);
463 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
464 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
465 sapEvent = pSapEvent->sapHddEventCode;
466 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800467 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700468
469 switch(sapEvent)
470 {
471 case eSAP_START_BSS_EVENT :
472 hddLog(LOG1, FL("BSS configured status = %s, channel = %lu, bc sta Id = %d\n"),
473 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
474 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
475 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
476
477 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
478 vos_status = vos_event_set(&pHostapdState->vosEvent);
479
480 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
481 {
482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!\n"));
483 goto stopbss;
484 }
485 else
486 {
487 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
488 //@@@ need wep logic here to set privacy bit
489 hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
490 }
491
492 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
493 {
494 // AP Inactivity timer init and start
495 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
496 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
497 if (!VOS_IS_STATUS_SUCCESS(vos_status))
498 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
499
500 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
501 if (!VOS_IS_STATUS_SUCCESS(vos_status))
502 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
503
504 }
505 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
506 pHostapdState->bssState = BSS_START;
507
508 // Send current operating channel of SoftAP to BTC-ES
509 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
510
Jeff Johnson295189b2012-06-20 16:38:30 -0700511 //Check if there is any group key pending to set.
512 if( pHddApCtx->groupKey.keyLength )
513 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700514 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700515 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
516 &pHddApCtx->groupKey ) )
517 {
518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
519 "%s: WLANSAP_SetKeySta failed", __func__);
520 }
521 pHddApCtx->groupKey.keyLength = 0;
522 }
523 else if ( pHddApCtx->wepKey[0].keyLength )
524 {
525 int i=0;
526 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
527 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700528 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700529 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
530 &pHddApCtx->wepKey[i] ) )
531 {
532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
533 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
534 }
535 pHddApCtx->wepKey[i].keyLength = 0;
536 }
537 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700538 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
539 startBssEvent = "SOFTAP.enabled";
540 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
541 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
542 memset(&wrqu, 0, sizeof(wrqu));
543 wrqu.data.length = strlen(startBssEvent);
544 we_event = IWEVCUSTOM;
545 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700546 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700547 break; //Event will be sent after Switch-Case stmt
548
549 case eSAP_STOP_BSS_EVENT:
550 hddLog(LOG1, FL("BSS stop status = %s\n"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
551 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
552
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700553 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700554 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700555
Jeff Johnson295189b2012-06-20 16:38:30 -0700556 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700557 goto stopbss;
558 case eSAP_STA_SET_KEY_EVENT:
559 //TODO: forward the message to hostapd once implementtation is done for now just print
560 hddLog(LOG1, FL("SET Key: configured status = %s\n"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
561 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
562 return VOS_STATUS_SUCCESS;
563 case eSAP_STA_DEL_KEY_EVENT:
564 //TODO: forward the message to hostapd once implementtation is done for now just print
565 hddLog(LOG1, FL("Event received %s\n"),"eSAP_STA_DEL_KEY_EVENT");
566 return VOS_STATUS_SUCCESS;
567 case eSAP_STA_MIC_FAILURE_EVENT:
568 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 memset(&msg, '\0', sizeof(msg));
570 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800571 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700573 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700574 msg.flags = IW_MICFAILURE_GROUP;
575 else
576 msg.flags = IW_MICFAILURE_PAIRWISE;
577 memset(&wrqu, 0, sizeof(wrqu));
578 wrqu.data.length = sizeof(msg);
579 we_event = IWEVMICHAELMICFAILURE;
580 we_custom_event_generic = (v_BYTE_t *)&msg;
581 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700582 /* inform mic failure to nl80211 */
583 cfg80211_michael_mic_failure(dev,
584 pSapEvent->sapevt.
585 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700586 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700587 NL80211_KEYTYPE_GROUP :
588 NL80211_KEYTYPE_PAIRWISE),
589 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
590 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
591 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700592 break;
593
594 case eSAP_STA_ASSOC_EVENT:
595 case eSAP_STA_REASSOC_EVENT:
596 wrqu.addr.sa_family = ARPHRD_ETHER;
597 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800598 sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700599 hddLog(LOG1, " associated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
600 we_event = IWEVREGISTERED;
601
602 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
603
604 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
605 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
606 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
607 {
608 bAuthRequired = FALSE;
609 }
610
611 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
612 {
613 hdd_softap_RegisterSTA( pHostapdAdapter,
614 TRUE,
615 pHddApCtx->uPrivacy,
616 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
617 0,
618 0,
619 (v_MACADDR_t *)wrqu.addr.sa_data,
620 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
621 }
622 else
623 {
624 hdd_softap_RegisterSTA( pHostapdAdapter,
625 FALSE,
626 pHddApCtx->uPrivacy,
627 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
628 0,
629 0,
630 (v_MACADDR_t *)wrqu.addr.sa_data,
631 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
Amar Singhal6144c002013-05-03 16:11:42 -0700632 }
633
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 // Stop AP inactivity timer
635 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
636 {
637 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
638 if (!VOS_IS_STATUS_SUCCESS(vos_status))
639 hddLog(LOGE, FL("Failed to start AP inactivity timer\n"));
640 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800641#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800642 if (wake_lock_active(&pHddCtx->sap_wake_lock))
643 {
644 wake_unlock(&pHddCtx->sap_wake_lock);
645 }
Amar Singhal6144c002013-05-03 16:11:42 -0700646 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800647#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
649 {
650 struct station_info staInfo;
651 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
652
653 memset(&staInfo, 0, sizeof(staInfo));
654 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
655 {
656 staInfo.assoc_req_ies =
657 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
658 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700659#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700660 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
661#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 cfg80211_new_sta(dev,
663 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
664 &staInfo, GFP_KERNEL);
665 }
666 else
667 {
668 hddLog(LOGE, FL(" Assoc Ie length is too long \n"));
669 }
670 }
671#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800672 pScanInfo = &pHddCtx->scan_info;
673 // Lets do abort scan to ensure smooth authentication for client
674 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
675 {
676 hdd_abort_mac_scan(pHddCtx);
677 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700678
679 break;
680 case eSAP_STA_DISASSOC_EVENT:
681 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800682 sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700683 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
684 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
685 hddLog(LOG1," User initiated disassociation");
686 else
687 hddLog(LOG1," MAC initiated disassociation");
688 we_event = IWEVEXPIRED;
689 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
690 if (!VOS_IS_STATUS_SUCCESS(vos_status))
691 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700692 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 -0700693 return VOS_STATUS_E_FAILURE;
694 }
695 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
696
697 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
698 {
699 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
700 // Start AP inactivity timer if no stations associated with it
701 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
702 {
703 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
704 {
705 bApActive = TRUE;
706 break;
707 }
708 }
709 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
710
711 if (bApActive == FALSE)
712 {
713 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
714 {
715 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
716 if (!VOS_IS_STATUS_SUCCESS(vos_status))
717 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
718 }
719 else
720 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
721 }
722 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
724 cfg80211_del_sta(dev,
725 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
726 GFP_KERNEL);
727#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800728 //Update the beacon Interval if it is P2P GO
729 hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 break;
731 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
732 {
733 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
734 union iwreq_data wreq;
735
736 down(&pHddApCtx->semWpsPBCOverlapInd);
737 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
738
739 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
740 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
741
742 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
743 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
744 memset(&wreq, 0, sizeof(wreq));
745 wreq.data.length = strlen(message); // This is length of message
746 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
747
748 return VOS_STATUS_SUCCESS;
749 }
750 case eSAP_ASSOC_STA_CALLBACK_EVENT:
751 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
752 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
753 { // List of associated stations
754 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
755 {
756 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
757 i+1,
758 pAssocStasArray->assocId,
759 pAssocStasArray->staId,
760 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
761 pAssocStasArray++;
762 }
763 }
764 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
765 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 case eSAP_INDICATE_MGMT_FRAME:
767 hdd_indicateMgmtFrame( pHostapdAdapter,
768 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
769 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
770 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530771 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700772 return VOS_STATUS_SUCCESS;
773 case eSAP_REMAIN_CHAN_READY:
774 hdd_remainChanReadyHandler( pHostapdAdapter );
775 return VOS_STATUS_SUCCESS;
776 case eSAP_SEND_ACTION_CNF:
777 hdd_sendActionCnf( pHostapdAdapter,
778 ( eSAP_STATUS_SUCCESS ==
779 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
780 TRUE : FALSE );
781 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 case eSAP_UNKNOWN_STA_JOIN:
783 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
784 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
785 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
786 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
787 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
788 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
789 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
790 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
791 wrqu.data.pointer = unknownSTAEvent;
792 wrqu.data.length = strlen(unknownSTAEvent);
793 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
794 hddLog(LOG1,"%s\n", unknownSTAEvent);
795 break;
796
797 case eSAP_MAX_ASSOC_EXCEEDED:
798 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
799 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
800 " one or more devices to enable the new device connection",
801 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
802 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
803 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
804 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
805 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
806 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
807 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
808 wrqu.data.pointer = maxAssocExceededEvent;
809 wrqu.data.length = strlen(maxAssocExceededEvent);
810 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
811 hddLog(LOG1,"%s\n", maxAssocExceededEvent);
812 break;
813 case eSAP_STA_ASSOC_IND:
814 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800815
816 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
817 hddLog(LOG1, FL(" Disconnecting all the P2P Clients....\n"));
818 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
819 return VOS_STATUS_SUCCESS;
820
821 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
822 hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
823 return VOS_STATUS_SUCCESS;
824
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 default:
826 hddLog(LOG1,"SAP message is not handled\n");
827 goto stopbss;
828 return VOS_STATUS_SUCCESS;
829 }
830 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
831 return VOS_STATUS_SUCCESS;
832
833stopbss :
834 {
835 v_BYTE_t we_custom_event[64];
836 char *stopBssEvent = "STOP-BSS.response";//17
837 int event_len = strlen(stopBssEvent);
838
839 hddLog(LOG1, FL("BSS stop status = %s"),
840 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
841 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
842
843 /* Change the BSS state now since, as we are shutting things down,
844 * we don't want interfaces to become re-enabled */
845 pHostapdState->bssState = BSS_STOP;
846
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +0530847 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
848 {
849 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
850 {
851 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
852 if (!VOS_IS_STATUS_SUCCESS(vos_status))
853 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
854 }
855
856 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
857 if (!VOS_IS_STATUS_SUCCESS(vos_status))
858 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
859 }
860
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 /* Stop the pkts from n/w stack as we are going to free all of
862 * the TX WMM queues for all STAID's */
863 hdd_hostapd_stop(dev);
864
865 /* reclaim all resources allocated to the BSS */
866 hdd_softap_stop_bss(pHostapdAdapter);
867
Amar Singhal37e6f052013-03-05 16:16:54 -0800868 /* once the event is set, structure dev/pHostapdAdapter should
869 * not be touched since they are now subject to being deleted
870 * by another thread */
871 if (eSAP_STOP_BSS_EVENT == sapEvent)
872 vos_event_set(&pHostapdState->vosEvent);
873
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 /* notify userspace that the BSS has stopped */
875 memset(&we_custom_event, '\0', sizeof(we_custom_event));
876 memcpy(&we_custom_event, stopBssEvent, event_len);
877 memset(&wrqu, 0, sizeof(wrqu));
878 wrqu.data.length = event_len;
879 we_event = IWEVCUSTOM;
880 we_custom_event_generic = we_custom_event;
881 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700882 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 }
884 return VOS_STATUS_SUCCESS;
885}
886int hdd_softap_unpackIE(
887 tHalHandle halHandle,
888 eCsrEncryptionType *pEncryptType,
889 eCsrEncryptionType *mcEncryptType,
890 eCsrAuthType *pAuthType,
891 u_int16_t gen_ie_len,
892 u_int8_t *gen_ie )
893{
894 tDot11fIERSN dot11RSNIE;
895 tDot11fIEWPA dot11WPAIE;
896
897 tANI_U8 *pRsnIe;
898 tANI_U16 RSNIeLen;
899
900 if (NULL == halHandle)
901 {
902 hddLog(LOGE, FL("Error haHandle returned NULL\n"));
903 return -EINVAL;
904 }
905
906 // Validity checks
907 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
908 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
909 return -EINVAL;
910 // Type check
911 if ( gen_ie[0] == DOT11F_EID_RSN)
912 {
913 // Validity checks
914 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
915 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
916 {
917 return VOS_STATUS_E_FAILURE;
918 }
919 // Skip past the EID byte and length byte
920 pRsnIe = gen_ie + 2;
921 RSNIeLen = gen_ie_len - 2;
922 // Unpack the RSN IE
923 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
924 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
925 pRsnIe,
926 RSNIeLen,
927 &dot11RSNIE);
928 // Copy out the encryption and authentication types
929 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700930 __func__, dot11RSNIE.pwise_cipher_suite_count );
Jeff Johnson295189b2012-06-20 16:38:30 -0700931 hddLog(LOG1, FL("%s: authentication suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700932 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 /*Here we have followed the apple base code,
934 but probably I suspect we can do something different*/
935 //dot11RSNIE.akm_suite_count
936 // Just translate the FIRST one
937 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
938 //dot11RSNIE.pwise_cipher_suite_count
939 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
940 //dot11RSNIE.gp_cipher_suite_count
941 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
942 // Set the PMKSA ID Cache for this interface
943
944 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
945 } else
946 if (gen_ie[0] == DOT11F_EID_WPA)
947 {
948 // Validity checks
949 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
950 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
951 {
952 return VOS_STATUS_E_FAILURE;
953 }
954 // Skip past the EID byte and length byte - and four byte WiFi OUI
955 pRsnIe = gen_ie + 2 + 4;
956 RSNIeLen = gen_ie_len - (2 + 4);
957 // Unpack the WPA IE
958 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
959 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
960 pRsnIe,
961 RSNIeLen,
962 &dot11WPAIE);
963 // Copy out the encryption and authentication types
964 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700965 __func__, dot11WPAIE.unicast_cipher_count );
Jeff Johnson295189b2012-06-20 16:38:30 -0700966 hddLog(LOG1, FL("%s: WPA authentication suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700967 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 //dot11WPAIE.auth_suite_count
969 // Just translate the FIRST one
970 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
971 //dot11WPAIE.unicast_cipher_count
972 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
973 //dot11WPAIE.unicast_cipher_count
974 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
975 }
976 else
977 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700978 hddLog(LOGW, FL("%s: gen_ie[0]: %d\n"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -0700979 return VOS_STATUS_E_FAILURE;
980 }
981 return VOS_STATUS_SUCCESS;
982}
983int
984static iw_softap_setparam(struct net_device *dev,
985 struct iw_request_info *info,
986 union iwreq_data *wrqu, char *extra)
987{
988 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
989 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
990 int *value = (int *)extra;
991 int sub_cmd = value[0];
992 int set_value = value[1];
993 eHalStatus status;
994 int ret = 0; /* success */
995 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
996
997 switch(sub_cmd)
998 {
999
1000 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001001 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 {
1003 ret = -EIO;
1004 }
1005 break;
1006
1007 case QCSAP_PARAM_ACL_MODE:
1008 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1009 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1010 {
1011 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1012 ret = -EINVAL;
1013 }
1014 else
1015 {
1016 WLANSAP_SetMode(pVosContext, set_value);
1017 }
1018 break;
1019 case QCSAP_PARAM_MAX_ASSOC:
1020 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1021 {
1022 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1023 ret = -EINVAL;
1024 }
1025 else
1026 {
1027 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1028 {
1029 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1030 "Setting it to max allowed and continuing"),
1031 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1032 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1033 }
1034 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1035 set_value, NULL, eANI_BOOLEAN_FALSE);
1036 if ( status != eHAL_STATUS_SUCCESS )
1037 {
1038 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1039 status);
1040 ret = -EIO;
1041 }
1042 }
1043 break;
1044
1045 case QCSAP_PARAM_HIDE_SSID:
1046 {
1047 eHalStatus status = eHAL_STATUS_SUCCESS;
1048 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1049 if(eHAL_STATUS_SUCCESS != status)
1050 {
1051 hddLog(VOS_TRACE_LEVEL_ERROR,
1052 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001053 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 return status;
1055 }
1056 break;
1057 }
1058
1059 default:
1060 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1061 sub_cmd, set_value);
1062 ret = -EINVAL;
1063 break;
1064 }
1065
1066 return ret;
1067}
1068
1069
1070int
1071static iw_softap_getparam(struct net_device *dev,
1072 struct iw_request_info *info,
1073 union iwreq_data *wrqu, char *extra)
1074{
1075 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1076 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1077 int *value = (int *)extra;
1078 int sub_cmd = value[0];
1079 eHalStatus status;
1080 int ret = 0; /* success */
1081 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1082
1083 switch (sub_cmd)
1084 {
1085 case QCSAP_PARAM_MAX_ASSOC:
1086 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1087 if (eHAL_STATUS_SUCCESS != status)
1088 {
1089 ret = -EIO;
1090 }
1091 break;
1092
1093 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001094 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 {
1096 ret = -EIO;
1097 }
1098 *value = 0;
1099 break;
1100
1101 case QCSAP_PARAM_MODULE_DOWN_IND:
1102 {
1103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001104 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1106#ifdef WLAN_BTAMP_FEATURE
1107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001108 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1110#endif
1111 *value = 0;
1112 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001113 }
1114
1115 case QCSAP_PARAM_GET_WLAN_DBG:
1116 {
1117 vos_trace_display();
1118 *value = 0;
1119 break;
1120 }
1121
1122 case QCSAP_PARAM_AUTO_CHANNEL:
1123 {
1124 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1125 break;
1126 }
1127
Jeff Johnson295189b2012-06-20 16:38:30 -07001128 default:
1129 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1130 ret = -EINVAL;
1131 break;
1132
1133 }
1134
1135 return ret;
1136}
1137
1138/* Usage:
1139 BLACK_LIST = 0
1140 WHITE_LIST = 1
1141 ADD MAC = 0
1142 REMOVE MAC = 1
1143
1144 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1145 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1146 while using this ioctl
1147
1148 Syntax:
1149 iwpriv softap.0 modify_acl
1150 <6 octet mac addr> <list type> <cmd type>
1151
1152 Examples:
1153 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1154 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1155 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1156 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1157*/
1158int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1159 union iwreq_data *wrqu, char *extra)
1160{
1161 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1162 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1163 v_BYTE_t *value = (v_BYTE_t*)extra;
1164 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1165 int listType, cmd, i;
1166 int ret = 0; /* success */
1167
1168 ENTER();
1169 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1170 {
1171 pPeerStaMac[i] = *(value+i);
1172 }
1173 listType = (int)(*(value+i));
1174 i++;
1175 cmd = (int)(*(value+i));
1176
1177 hddLog(LOG1, "%s: SAP Modify ACL arg0 %02x:%02x:%02x:%02x:%02x:%02x arg1 %d arg2 %d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001178 __func__, pPeerStaMac[0], pPeerStaMac[1], pPeerStaMac[2],
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 pPeerStaMac[3], pPeerStaMac[4], pPeerStaMac[5], listType, cmd);
1180
1181 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1182 != VOS_STATUS_SUCCESS)
1183 {
1184 hddLog(LOGE, FL("Modify ACL failed\n"));
1185 ret = -EIO;
1186 }
1187 EXIT();
1188 return ret;
1189}
1190
1191int
1192static iw_softap_getchannel(struct net_device *dev,
1193 struct iw_request_info *info,
1194 union iwreq_data *wrqu, char *extra)
1195{
1196 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1197
Jeff Johnson43971f52012-07-17 12:26:56 -07001198 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001199
Jeff Johnson43971f52012-07-17 12:26:56 -07001200 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 return 0;
1202}
1203
Jeff Johnsone7245742012-09-05 17:12:55 -07001204int
schang86c22c42013-03-13 18:41:24 -07001205static iw_softap_set_max_tx_power(struct net_device *dev,
Jeff Johnsone7245742012-09-05 17:12:55 -07001206 struct iw_request_info *info,
1207 union iwreq_data *wrqu, char *extra)
1208{
1209 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1210 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001211 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001212 int set_value;
1213 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1214 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1215
schang86c22c42013-03-13 18:41:24 -07001216 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001217 return -ENOMEM;
1218
schang86c22c42013-03-13 18:41:24 -07001219 set_value = value[0];
1220 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001223 __func__);
schang86c22c42013-03-13 18:41:24 -07001224 return -EIO;
1225 }
1226
1227 return 0;
1228}
1229
1230int
1231static iw_softap_set_tx_power(struct net_device *dev,
1232 struct iw_request_info *info,
1233 union iwreq_data *wrqu, char *extra)
1234{
1235 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1236 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1237 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1238 int *value = (int *)extra;
1239 int set_value;
1240 ptSapContext pSapCtx = NULL;
1241
1242 if (NULL == value)
1243 return -ENOMEM;
1244
1245 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1246 if (NULL == pSapCtx)
1247 {
1248 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1249 "%s: Invalid SAP pointer from pvosGCtx", __func__);
1250 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07001251 }
1252
1253 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07001254 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07001255 {
schang86c22c42013-03-13 18:41:24 -07001256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07001257 __func__);
1258 return -EIO;
1259 }
1260
1261 return 0;
1262}
1263
Jeff Johnson295189b2012-06-20 16:38:30 -07001264#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1265
1266int
1267static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1268 struct iw_request_info *info,
1269 union iwreq_data *wrqu, char *extra)
1270{
1271 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1272 unsigned char *pmaclist;
1273 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
1274 int cnt = 0, len;
1275
1276
1277 pmaclist = wrqu->data.pointer + sizeof(unsigned long int);
1278 len = wrqu->data.length;
1279
1280 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
1281 while((cnt < WLAN_MAX_STA_COUNT) && (len > (sizeof(v_MACADDR_t)+1))) {
1282 if (TRUE == pStaInfo[cnt].isUsed) {
1283
1284 if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
1285 memcpy((void *)pmaclist, (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t));
1286 pmaclist += sizeof(v_MACADDR_t);
1287 len -= sizeof(v_MACADDR_t);
1288 }
1289 }
1290 cnt++;
1291 }
1292 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
1293
1294 *pmaclist = '\0';
1295
1296 wrqu->data.length -= len;
1297
1298 *(unsigned long int *)(wrqu->data.pointer) = wrqu->data.length;
1299
1300 return 0;
1301}
1302
1303/* Usage:
1304 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1305 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1306 while using this ioctl
1307
1308 Syntax:
1309 iwpriv softap.0 disassoc_sta <6 octet mac address>
1310
1311 e.g.
1312 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1313 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1314*/
1315
1316int
1317static iw_softap_disassoc_sta(struct net_device *dev,
1318 struct iw_request_info *info,
1319 union iwreq_data *wrqu, char *extra)
1320{
1321 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1322 v_U8_t *peerMacAddr;
1323
1324 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301325 /* iwpriv tool or framework calls this ioctl with
1326 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301328 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07001329
1330 hddLog(LOG1, "data %02x:%02x:%02x:%02x:%02x:%02x",
1331 peerMacAddr[0], peerMacAddr[1], peerMacAddr[2],
1332 peerMacAddr[3], peerMacAddr[4], peerMacAddr[5]);
1333 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1334 EXIT();
1335 return 0;
1336}
1337
1338int
1339static iw_softap_ap_stats(struct net_device *dev,
1340 struct iw_request_info *info,
1341 union iwreq_data *wrqu, char *extra)
1342{
1343 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1344 WLANTL_TRANSFER_STA_TYPE statBuffer;
1345 char *pstatbuf;
1346 int len = wrqu->data.length;
1347 pstatbuf = wrqu->data.pointer;
1348
1349 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &statBuffer, (v_BOOL_t)wrqu->data.flags);
1350
1351 len = snprintf(pstatbuf, len,
1352 "RUF=%d RMF=%d RBF=%d "
1353 "RUB=%d RMB=%d RBB=%d "
1354 "TUF=%d TMF=%d TBF=%d "
1355 "TUB=%d TMB=%d TBB=%d",
1356 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, (int)statBuffer.rxBCFcnt,
1357 (int)statBuffer.rxUCBcnt, (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1358 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, (int)statBuffer.txBCFcnt,
1359 (int)statBuffer.txUCBcnt, (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt
1360 );
1361
1362 wrqu->data.length -= len;
1363 return 0;
1364}
1365
1366int
1367static iw_softap_commit(struct net_device *dev,
1368 struct iw_request_info *info,
1369 union iwreq_data *wrqu, char *extra)
1370{
1371 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1372 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1373 hdd_hostapd_state_t *pHostapdState;
1374 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1375 tpWLAN_SAPEventCB pSapEventCallback;
1376 tsap_Config_t *pConfig;
1377 s_CommitConfig_t *pCommitConfig;
1378 struct qc_mac_acl_entry *acl_entry = NULL;
1379 v_SINT_t i = 0, num_mac = 0;
1380 v_U32_t status = 0;
1381 eCsrAuthType RSNAuthType;
1382 eCsrEncryptionType RSNEncryptType;
1383 eCsrEncryptionType mcRSNEncryptType;
1384
1385 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1386 pCommitConfig = (s_CommitConfig_t *)extra;
1387
1388 pConfig = kmalloc(sizeof(tsap_Config_t), GFP_KERNEL);
1389 if(NULL == pConfig) {
1390 hddLog(LOG1, "VOS unable to allocate memory\n");
1391 return -ENOMEM;
1392 }
1393 pConfig->beacon_int = pCommitConfig->beacon_int;
1394 pConfig->channel = pCommitConfig->channel;
1395
1396 /*Protection parameter to enable or disable*/
1397 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1398 pConfig->dtim_period = pCommitConfig->dtim_period;
1399 switch(pCommitConfig->hw_mode )
1400 {
1401 case eQC_DOT11_MODE_11A:
1402 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
1403 break;
1404 case eQC_DOT11_MODE_11B:
1405 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
1406 break;
1407 case eQC_DOT11_MODE_11G:
1408 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
1409 break;
1410
1411 case eQC_DOT11_MODE_11N:
1412 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1413 break;
1414 case eQC_DOT11_MODE_11G_ONLY:
1415 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1416 break;
1417 case eQC_DOT11_MODE_11N_ONLY:
1418 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
1419 break;
1420 default:
1421 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1422 break;
1423
1424 }
1425
1426 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
1427 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
1428 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
1429 pConfig->authType = eSAP_SHARED_KEY;
1430 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
1431 pConfig->authType = eSAP_OPEN_SYSTEM;
1432 else
1433 pConfig->authType = eSAP_AUTO_SWITCH;
1434
1435 pConfig->privacy = pCommitConfig->privacy;
1436 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
1437 pConfig->wps_state = pCommitConfig->wps_state;
1438 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1439 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
1440 if(pConfig->RSNWPAReqIELength){
1441 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
1442 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
1443 // The actual processing may eventually be more extensive than this.
1444 // Right now, just consume any PMKIDs that are sent in by the app.
1445 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 &RSNEncryptType,
1448 &mcRSNEncryptType,
1449 &RSNAuthType,
1450 pConfig->pRSNWPAReqIE[1]+2,
1451 pConfig->pRSNWPAReqIE );
1452
1453 if( VOS_STATUS_SUCCESS == status )
1454 {
1455 // Now copy over all the security attributes you have parsed out
1456 //TODO: Need to handle mixed mode
1457 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1458 pConfig->mcRSNEncryptType = mcRSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301459 hddLog( LOG1, FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1461 }
1462 }
1463 }
1464 else
1465 {
1466 /* If no RSNIE, set encrypt type to NONE*/
1467 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1468 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1469 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d\n"),
1470 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
1471 }
1472
Chilam Ngc4244af2013-04-01 15:37:32 -07001473 if (pConfig->RSNWPAReqIELength > QCSAP_MAX_OPT_IE) {
1474 hddLog(LOGE, FL("RSNWPAReqIELength: %d too large"), pConfig->RSNWPAReqIELength);
1475 kfree(pConfig);
1476 return -EIO;
1477 }
1478
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
1480 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
1481 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
1482 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1483
1484 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
1485
1486 // ht_capab is not what the name conveys,this is used for protection bitmap
1487 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1488
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301489 if (pCommitConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1490 num_mac = pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001491 else
1492 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
1493 acl_entry = pCommitConfig->accept_mac;
1494 for (i = 0; i < num_mac; i++)
1495 {
1496 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1497 acl_entry++;
1498 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301499 if (pCommitConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1500 num_mac = pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001501 else
1502 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
1503 acl_entry = pCommitConfig->deny_mac;
1504 for (i = 0; i < num_mac; i++)
1505 {
1506 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1507 acl_entry++;
1508 }
1509 //Uapsd Enabled Bit
1510 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1511 //Enable OBSS protection
1512 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1513 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
1514
1515 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1516 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1517 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int, (int)pConfig->channel);
1518 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1519 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy, pConfig->authType);
1520 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1521 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1522 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),pConfig->protEnabled, pConfig->obssProtEnabled);
1523 hddLog(LOGW,FL("DisableIntraBssFwd = %d\n"),(WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
1524
1525 pSapEventCallback = hdd_hostapd_SAPEventCB;
1526 pConfig->persona = pHostapdAdapter->device_mode;
1527 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
1528 {
1529 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1530 }
1531
1532 kfree(pConfig);
1533
1534 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1535 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1536
1537 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1538 {
1539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos wait for single_event failed!!\n"));
1540 VOS_ASSERT(0);
1541 }
1542
1543 pHostapdState->bCommit = TRUE;
1544 if(pHostapdState->vosStatus)
1545 {
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001546 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001547 }
1548 else
1549 {
1550 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1551 WLANSAP_Update_WpsIe ( pVosContext );
1552 return 0;
1553 }
1554}
1555static
1556int iw_softap_setmlme(struct net_device *dev,
1557 struct iw_request_info *info,
1558 union iwreq_data *wrqu, char *extra)
1559{
1560 struct sQcSapreq_mlme *pmlme;
1561 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
1562 v_MACADDR_t destAddress;
1563 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
1564 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
1565 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
1566 switch(pmlme->im_op)
1567 {
1568 case QCSAP_MLME_AUTHORIZE:
1569 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
1570 break;
1571 case QCSAP_MLME_ASSOC:
1572 //TODO:inform to TL after associating (not needed as we do in sapCallback)
1573 break;
1574 case QCSAP_MLME_UNAUTHORIZE:
1575 //TODO: send the disassoc to station
1576 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
1577 break;
1578 case QCSAP_MLME_DISASSOC:
1579 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
1580 break;
1581 case QCSAP_MLME_DEAUTH:
1582 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
1583 break;
1584 case QCSAP_MLME_MICFAILURE:
1585 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
1586 break;
1587 default:
1588 break;
1589 }
1590 return 0;
1591}
1592
1593static int iw_softap_set_channel_range(struct net_device *dev,
1594 struct iw_request_info *info,
1595 union iwreq_data *wrqu, char *extra)
1596{
1597 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1598 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001599 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001600
1601 int *value = (int *)extra;
1602 int startChannel = value[0];
1603 int endChannel = value[1];
1604 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07001605 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07001606 int ret = 0; /* success */
1607
1608 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
1609 if(status != VOS_STATUS_SUCCESS)
1610 {
1611 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d\n"),
1612 startChannel,endChannel, band);
1613 ret = -EINVAL;
1614 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08001615
1616 pHddCtx->is_dynamic_channel_range_set = 1;
1617
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 return ret;
1619}
1620
1621int iw_softap_get_channel_list(struct net_device *dev,
1622 struct iw_request_info *info,
1623 union iwreq_data *wrqu, char *extra)
1624{
1625 v_U32_t num_channels = 0;
1626 v_U8_t i = 0;
1627 v_U8_t bandStartChannel = RF_CHAN_1;
1628 v_U8_t bandEndChannel = RF_CHAN_165;
1629 v_U32_t temp_num_channels = 0;
1630 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001631 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1633 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001635 eCsrBand curBand = eCSR_BAND_ALL;
1636
1637 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
1638 {
1639 hddLog(LOGE,FL("not able get the current frequency band\n"));
1640 return -EIO;
1641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 wrqu->data.length = sizeof(tChannelListInfo);
1643 ENTER();
1644
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001645 if (eCSR_BAND_24 == curBand)
1646 {
1647 bandStartChannel = RF_CHAN_1;
1648 bandEndChannel = RF_CHAN_14;
1649 }
1650 else if (eCSR_BAND_5G == curBand)
1651 {
1652 bandStartChannel = RF_CHAN_36;
1653 bandEndChannel = RF_CHAN_165;
1654 }
1655
1656 hddLog(LOG1, FL("\n nBandCapability = %d, bandStartChannel = %hu, "
1657 "bandEndChannel = %hu \n"), pHddCtx->cfg_ini->nBandCapability,
1658 bandStartChannel, bandEndChannel );
1659
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 for( i = bandStartChannel; i <= bandEndChannel; i++ )
1661 {
1662 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
1663 {
1664 channel_list->channels[num_channels] = rfChannels[i].channelNum;
1665 num_channels++;
1666 }
1667 }
1668
1669 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
1670
1671 temp_num_channels = num_channels;
1672
1673 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
1674 {
1675 hddLog(LOG1,FL("Failed to get Domain ID, %d \n"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001676 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 }
1678
1679 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
1680 {
1681 for(i = 0; i < temp_num_channels; i++)
1682 {
1683
1684 if((channel_list->channels[i] > 35) &&
1685 (channel_list->channels[i] < 49))
1686 {
1687 vos_mem_move(&channel_list->channels[i],
1688 &channel_list->channels[i+1],
1689 temp_num_channels - (i-1));
1690 num_channels--;
1691 temp_num_channels--;
1692 i--;
1693 }
1694 }
1695 }
1696
1697 hddLog(LOG1,FL(" number of channels %d\n"), num_channels);
1698
1699 if (num_channels > IW_MAX_FREQUENCIES)
1700 {
1701 num_channels = IW_MAX_FREQUENCIES;
1702 }
1703
1704 channel_list->num_channels = num_channels;
1705 EXIT();
1706
1707 return 0;
1708}
1709
1710static
1711int iw_get_genie(struct net_device *dev,
1712 struct iw_request_info *info,
1713 union iwreq_data *wrqu, char *extra)
1714{
1715 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1716 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1717 eHalStatus status;
1718 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
1719 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
1720 ENTER();
1721 hddLog(LOG1,FL("getGEN_IE ioctl\n"));
1722 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
1723 status = WLANSap_getstationIE_information(pVosContext,
1724 &length,
1725 genIeBytes);
1726 wrqu->data.length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
1727 vos_mem_copy( wrqu->data.pointer, (v_VOID_t*)genIeBytes, wrqu->data.length);
1728
1729 hddLog(LOG1,FL(" RSN IE of %d bytes returned\n"), wrqu->data.length );
1730
1731
1732 EXIT();
1733 return 0;
1734}
1735static
1736int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
1737 struct iw_request_info *info,
1738 union iwreq_data *wrqu, char *extra)
1739{
1740 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1741 sQcSapreq_WPSPBCProbeReqIES_t *pWPSPBCProbeReqIEs;
1742 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1743 ENTER();
1744
1745 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl\n"));
1746
1747 pWPSPBCProbeReqIEs = (sQcSapreq_WPSPBCProbeReqIES_t *)(wrqu->data.pointer);
1748 pWPSPBCProbeReqIEs->probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
1749 vos_mem_copy(pWPSPBCProbeReqIEs->probeReqIE, pHddApCtx->WPSPBCProbeReq.probeReqIE, pWPSPBCProbeReqIEs->probeReqIELen);
1750 vos_mem_copy(pWPSPBCProbeReqIEs->macaddr, pHddApCtx->WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
1751 wrqu->data.length = 12 + pWPSPBCProbeReqIEs->probeReqIELen;
1752 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pWPSPBCProbeReqIEs->macaddr));
1753 up(&pHddApCtx->semWpsPBCOverlapInd);
1754 EXIT();
1755 return 0;
1756}
1757
1758/**---------------------------------------------------------------------------
1759
1760 \brief iw_set_auth_hostap() -
1761 This function sets the auth type received from the wpa_supplicant.
1762
1763 \param - dev - Pointer to the net device.
1764 - info - Pointer to the iw_request_info.
1765 - wrqu - Pointer to the iwreq_data.
1766 - extra - Pointer to the data.
1767 \return - 0 for success, non zero for failure
1768
1769 --------------------------------------------------------------------------*/
1770int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
1771 union iwreq_data *wrqu,char *extra)
1772{
1773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1774 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1775
1776 ENTER();
1777 switch(wrqu->param.flags & IW_AUTH_INDEX)
1778 {
1779 case IW_AUTH_TKIP_COUNTERMEASURES:
1780 {
1781 if(wrqu->param.value) {
1782 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1783 "Counter Measure started %d", wrqu->param.value);
1784 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
1785 }
1786 else {
1787 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1788 "Counter Measure stopped=%d", wrqu->param.value);
1789 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
1790 }
1791
1792 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
1793 wrqu->param.value);
1794 }
1795 break;
1796
1797 default:
1798
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001799 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 wrqu->param.flags & IW_AUTH_INDEX);
1801 break;
1802 }
1803
1804 EXIT();
1805 return 0;
1806}
1807
1808static int iw_set_ap_encodeext(struct net_device *dev,
1809 struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1811{
1812 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1813 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1814 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07001815 int retval = 0;
1816 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001817 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1818 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1819 int key_index;
1820 struct iw_point *encoding = &wrqu->encoding;
1821 tCsrRoamSetKey setKey;
1822// tCsrRoamRemoveKey RemoveKey;
1823 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07001824
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 ENTER();
1826
1827 key_index = encoding->flags & IW_ENCODE_INDEX;
1828
1829 if(key_index > 0) {
1830
1831 /*Convert from 1-based to 0-based keying*/
1832 key_index--;
1833 }
1834 if(!ext->key_len) {
1835#if 0
1836 /*Set the encrytion type to NONE*/
1837#if 0
1838 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
1839#endif
1840
1841 RemoveKey.keyId = key_index;
1842 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1843 /*Key direction for group is RX only*/
1844 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1845 }
1846 else {
1847 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1848 }
1849 switch(ext->alg)
1850 {
1851 case IW_ENCODE_ALG_NONE:
1852 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1853 break;
1854 case IW_ENCODE_ALG_WEP:
1855 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1856 break;
1857 case IW_ENCODE_ALG_TKIP:
1858 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07001859 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 case IW_ENCODE_ALG_CCMP:
1861 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
1862 break;
1863 default:
1864 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1865 break;
1866 }
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d \n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001868 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR"\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001870 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001871 );
Jeff Johnson43971f52012-07-17 12:26:56 -07001872 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
1873 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07001874 {
1875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07001876 __LINE__, vstatus );
1877 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001879#endif
1880 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07001881
Jeff Johnson43971f52012-07-17 12:26:56 -07001882 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001883
1884 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
1885
1886 setKey.keyId = key_index;
1887 setKey.keyLength = ext->key_len;
1888
1889 if(ext->key_len <= CSR_MAX_KEY_LEN) {
1890 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
1891 }
1892
1893 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1894 /*Key direction for group is RX only*/
1895 setKey.keyDirection = eSIR_RX_ONLY;
1896 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1897 }
1898 else {
1899
1900 setKey.keyDirection = eSIR_TX_RX;
1901 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1902 }
1903 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1904 {
1905 setKey.keyDirection = eSIR_TX_DEFAULT;
1906 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1907 }
1908
1909 /*For supplicant pae role is zero*/
1910 setKey.paeRole = 0;
1911
1912 switch(ext->alg)
1913 {
1914 case IW_ENCODE_ALG_NONE:
1915 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1916 break;
1917
1918 case IW_ENCODE_ALG_WEP:
1919 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1920 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001921 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 break;
1923
1924 case IW_ENCODE_ALG_TKIP:
1925 {
1926 v_U8_t *pKey = &setKey.Key[0];
1927
1928 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
1929
1930 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
1931
1932 /*Supplicant sends the 32bytes key in this order
1933
1934 |--------------|----------|----------|
1935 | Tk1 |TX-MIC | RX Mic |
1936 |--------------|----------|----------|
1937 <---16bytes---><--8bytes--><--8bytes-->
1938
1939 */
1940 /*Sme expects the 32 bytes key to be in the below order
1941
1942 |--------------|----------|----------|
1943 | Tk1 |RX-MIC | TX Mic |
1944 |--------------|----------|----------|
1945 <---16bytes---><--8bytes--><--8bytes-->
1946 */
1947 /* Copy the Temporal Key 1 (TK1) */
1948 vos_mem_copy(pKey,ext->key,16);
1949
1950 /*Copy the rx mic first*/
1951 vos_mem_copy(&pKey[16],&ext->key[24],8);
1952
1953 /*Copy the tx mic */
1954 vos_mem_copy(&pKey[24],&ext->key[16],8);
1955
1956 }
1957 break;
1958
1959 case IW_ENCODE_ALG_CCMP:
1960 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
1961 break;
1962
1963 default:
1964 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1965 break;
1966 }
1967
1968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301969 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 setKey.keyId);
1971 for(i=0; i< ext->key_len; i++)
1972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1973 ("%02x"), setKey.Key[i]);
1974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1975 ("\n"));
Jeff Johnson43971f52012-07-17 12:26:56 -07001976
1977 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
1978 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 {
1980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07001981 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
1982 retval = -EINVAL;
1983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001984
Jeff Johnson43971f52012-07-17 12:26:56 -07001985 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07001986}
Jeff Johnson43971f52012-07-17 12:26:56 -07001987
1988
Jeff Johnson295189b2012-06-20 16:38:30 -07001989static int iw_set_ap_mlme(struct net_device *dev,
1990 struct iw_request_info *info,
1991 union iwreq_data *wrqu,
1992 char *extra)
1993{
1994#if 0
1995 hdd_adapter_t *pAdapter = (netdev_priv(dev));
1996 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1997
1998 ENTER();
1999
2000 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2001 switch (mlme->cmd) {
2002 case IW_MLME_DISASSOC:
2003 case IW_MLME_DEAUTH:
2004 hddLog(LOG1, "Station disassociate");
2005 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2006 {
2007 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2008
2009 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2010 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2011
2012 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2013
2014 //clear all the reason codes
2015 if (status != 0)
2016 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002017 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d \n", __func__, (int)mlme->cmd, (int)status );
Jeff Johnson295189b2012-06-20 16:38:30 -07002018 }
2019
2020 netif_stop_queue(dev);
2021 netif_carrier_off(dev);
2022 }
2023 else
2024 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002025 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state \n", __func__, (int)mlme->cmd );
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 }
2027 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002028 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate \n", __func__, (int)mlme->cmd );
Jeff Johnson295189b2012-06-20 16:38:30 -07002029 return -EINVAL;
2030 }//end of switch
2031 EXIT();
2032#endif
2033 return 0;
2034// return status;
2035}
2036
2037static int iw_get_ap_rts_threshold(struct net_device *dev,
2038 struct iw_request_info *info,
2039 union iwreq_data *wrqu, char *extra)
2040{
2041 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2042 v_U32_t status = 0;
2043
2044 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2045
2046 return status;
2047}
2048
2049static int iw_get_ap_frag_threshold(struct net_device *dev,
2050 struct iw_request_info *info,
2051 union iwreq_data *wrqu, char *extra)
2052{
2053 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2054 v_U32_t status = 0;
2055
2056 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2057
2058 return status;
2059}
2060
2061static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2062 struct iw_freq *fwrq, char *extra)
2063{
Jeff Johnsone7245742012-09-05 17:12:55 -07002064 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2066 tHalHandle hHal;
2067 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002068 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002069
2070 ENTER();
2071
2072 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2074 "%s:LOGP in Progress. Ignore!!!",__func__);
2075 return status;
2076 }
2077
2078 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2079 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2080
2081 if(pHostapdState->bssState == BSS_STOP )
2082 {
2083 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2084 != eHAL_STATUS_SUCCESS)
2085 {
2086 return -EIO;
2087 }
2088 else
2089 {
2090 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002091 if( TRUE == status)
2092 {
2093 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2094 * iwlist & iwconfig command shows frequency into proper
2095 * format (2.412 GHz instead of 246.2 MHz)*/
2096 fwrq->m = freq;
2097 fwrq->e = MHZ;
2098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 }
2100 }
2101 else
2102 {
2103 channel = pHddApCtx->operatingChannel;
2104 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002105 if( TRUE == status)
2106 {
2107 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2108 * iwlist & iwconfig command shows frequency into proper
2109 * format (2.412 GHz instead of 246.2 MHz)*/
2110 fwrq->m = freq;
2111 fwrq->e = MHZ;
2112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002114 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002115}
2116
2117static int iw_softap_setwpsie(struct net_device *dev,
2118 struct iw_request_info *info,
2119 union iwreq_data *wrqu,
2120 char *extra)
2121{
2122 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2123 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2124 hdd_hostapd_state_t *pHostapdState;
2125 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2126 u_int8_t *wps_genie = wrqu->data.pointer;
2127 u_int8_t *pos;
2128 tpSap_WPSIE pSap_WPSIe;
2129 u_int8_t WPSIeType;
2130 u_int16_t length;
2131 ENTER();
2132
2133 if(!wrqu->data.length)
2134 return 0;
2135
2136 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2137 if (NULL == pSap_WPSIe)
2138 {
2139 hddLog(LOGE, "VOS unable to allocate memory\n");
2140 return -ENOMEM;
2141 }
2142 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2143
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002144 hddLog(LOG1,"%s WPS IE type[0x%X] IE[0x%X], LEN[%d]\n", __func__, wps_genie[0], wps_genie[1], wps_genie[2]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002145 WPSIeType = wps_genie[0];
2146 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2147 {
2148 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2149 wps_genie = wps_genie + 1;
2150 switch ( wps_genie[0] )
2151 {
2152 case DOT11F_EID_WPA:
2153 if (wps_genie[1] < 2 + 4)
2154 {
2155 vos_mem_free(pSap_WPSIe);
2156 return -EINVAL;
2157 }
2158 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2159 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002160 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002161 pos = &wps_genie[6];
2162 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2163 {
2164 switch((u_int16_t)(*pos<<8) | *(pos+1))
2165 {
2166 case HDD_WPS_ELEM_VERSION:
2167 pos += 4;
2168 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
2169 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
2170 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2171 pos += 1;
2172 break;
2173
2174 case HDD_WPS_ELEM_WPS_STATE:
2175 pos +=4;
2176 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
2177 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
2178 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2179 pos += 1;
2180 break;
2181 case HDD_WPS_ELEM_APSETUPLOCK:
2182 pos += 4;
2183 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
2184 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
2185 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2186 pos += 1;
2187 break;
2188 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2189 pos += 4;
2190 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
2191 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
2192 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2193 pos += 1;
2194 break;
2195 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2196 pos += 4;
2197 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2198 hddLog(LOG1, "Password ID: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
2199 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2200 pos += 2;
2201 break;
2202 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2203 pos += 4;
2204 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2205 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
2206 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2207 pos += 2;
2208 break;
2209
2210 case HDD_WPS_ELEM_UUID_E:
2211 pos += 2;
2212 length = *pos<<8 | *(pos+1);
2213 pos += 2;
2214 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2215 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2216 pos += length;
2217 break;
2218 case HDD_WPS_ELEM_RF_BANDS:
2219 pos += 4;
2220 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
2221 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
2222 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2223 pos += 1;
2224 break;
2225
2226 default:
2227 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)\n", (*pos<<8 | *(pos+1)));
2228 vos_mem_free(pSap_WPSIe);
2229 return -EINVAL;
2230 }
2231 }
2232 }
2233 else {
2234 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002235 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 }
2237 break;
2238
2239 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002240 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 vos_mem_free(pSap_WPSIe);
2242 return 0;
2243 }
2244 }
2245 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2246 {
2247 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2248 wps_genie = wps_genie + 1;
2249 switch ( wps_genie[0] )
2250 {
2251 case DOT11F_EID_WPA:
2252 if (wps_genie[1] < 2 + 4)
2253 {
2254 vos_mem_free(pSap_WPSIe);
2255 return -EINVAL;
2256 }
2257 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2258 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002259 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 pos = &wps_genie[6];
2261 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2262 {
2263 switch((u_int16_t)(*pos<<8) | *(pos+1))
2264 {
2265 case HDD_WPS_ELEM_VERSION:
2266 pos += 4;
2267 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
2268 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
2269 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2270 pos += 1;
2271 break;
2272
2273 case HDD_WPS_ELEM_WPS_STATE:
2274 pos +=4;
2275 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
2276 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
2277 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2278 pos += 1;
2279 break;
2280 case HDD_WPS_ELEM_APSETUPLOCK:
2281 pos += 4;
2282 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
2283 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
2284 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2285 pos += 1;
2286 break;
2287 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2288 pos += 4;
2289 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
2290 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
2291 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2292 pos += 1;
2293 break;
2294 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2295 pos += 4;
2296 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2297 hddLog(LOG1, "Password ID: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
2298 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2299 pos += 2;
2300 break;
2301 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2302 pos += 4;
2303 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2304 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2305 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2306 pos += 2;
2307 break;
2308 case HDD_WPS_ELEM_RSP_TYPE:
2309 pos += 4;
2310 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
2311 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
2312 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2313 pos += 1;
2314 break;
2315 case HDD_WPS_ELEM_UUID_E:
2316 pos += 2;
2317 length = *pos<<8 | *(pos+1);
2318 pos += 2;
2319 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2320 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2321 pos += length;
2322 break;
2323
2324 case HDD_WPS_ELEM_MANUFACTURER:
2325 pos += 2;
2326 length = *pos<<8 | *(pos+1);
2327 pos += 2;
2328 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2329 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2330 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2331 pos += length;
2332 break;
2333
2334 case HDD_WPS_ELEM_MODEL_NAME:
2335 pos += 2;
2336 length = *pos<<8 | *(pos+1);
2337 pos += 2;
2338 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2339 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2340 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2341 pos += length;
2342 break;
2343 case HDD_WPS_ELEM_MODEL_NUM:
2344 pos += 2;
2345 length = *pos<<8 | *(pos+1);
2346 pos += 2;
2347 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2348 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2349 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2350 pos += length;
2351 break;
2352 case HDD_WPS_ELEM_SERIAL_NUM:
2353 pos += 2;
2354 length = *pos<<8 | *(pos+1);
2355 pos += 2;
2356 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2357 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2358 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2359 pos += length;
2360 break;
2361 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2362 pos += 4;
2363 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
2364 hddLog(LOG1, "primary dev category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
2365 pos += 2;
2366
2367 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
2368 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x\n", pos[0], pos[1], pos[2], pos[3]);
2369 pos += 4;
2370 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
2371 hddLog(LOG1, "primary dev sub category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
2372 pos += 2;
2373 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2374 break;
2375 case HDD_WPS_ELEM_DEVICE_NAME:
2376 pos += 2;
2377 length = *pos<<8 | *(pos+1);
2378 pos += 2;
2379 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2380 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2381 pos += length;
2382 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2383 break;
2384 case HDD_WPS_ELEM_CONFIG_METHODS:
2385 pos += 4;
2386 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
2387 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2388 pos += 2;
2389 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2390 break;
2391
2392 case HDD_WPS_ELEM_RF_BANDS:
2393 pos += 4;
2394 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
2395 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
2396 pos += 1;
2397 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2398 break;
2399 } // switch
2400 }
2401 }
2402 else
2403 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002404 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002405 }
2406
2407 } // switch
2408 }
2409 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2410 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2411 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2412 {
2413 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2414 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2415 WLANSAP_Update_WpsIe ( pVosContext );
2416 }
2417
2418 vos_mem_free(pSap_WPSIe);
2419 EXIT();
2420 return halStatus;
2421}
2422
2423static int iw_softap_stopbss(struct net_device *dev,
2424 struct iw_request_info *info,
2425 union iwreq_data *wrqu,
2426 char *extra)
2427{
2428 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2429 VOS_STATUS status = VOS_STATUS_SUCCESS;
2430 ENTER();
2431 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2432 {
2433 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2434 {
2435 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2436
2437 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2438
2439 if (!VOS_IS_STATUS_SUCCESS(status))
2440 {
2441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2442 ("ERROR: HDD vos wait for single_event failed!!\n"));
2443 VOS_ASSERT(0);
2444 }
2445 }
2446 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2447 }
2448 EXIT();
2449 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2450}
2451
2452static int iw_softap_version(struct net_device *dev,
2453 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002454 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07002455 char *extra)
2456{
Jeff Johnson295189b2012-06-20 16:38:30 -07002457 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002458
Jeff Johnson295189b2012-06-20 16:38:30 -07002459 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002460 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002462 return 0;
2463}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002464
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002465VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002466{
2467 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002468 int len = 0;
2469 const char sta_info_header[] = "staId staAddress\n";
2470
2471 len = snprintf(pBuf, buf_len, sta_info_header);
2472 pBuf += len;
2473 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002474
2475 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2476 {
2477 if(pAdapter->aStaInfo[i].isUsed)
2478 {
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002479 len = snprintf(pBuf, buf_len, "%*d .%02x:%02x:%02x:%02x:%02x:%02x\n",
2480 strlen("staId"),
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002481 pAdapter->aStaInfo[i].ucSTAId,
2482 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
2483 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
2484 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
2485 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
2486 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
2487 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07002488 pBuf += len;
2489 buf_len -= len;
2490 }
2491 if(WE_GET_STA_INFO_SIZE > buf_len)
2492 {
2493 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002494 }
2495 }
2496 return VOS_STATUS_SUCCESS;
2497}
2498
2499static int iw_softap_get_sta_info(struct net_device *dev,
2500 struct iw_request_info *info,
2501 union iwreq_data *wrqu,
2502 char *extra)
2503{
2504 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2505 VOS_STATUS status;
2506 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07002507 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002508 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
2509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n",__func__);
2510 return -EINVAL;
2511 }
2512 wrqu->data.length = strlen(extra);
2513 EXIT();
2514 return 0;
2515}
2516
Jeff Johnson295189b2012-06-20 16:38:30 -07002517static int iw_set_ap_genie(struct net_device *dev,
2518 struct iw_request_info *info,
2519 union iwreq_data *wrqu,
2520 char *extra)
2521{
2522
2523 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2524 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2525 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2526 u_int8_t *genie = wrqu->data.pointer;
2527
2528 ENTER();
2529
2530 if(!wrqu->data.length)
2531 {
2532 EXIT();
2533 return 0;
2534 }
2535
2536 switch (genie[0])
2537 {
2538 case DOT11F_EID_WPA:
2539 case DOT11F_EID_RSN:
2540 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
2541 {
2542 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
2543 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
2544 }
2545 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
2546 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, wrqu->data.pointer, wrqu->data.length);
2547 break;
2548
2549 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002550 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002551 halStatus = 0;
2552 }
2553
2554 EXIT();
2555 return halStatus;
2556}
2557
2558static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
2559{
2560 eHalStatus hstatus;
2561 long lrc;
2562 struct statsContext context;
2563
2564 if (NULL == pAdapter)
2565 {
2566 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Padapter is NULL", __func__);
2567 return VOS_STATUS_E_FAULT;
2568 }
2569
2570 init_completion(&context.completion);
2571 context.pAdapter = pAdapter;
2572 context.magic = STATS_CONTEXT_MAGIC;
2573 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
2574 eCSR_HDD,
2575 SME_GLOBAL_CLASSA_STATS,
2576 hdd_GetClassA_statisticsCB,
2577 0, // not periodic
2578 FALSE, //non-cached results
2579 staid,
2580 &context);
2581 if (eHAL_STATUS_SUCCESS != hstatus)
2582 {
2583 hddLog(VOS_TRACE_LEVEL_ERROR,
2584 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002585 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002586 }
2587 else
2588 {
2589 lrc = wait_for_completion_interruptible_timeout(&context.completion,
2590 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2591 context.magic = 0;
2592 if (lrc <= 0)
2593 {
2594 hddLog(VOS_TRACE_LEVEL_ERROR,
2595 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002596 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 msleep(50);
2598 }
2599 }
2600 return VOS_STATUS_SUCCESS;
2601}
2602
2603int iw_get_softap_linkspeed(struct net_device *dev,
2604 struct iw_request_info *info,
2605 union iwreq_data *wrqu,
2606 char *extra)
2607
2608{
2609 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302610 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002611 char *pLinkSpeed = (char*)extra;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302612 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07002613 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302614 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002615 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
2616 VOS_STATUS status;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302617 int rc, valid;
2618
2619 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2620
2621 valid = wlan_hdd_validate_context(pHddCtx);
2622
2623 if (0 != valid)
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
2626 return valid;
2627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002628
2629 if ( hdd_string_to_hex ((char *)wrqu->data.pointer, wrqu->data.length, macAddress ) )
2630 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302631 hddLog(VOS_TRACE_LEVEL_FATAL, FL("ERROR: Command not found"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002632 return -EINVAL;
2633 }
2634
2635 status = hdd_softap_GetStaId(pHostapdAdapter, (v_MACADDR_t *)macAddress, (void *)(&staId));
2636
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302637 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002638 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002640 link_speed = 0;
2641 }
2642 else
2643 {
2644 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302645
Jeff Johnson295189b2012-06-20 16:38:30 -07002646 if (!VOS_IS_STATUS_SUCCESS(status ))
2647 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002649 return -EINVAL;
2650 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302651
2652 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
2653 staId, &link_speed);
2654
2655 link_speed = link_speed / 10;
2656
2657 if (0 == link_speed)
2658 {
2659 /* The linkspeed returned by HAL is in units of 500kbps.
2660 * converting it to mbps.
2661 * This is required to support legacy firmware which does
2662 * not return link capacity.
2663 */
2664 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
2665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002666 }
2667
2668 wrqu->data.length = len;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302669 rc = snprintf(pLinkSpeed, len, "%lu", link_speed);
2670
Jeff Johnson295189b2012-06-20 16:38:30 -07002671 if ((rc < 0) || (rc >= len))
2672 {
2673 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302674 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002675 return -EIO;
2676 }
2677
2678 return 0;
2679}
2680
2681static const iw_handler hostapd_handler[] =
2682{
2683 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2684 (iw_handler) NULL, /* SIOCGIWNAME */
2685 (iw_handler) NULL, /* SIOCSIWNWID */
2686 (iw_handler) NULL, /* SIOCGIWNWID */
2687 (iw_handler) NULL, /* SIOCSIWFREQ */
2688 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
2689 (iw_handler) NULL, /* SIOCSIWMODE */
2690 (iw_handler) NULL, /* SIOCGIWMODE */
2691 (iw_handler) NULL, /* SIOCSIWSENS */
2692 (iw_handler) NULL, /* SIOCGIWSENS */
2693 (iw_handler) NULL, /* SIOCSIWRANGE */
2694 (iw_handler) NULL, /* SIOCGIWRANGE */
2695 (iw_handler) NULL, /* SIOCSIWPRIV */
2696 (iw_handler) NULL, /* SIOCGIWPRIV */
2697 (iw_handler) NULL, /* SIOCSIWSTATS */
2698 (iw_handler) NULL, /* SIOCGIWSTATS */
2699 (iw_handler) NULL, /* SIOCSIWSPY */
2700 (iw_handler) NULL, /* SIOCGIWSPY */
2701 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2702 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2703 (iw_handler) NULL, /* SIOCSIWAP */
2704 (iw_handler) NULL, /* SIOCGIWAP */
2705 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
2706 (iw_handler) NULL, /* SIOCGIWAPLIST */
2707 (iw_handler) NULL, /* SIOCSIWSCAN */
2708 (iw_handler) NULL, /* SIOCGIWSCAN */
2709 (iw_handler) NULL, /* SIOCSIWESSID */
2710 (iw_handler) NULL, /* SIOCGIWESSID */
2711 (iw_handler) NULL, /* SIOCSIWNICKN */
2712 (iw_handler) NULL, /* SIOCGIWNICKN */
2713 (iw_handler) NULL, /* -- hole -- */
2714 (iw_handler) NULL, /* -- hole -- */
2715 (iw_handler) NULL, /* SIOCSIWRATE */
2716 (iw_handler) NULL, /* SIOCGIWRATE */
2717 (iw_handler) NULL, /* SIOCSIWRTS */
2718 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
2719 (iw_handler) NULL, /* SIOCSIWFRAG */
2720 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
2721 (iw_handler) NULL, /* SIOCSIWTXPOW */
2722 (iw_handler) NULL, /* SIOCGIWTXPOW */
2723 (iw_handler) NULL, /* SIOCSIWRETRY */
2724 (iw_handler) NULL, /* SIOCGIWRETRY */
2725 (iw_handler) NULL, /* SIOCSIWENCODE */
2726 (iw_handler) NULL, /* SIOCGIWENCODE */
2727 (iw_handler) NULL, /* SIOCSIWPOWER */
2728 (iw_handler) NULL, /* SIOCGIWPOWER */
2729 (iw_handler) NULL, /* -- hole -- */
2730 (iw_handler) NULL, /* -- hole -- */
2731 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
2732 (iw_handler) NULL, /* SIOCGIWGENIE */
2733 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
2734 (iw_handler) NULL, /* SIOCGIWAUTH */
2735 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
2736 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
2737 (iw_handler) NULL, /* SIOCSIWPMKSA */
2738};
2739
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002740#define IW_PRIV_TYPE_OPTIE (IW_PRIV_TYPE_BYTE | QCSAP_MAX_OPT_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002741#define IW_PRIV_TYPE_MLME \
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002742 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
Jeff Johnson295189b2012-06-20 16:38:30 -07002743
2744static const struct iw_priv_args hostapd_private_args[] = {
2745 { QCSAP_IOCTL_SETPARAM,
2746 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
2747 { QCSAP_IOCTL_SETPARAM,
2748 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2749 { QCSAP_PARAM_MAX_ASSOC,
2750 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
2751 { QCSAP_PARAM_HIDE_SSID,
2752 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
2753 { QCSAP_IOCTL_GETPARAM,
2754 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2755 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
2756 { QCSAP_IOCTL_GETPARAM, 0,
2757 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2758 { QCSAP_PARAM_MAX_ASSOC, 0,
2759 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07002760 { QCSAP_PARAM_GET_WLAN_DBG, 0,
2761 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
2762 { QCSAP_PARAM_AUTO_CHANNEL, 0,
2763 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002764 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
2765 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
2766 { QCSAP_PARAM_CLR_ACL, 0,
2767 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
2768 { QCSAP_PARAM_ACL_MODE,
2769 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
2770 { QCSAP_IOCTL_COMMIT,
2771 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
2772 { QCSAP_IOCTL_SETMLME,
2773 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
2774 { QCSAP_IOCTL_GET_STAWPAIE,
2775 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
2776 { QCSAP_IOCTL_SETWPAIE,
2777 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
2778 { QCSAP_IOCTL_STOPBSS,
2779 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
2780 { QCSAP_IOCTL_VERSION, 0,
2781 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002782 { QCSAP_IOCTL_GET_STA_INFO, 0,
2783 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002784 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
2785 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED | 1, 0, "getProbeReqIEs" },
2786 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07002787 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002788 { QCSAP_IOCTL_ASSOC_STA_MACADDR, 0,
2789 IW_PRIV_TYPE_BYTE | /*((WLAN_MAX_STA_COUNT*6)+100)*/1 , "get_assoc_stamac" },
2790 { QCSAP_IOCTL_DISASSOC_STA,
2791 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
2792 { QCSAP_IOCTL_AP_STATS,
2793 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
2794 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
2795 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05302796 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002797
2798 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
2799 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
2800 /* handlers for sub-ioctl */
2801 { WE_SET_WLAN_DBG,
2802 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
2803 0,
2804 "setwlandbg" },
2805
2806 /* handlers for main ioctl */
2807 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
2808 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2809 0,
2810 "" },
2811
2812 /* handlers for sub-ioctl */
2813 { WE_LOG_DUMP_CMD,
2814 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2815 0,
2816 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002817 { WE_P2P_NOA_CMD,
2818 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2819 0,
2820 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08002821 /* handlers for sub ioctl */
2822 {
2823 WE_MCC_CONFIG_CREDENTIAL,
2824 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2825 0,
2826 "setMccCrdnl" },
2827
2828 /* handlers for sub ioctl */
2829 {
2830 WE_MCC_CONFIG_PARAMS,
2831 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2832 0,
2833 "setMccConfig" },
2834
Jeff Johnson295189b2012-06-20 16:38:30 -07002835 /* handlers for main ioctl */
2836 { QCSAP_IOCTL_MODIFY_ACL,
2837 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
2838 0,
2839 "modify_acl" },
2840
2841 /* handlers for main ioctl */
2842 { QCSAP_IOCTL_GET_CHANNEL_LIST,
2843 0,
2844 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
2845 "getChannelList" },
2846
Jeff Johnsone7245742012-09-05 17:12:55 -07002847 /* handlers for main ioctl */
2848 { QCSAP_IOCTL_SET_TX_POWER,
2849 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
2850 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05302851 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07002852
2853 /* handlers for main ioctl */
2854 { QCSAP_IOCTL_SET_MAX_TX_POWER,
2855 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
2856 0,
2857 "setTxMaxPower" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002858};
Jeff Johnsone7245742012-09-05 17:12:55 -07002859
Jeff Johnson295189b2012-06-20 16:38:30 -07002860static const iw_handler hostapd_private[] = {
2861 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
2862 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
2863 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
2864 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
2865 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
2866 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
2867 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
2868 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
2869 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
2870 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
2871 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
2872 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
2873 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
2874 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
2875 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
2876 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
2877 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
2878 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002879 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07002880 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
2881 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07002882 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Jeff Johnson295189b2012-06-20 16:38:30 -07002883};
2884const struct iw_handler_def hostapd_handler_def = {
2885 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
2886 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
2887 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
2888 .standard = (iw_handler *)hostapd_handler,
2889 .private = (iw_handler *)hostapd_private,
2890 .private_args = hostapd_private_args,
2891 .get_wireless_stats = NULL,
2892};
2893#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2894struct net_device_ops net_ops_struct = {
2895 .ndo_open = hdd_hostapd_open,
2896 .ndo_stop = hdd_hostapd_stop,
2897 .ndo_uninit = hdd_hostapd_uninit,
2898 .ndo_start_xmit = hdd_softap_hard_start_xmit,
2899 .ndo_tx_timeout = hdd_softap_tx_timeout,
2900 .ndo_get_stats = hdd_softap_stats,
2901 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
2902 .ndo_do_ioctl = hdd_hostapd_ioctl,
2903 .ndo_change_mtu = hdd_hostapd_change_mtu,
2904 .ndo_select_queue = hdd_hostapd_select_queue,
2905 };
2906#endif
2907
2908int hdd_set_hostapd(hdd_adapter_t *pAdapter)
2909{
2910 return VOS_STATUS_SUCCESS;
2911}
2912
2913void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
2914{
2915#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2916 pWlanHostapdDev->netdev_ops = &net_ops_struct;
2917#else
2918 pWlanHostapdDev->open = hdd_hostapd_open;
2919 pWlanHostapdDev->stop = hdd_hostapd_stop;
2920 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
2921 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
2922 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
2923 pWlanHostapdDev->get_stats = hdd_softap_stats;
2924 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
2925 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
2926#endif
2927}
2928
2929VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
2930{
2931 hdd_hostapd_state_t * phostapdBuf;
2932 struct net_device *dev = pAdapter->dev;
2933 VOS_STATUS status;
2934 ENTER();
2935 // Allocate the Wireless Extensions state structure
2936 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
2937
2938 // Zero the memory. This zeros the profile structure.
2939 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
2940
2941 // Set up the pointer to the Wireless Extensions state structure
2942 // NOP
2943 status = hdd_set_hostapd(pAdapter);
2944 if(!VOS_IS_STATUS_SUCCESS(status)) {
2945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!\n"));
2946 return status;
2947 }
2948
2949 status = vos_event_init(&phostapdBuf->vosEvent);
2950 if (!VOS_IS_STATUS_SUCCESS(status))
2951 {
2952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!\n"));
2953 return status;
2954 }
2955
2956 init_completion(&pAdapter->session_close_comp_var);
2957 init_completion(&pAdapter->session_open_comp_var);
2958
2959 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
2960
2961 // Register as a wireless device
2962 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
2963
2964 //Initialize the data path module
2965 status = hdd_softap_init_tx_rx(pAdapter);
2966 if ( !VOS_IS_STATUS_SUCCESS( status ))
2967 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002968 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 }
2970
Jeff Johnson295189b2012-06-20 16:38:30 -07002971 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002972 EXIT();
2973 return status;
2974}
2975
2976hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
2977{
2978 struct net_device *pWlanHostapdDev = NULL;
2979 hdd_adapter_t *pHostapdAdapter = NULL;
2980 v_CONTEXT_t pVosContext= NULL;
2981
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07002983
2984 if (pWlanHostapdDev != NULL)
2985 {
2986 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
2987
2988 //Init the net_device structure
2989 ether_setup(pWlanHostapdDev);
2990
2991 //Initialize the adapter context to zeros.
2992 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
2993 pHostapdAdapter->dev = pWlanHostapdDev;
2994 pHostapdAdapter->pHddCtx = pHddCtx;
2995 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
2996
2997 //Get the Global VOSS context.
2998 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2999 //Save the adapter context in global context for future.
3000 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3001
3002 //Init the net_device structure
3003 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3004
3005 hdd_set_ap_ops( pHostapdAdapter->dev );
3006
3007 pWlanHostapdDev->tx_queue_len = NET_DEV_TX_QUEUE_LEN;
3008 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3009 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3010
3011 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3012 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3013
3014 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003015 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3016 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3017 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3018 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003019 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3020 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
3021#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3022 init_completion(&pHostapdAdapter->offchannel_tx_event);
3023#endif
3024
Jeff Johnson295189b2012-06-20 16:38:30 -07003025 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3026 }
3027 return pHostapdAdapter;
3028}
3029
3030VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3031{
3032 struct net_device *dev = pAdapter->dev;
3033 VOS_STATUS status = VOS_STATUS_SUCCESS;
3034
3035 ENTER();
3036
3037 if( rtnl_lock_held )
3038 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003039 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003040 if( dev_alloc_name(dev, dev->name) < 0 )
3041 {
3042 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3043 return VOS_STATUS_E_FAILURE;
3044 }
3045 }
3046 if (register_netdevice(dev))
3047 {
3048 hddLog(VOS_TRACE_LEVEL_FATAL,
3049 "%s:Failed:register_netdevice", __func__);
3050 return VOS_STATUS_E_FAILURE;
3051 }
3052 }
3053 else
3054 {
3055 if (register_netdev(dev))
3056 {
3057 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3058 return VOS_STATUS_E_FAILURE;
3059 }
3060 }
3061 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3062
3063 EXIT();
3064 return status;
3065}
3066
3067VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3068{
3069 ENTER();
3070
3071 hdd_softap_deinit_tx_rx(pAdapter);
3072
3073 /* if we are being called during driver unload, then the dev has already
3074 been invalidated. if we are being called at other times, then we can
3075 detatch the wireless device handlers */
3076 if (pAdapter->dev)
3077 {
3078 pAdapter->dev->wireless_handlers = NULL;
3079 }
3080 EXIT();
3081 return 0;
3082}