blob: c405e5140885f52b9985560854baeb8516bdbaae [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>
93#if defined CONFIG_CFG80211
94#include "wlan_hdd_p2p.h"
95#endif
96
97#define IS_UP(_dev) \
98 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
99#define IS_UP_AUTO(_ic) \
100 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
101#define WE_WLAN_VERSION 1
102#define STATS_CONTEXT_MAGIC 0x53544154
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800103#define WE_GET_STA_INFO_SIZE 50
104#define WE_SAP_MAX_STA_INFO (WE_GET_STA_INFO_SIZE * WLAN_MAX_STA_COUNT)
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
106struct statsContext
107{
108 struct completion completion;
109 hdd_adapter_t *pAdapter;
110 unsigned int magic;
111};
112#define SAP_24GHZ_CH_COUNT (14)
113/*---------------------------------------------------------------------------
114 * Function definitions
115 *-------------------------------------------------------------------------*/
116/**---------------------------------------------------------------------------
117
118 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
119
120 This is called in response to ifconfig up
121
122 \param - dev Pointer to net_device structure
123
124 \return - 0 for success non-zero for failure
125
126 --------------------------------------------------------------------------*/
127int hdd_hostapd_open (struct net_device *dev)
128{
129 ENTER();
130
131 //Turn ON carrier state
132 netif_carrier_on(dev);
133 //Enable all Tx queues
134 netif_tx_start_all_queues(dev);
135
136 EXIT();
137 return 0;
138}
139/**---------------------------------------------------------------------------
140
141 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
142
143 This is called in response to ifconfig down
144
145 \param - dev Pointer to net_device structure
146
147 \return - 0 for success non-zero for failure
148
149 --------------------------------------------------------------------------*/
150int hdd_hostapd_stop (struct net_device *dev)
151{
152 ENTER();
153
154 //Stop all tx queues
155 netif_tx_disable(dev);
156
157 //Turn OFF carrier state
158 netif_carrier_off(dev);
159
160 EXIT();
161 return 0;
162}
163/**---------------------------------------------------------------------------
164
165 \brief hdd_hostapd_uninit() - HDD uninit function
166
167 This is called during the netdev unregister to uninitialize all data
168associated with the device
169
170 \param - dev Pointer to net_device structure
171
172 \return - void
173
174 --------------------------------------------------------------------------*/
175static void hdd_hostapd_uninit (struct net_device *dev)
176{
177 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
178
179 ENTER();
180
181 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
182 {
183 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
184
185 /* after uninit our adapter structure will no longer be valid */
186 pHostapdAdapter->dev = NULL;
187 }
188
189 EXIT();
190}
191
192
193/**============================================================================
194 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
195 transmitting packets. There are 2 versions of this function. One that uses
196 locked queue and other that uses lockless queues. Both have been retained to
197 do some performance testing
198 @param skb : [in] pointer to OS packet (sk_buff)
199 @param dev : [in] pointer to Libra network device
200
201 @return : NET_XMIT_DROP if packets are dropped
202 : NET_XMIT_SUCCESS if packet is enqueued succesfully
203 ===========================================================================*/
204int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
205{
206 return 0;
207}
208int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
209{
210 return 0;
211}
212
213int hdd_hostapd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
214{
215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
216 hdd_priv_data_t priv_data;
217 tANI_U8 *command = NULL;
218 int ret = 0;
219
220 if (NULL == pAdapter)
221 {
222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700223 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700224 ret = -ENODEV;
225 goto exit;
226 }
227
Jeff Johnsone7245742012-09-05 17:12:55 -0700228 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -0700229 {
230 ret = -EINVAL;
231 goto exit;
232 }
233
234 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
235 {
236 ret = -EFAULT;
237 goto exit;
238 }
239
240 command = kmalloc(priv_data.total_len, GFP_KERNEL);
241 if (!command)
242 {
243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700244 "%s: failed to allocate memory\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 ret = -ENOMEM;
246 goto exit;
247 }
248
249 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
250 {
251 ret = -EFAULT;
252 goto exit;
253 }
254
255 if ((SIOCDEVPRIVATE + 1) == cmd)
256 {
257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
258 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
259
260#ifdef WLAN_FEATURE_P2P
261 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 }
269#endif
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700270
271 /*
272 command should be a string having format
273 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
274 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700275 if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700276 {
277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700278 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700279
280 ret = sapSetPreferredChannel(dev,command);
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700281 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 }
283exit:
284 if (command)
285 {
286 kfree(command);
287 }
288 return ret;
289}
290
291/**---------------------------------------------------------------------------
292
293 \brief hdd_hostapd_set_mac_address() -
294 This function sets the user specified mac address using
295 the command ifconfig wlanX hw ether <mac adress>.
296
297 \param - dev - Pointer to the net device.
298 - addr - Pointer to the sockaddr.
299 \return - 0 for success, non zero for failure
300
301 --------------------------------------------------------------------------*/
302
303static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
304{
305 struct sockaddr *psta_mac_addr = addr;
306 ENTER();
307 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
308 EXIT();
309 return 0;
310}
311void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
312{
313 struct net_device *dev = (struct net_device *)usrDataForCallback;
314 v_BYTE_t we_custom_event[64];
315 union iwreq_data wrqu;
316#ifdef DISABLE_CONCURRENCY_AUTOSAVE
317 VOS_STATUS vos_status;
318 hdd_adapter_t *pHostapdAdapter;
319 hdd_ap_ctx_t *pHddApCtx;
320#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
321
322 /* event_name space-delimiter driver_module_name */
323 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
324 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
325 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
326
327 ENTER();
328
329#ifdef DISABLE_CONCURRENCY_AUTOSAVE
330 if (vos_concurrent_sessions_running())
331 {
332 /*
333 This timer routine is going to be called only when AP
334 persona is up.
335 If there are concurrent sessions running we do not want
336 to shut down the Bss.Instead we run the timer again so
337 that if Autosave is enabled next time and other session
338 was down only then we bring down AP
339 */
340 pHostapdAdapter = netdev_priv(dev);
341 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
342 vos_status = vos_timer_start(
343 &pHddApCtx->hdd_ap_inactivity_timer,
344 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
345 * 1000);
346 if (!VOS_IS_STATUS_SUCCESS(vos_status))
347 {
348 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
349 }
350 EXIT();
351 return;
352 }
353#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
354 memset(&we_custom_event, '\0', sizeof(we_custom_event));
355 memcpy(&we_custom_event, autoShutEvent, event_len);
356
357 memset(&wrqu, 0, sizeof(wrqu));
358 wrqu.data.length = event_len;
359
360 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
361 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
362
363 EXIT();
364}
365
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800366VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
367{
368 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
369 ptSapContext pSapCtx = NULL;
370 eHalStatus halStatus = eHAL_STATUS_FAILURE;
371 v_PVOID_t hHal = NULL;
372
373 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
374 "%s: UPDATE Beacon Params", __func__);
375
376 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
377 pSapCtx = VOS_GET_SAP_CB(pVosContext);
378 if ( NULL == pSapCtx )
379 {
380 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
381 "%s: Invalid SAP pointer from pvosGCtx", __func__);
382 return VOS_STATUS_E_FAULT;
383 }
384
385 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
386 if ( NULL == hHal ){
387 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
388 "%s: Invalid HAL pointer from pvosGCtx", __func__);
389 return VOS_STATUS_E_FAULT;
390 }
391 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
392 if(halStatus == eHAL_STATUS_FAILURE ){
393 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
394 "%s: Failed to update Beacon Params", __func__);
395 return VOS_STATUS_E_FAILURE;
396 }
397 }
398 return VOS_STATUS_SUCCESS;
399}
400
401void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
402{
403 v_U8_t staId = 0;
404 struct net_device *dev;
405 dev = (struct net_device *)usrDataForCallback;
406
407 hddLog(LOGE, FL("Clearing all the STA entry....\n"));
408 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
409 {
410 if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
411 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
412 {
413 //Disconnect all the stations
414 hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
415 }
416 }
417}
418
419static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
420{
421 struct net_device *dev;
422 VOS_STATUS status = VOS_STATUS_SUCCESS;
423 dev = (struct net_device *)usrDataForCallback;
424 ENTER();
425 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
426 {
427 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
428 {
429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
430 }
431 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
432 }
433 EXIT();
434 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
435}
Jeff Johnson295189b2012-06-20 16:38:30 -0700436
437VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
438{
439 hdd_adapter_t *pHostapdAdapter;
440 hdd_ap_ctx_t *pHddApCtx;
441 hdd_hostapd_state_t *pHostapdState;
442 struct net_device *dev;
443 eSapHddEvent sapEvent;
444 union iwreq_data wrqu;
445 v_BYTE_t *we_custom_event_generic = NULL;
446 int we_event = 0;
447 int i = 0;
448 v_U8_t staId;
449 VOS_STATUS vos_status;
450 v_BOOL_t bWPSState;
451 v_BOOL_t bApActive = FALSE;
452 v_BOOL_t bAuthRequired = TRUE;
453 tpSap_AssocMacAddr pAssocStasArray = NULL;
454 char unknownSTAEvent[IW_CUSTOM_MAX+1];
455 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
456 v_BYTE_t we_custom_start_event[64];
457 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800458 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800459 hdd_scaninfo_t *pScanInfo = NULL;
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
511#ifdef CONFIG_CFG80211
512 //Check if there is any group key pending to set.
513 if( pHddApCtx->groupKey.keyLength )
514 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700515 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700516 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
517 &pHddApCtx->groupKey ) )
518 {
519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
520 "%s: WLANSAP_SetKeySta failed", __func__);
521 }
522 pHddApCtx->groupKey.keyLength = 0;
523 }
524 else if ( pHddApCtx->wepKey[0].keyLength )
525 {
526 int i=0;
527 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
528 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700529 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700530 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
531 &pHddApCtx->wepKey[i] ) )
532 {
533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
534 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
535 }
536 pHddApCtx->wepKey[i].keyLength = 0;
537 }
538 }
539#endif
540 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
541 startBssEvent = "SOFTAP.enabled";
542 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
543 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
544 memset(&wrqu, 0, sizeof(wrqu));
545 wrqu.data.length = strlen(startBssEvent);
546 we_event = IWEVCUSTOM;
547 we_custom_event_generic = we_custom_start_event;
548
549 break; //Event will be sent after Switch-Case stmt
550
551 case eSAP_STOP_BSS_EVENT:
552 hddLog(LOG1, FL("BSS stop status = %s\n"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
553 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
554
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700555 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700556 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700557
Jeff Johnson295189b2012-06-20 16:38:30 -0700558 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
559 vos_event_set(&pHostapdState->vosEvent);
560 goto stopbss;
561 case eSAP_STA_SET_KEY_EVENT:
562 //TODO: forward the message to hostapd once implementtation is done for now just print
563 hddLog(LOG1, FL("SET Key: configured status = %s\n"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
564 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
565 return VOS_STATUS_SUCCESS;
566 case eSAP_STA_DEL_KEY_EVENT:
567 //TODO: forward the message to hostapd once implementtation is done for now just print
568 hddLog(LOG1, FL("Event received %s\n"),"eSAP_STA_DEL_KEY_EVENT");
569 return VOS_STATUS_SUCCESS;
570 case eSAP_STA_MIC_FAILURE_EVENT:
571 {
572 struct iw_michaelmicfailure msg;
573 memset(&msg, '\0', sizeof(msg));
574 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800575 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700576 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700577 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700578 msg.flags = IW_MICFAILURE_GROUP;
579 else
580 msg.flags = IW_MICFAILURE_PAIRWISE;
581 memset(&wrqu, 0, sizeof(wrqu));
582 wrqu.data.length = sizeof(msg);
583 we_event = IWEVMICHAELMICFAILURE;
584 we_custom_event_generic = (v_BYTE_t *)&msg;
585 }
586#ifdef CONFIG_CFG80211
587 /* inform mic failure to nl80211 */
588 cfg80211_michael_mic_failure(dev,
589 pSapEvent->sapevt.
590 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700591 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700592 NL80211_KEYTYPE_GROUP :
593 NL80211_KEYTYPE_PAIRWISE),
594 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
595 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
596 GFP_KERNEL);
597#endif
598 break;
599
600 case eSAP_STA_ASSOC_EVENT:
601 case eSAP_STA_REASSOC_EVENT:
602 wrqu.addr.sa_family = ARPHRD_ETHER;
603 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800604 sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700605 hddLog(LOG1, " associated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
606 we_event = IWEVREGISTERED;
607
608 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
609
610 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
611 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
612 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
613 {
614 bAuthRequired = FALSE;
615 }
616
617 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
618 {
619 hdd_softap_RegisterSTA( pHostapdAdapter,
620 TRUE,
621 pHddApCtx->uPrivacy,
622 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
623 0,
624 0,
625 (v_MACADDR_t *)wrqu.addr.sa_data,
626 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
627 }
628 else
629 {
630 hdd_softap_RegisterSTA( pHostapdAdapter,
631 FALSE,
632 pHddApCtx->uPrivacy,
633 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
634 0,
635 0,
636 (v_MACADDR_t *)wrqu.addr.sa_data,
637 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
638 }
639
640 // Stop AP inactivity timer
641 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
642 {
643 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
644 if (!VOS_IS_STATUS_SUCCESS(vos_status))
645 hddLog(LOGE, FL("Failed to start AP inactivity timer\n"));
646 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800647#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800648 if (wake_lock_active(&pHddCtx->sap_wake_lock))
649 {
650 wake_unlock(&pHddCtx->sap_wake_lock);
651 }
652 wake_lock_timeout(&pHddCtx->sap_wake_lock, HDD_SAP_WAKE_LOCK_DURATION);
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800653#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700654#ifdef CONFIG_CFG80211
655#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
656 {
657 struct station_info staInfo;
658 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
659
660 memset(&staInfo, 0, sizeof(staInfo));
661 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
662 {
663 staInfo.assoc_req_ies =
664 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
665 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700667 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
668#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700669 cfg80211_new_sta(dev,
670 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
671 &staInfo, GFP_KERNEL);
672 }
673 else
674 {
675 hddLog(LOGE, FL(" Assoc Ie length is too long \n"));
676 }
677 }
678#endif
679#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800680 pScanInfo = &pHddCtx->scan_info;
681 // Lets do abort scan to ensure smooth authentication for client
682 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
683 {
684 hdd_abort_mac_scan(pHddCtx);
685 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700686
687 break;
688 case eSAP_STA_DISASSOC_EVENT:
689 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800690 sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700691 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
692 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
693 hddLog(LOG1," User initiated disassociation");
694 else
695 hddLog(LOG1," MAC initiated disassociation");
696 we_event = IWEVEXPIRED;
697 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
698 if (!VOS_IS_STATUS_SUCCESS(vos_status))
699 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700700 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 -0700701 return VOS_STATUS_E_FAILURE;
702 }
703 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
704
705 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
706 {
707 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
708 // Start AP inactivity timer if no stations associated with it
709 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
710 {
711 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
712 {
713 bApActive = TRUE;
714 break;
715 }
716 }
717 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
718
719 if (bApActive == FALSE)
720 {
721 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
722 {
723 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
724 if (!VOS_IS_STATUS_SUCCESS(vos_status))
725 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
726 }
727 else
728 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
729 }
730 }
731#ifdef CONFIG_CFG80211
732#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
733 cfg80211_del_sta(dev,
734 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
735 GFP_KERNEL);
736#endif
737#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800738 //Update the beacon Interval if it is P2P GO
739 hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700740 break;
741 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
742 {
743 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
744 union iwreq_data wreq;
745
746 down(&pHddApCtx->semWpsPBCOverlapInd);
747 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
748
749 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
750 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
751
752 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
753 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
754 memset(&wreq, 0, sizeof(wreq));
755 wreq.data.length = strlen(message); // This is length of message
756 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
757
758 return VOS_STATUS_SUCCESS;
759 }
760 case eSAP_ASSOC_STA_CALLBACK_EVENT:
761 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
762 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
763 { // List of associated stations
764 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
765 {
766 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
767 i+1,
768 pAssocStasArray->assocId,
769 pAssocStasArray->staId,
770 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
771 pAssocStasArray++;
772 }
773 }
774 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
775 return VOS_STATUS_SUCCESS;
776#ifdef WLAN_FEATURE_P2P
777 case eSAP_INDICATE_MGMT_FRAME:
778 hdd_indicateMgmtFrame( pHostapdAdapter,
779 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
780 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
781 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530782 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 return VOS_STATUS_SUCCESS;
784 case eSAP_REMAIN_CHAN_READY:
785 hdd_remainChanReadyHandler( pHostapdAdapter );
786 return VOS_STATUS_SUCCESS;
787 case eSAP_SEND_ACTION_CNF:
788 hdd_sendActionCnf( pHostapdAdapter,
789 ( eSAP_STATUS_SUCCESS ==
790 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
791 TRUE : FALSE );
792 return VOS_STATUS_SUCCESS;
793#endif
794 case eSAP_UNKNOWN_STA_JOIN:
795 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
796 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
797 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
798 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
799 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
800 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
801 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
802 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
803 wrqu.data.pointer = unknownSTAEvent;
804 wrqu.data.length = strlen(unknownSTAEvent);
805 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
806 hddLog(LOG1,"%s\n", unknownSTAEvent);
807 break;
808
809 case eSAP_MAX_ASSOC_EXCEEDED:
810 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
811 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
812 " one or more devices to enable the new device connection",
813 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
814 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
815 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
816 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
817 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
818 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
819 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
820 wrqu.data.pointer = maxAssocExceededEvent;
821 wrqu.data.length = strlen(maxAssocExceededEvent);
822 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
823 hddLog(LOG1,"%s\n", maxAssocExceededEvent);
824 break;
825 case eSAP_STA_ASSOC_IND:
826 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800827
828 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
829 hddLog(LOG1, FL(" Disconnecting all the P2P Clients....\n"));
830 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
831 return VOS_STATUS_SUCCESS;
832
833 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
834 hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
835 return VOS_STATUS_SUCCESS;
836
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 default:
838 hddLog(LOG1,"SAP message is not handled\n");
839 goto stopbss;
840 return VOS_STATUS_SUCCESS;
841 }
842 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
843 return VOS_STATUS_SUCCESS;
844
845stopbss :
846 {
847 v_BYTE_t we_custom_event[64];
848 char *stopBssEvent = "STOP-BSS.response";//17
849 int event_len = strlen(stopBssEvent);
850
851 hddLog(LOG1, FL("BSS stop status = %s"),
852 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
853 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
854
855 /* Change the BSS state now since, as we are shutting things down,
856 * we don't want interfaces to become re-enabled */
857 pHostapdState->bssState = BSS_STOP;
858
859 /* Stop the pkts from n/w stack as we are going to free all of
860 * the TX WMM queues for all STAID's */
861 hdd_hostapd_stop(dev);
862
863 /* reclaim all resources allocated to the BSS */
864 hdd_softap_stop_bss(pHostapdAdapter);
865
866 /* notify userspace that the BSS has stopped */
867 memset(&we_custom_event, '\0', sizeof(we_custom_event));
868 memcpy(&we_custom_event, stopBssEvent, event_len);
869 memset(&wrqu, 0, sizeof(wrqu));
870 wrqu.data.length = event_len;
871 we_event = IWEVCUSTOM;
872 we_custom_event_generic = we_custom_event;
873 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
874 }
875 return VOS_STATUS_SUCCESS;
876}
877int hdd_softap_unpackIE(
878 tHalHandle halHandle,
879 eCsrEncryptionType *pEncryptType,
880 eCsrEncryptionType *mcEncryptType,
881 eCsrAuthType *pAuthType,
882 u_int16_t gen_ie_len,
883 u_int8_t *gen_ie )
884{
885 tDot11fIERSN dot11RSNIE;
886 tDot11fIEWPA dot11WPAIE;
887
888 tANI_U8 *pRsnIe;
889 tANI_U16 RSNIeLen;
890
891 if (NULL == halHandle)
892 {
893 hddLog(LOGE, FL("Error haHandle returned NULL\n"));
894 return -EINVAL;
895 }
896
897 // Validity checks
898 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
899 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
900 return -EINVAL;
901 // Type check
902 if ( gen_ie[0] == DOT11F_EID_RSN)
903 {
904 // Validity checks
905 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
906 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
907 {
908 return VOS_STATUS_E_FAILURE;
909 }
910 // Skip past the EID byte and length byte
911 pRsnIe = gen_ie + 2;
912 RSNIeLen = gen_ie_len - 2;
913 // Unpack the RSN IE
914 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
915 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
916 pRsnIe,
917 RSNIeLen,
918 &dot11RSNIE);
919 // Copy out the encryption and authentication types
920 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700921 __func__, dot11RSNIE.pwise_cipher_suite_count );
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 hddLog(LOG1, FL("%s: authentication suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700923 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 /*Here we have followed the apple base code,
925 but probably I suspect we can do something different*/
926 //dot11RSNIE.akm_suite_count
927 // Just translate the FIRST one
928 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
929 //dot11RSNIE.pwise_cipher_suite_count
930 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
931 //dot11RSNIE.gp_cipher_suite_count
932 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
933 // Set the PMKSA ID Cache for this interface
934
935 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
936 } else
937 if (gen_ie[0] == DOT11F_EID_WPA)
938 {
939 // Validity checks
940 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
941 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
942 {
943 return VOS_STATUS_E_FAILURE;
944 }
945 // Skip past the EID byte and length byte - and four byte WiFi OUI
946 pRsnIe = gen_ie + 2 + 4;
947 RSNIeLen = gen_ie_len - (2 + 4);
948 // Unpack the WPA IE
949 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
950 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
951 pRsnIe,
952 RSNIeLen,
953 &dot11WPAIE);
954 // Copy out the encryption and authentication types
955 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700956 __func__, dot11WPAIE.unicast_cipher_count );
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 hddLog(LOG1, FL("%s: WPA authentication suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700958 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 //dot11WPAIE.auth_suite_count
960 // Just translate the FIRST one
961 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
962 //dot11WPAIE.unicast_cipher_count
963 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
964 //dot11WPAIE.unicast_cipher_count
965 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
966 }
967 else
968 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700969 hddLog(LOGW, FL("%s: gen_ie[0]: %d\n"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 return VOS_STATUS_E_FAILURE;
971 }
972 return VOS_STATUS_SUCCESS;
973}
974int
975static iw_softap_setparam(struct net_device *dev,
976 struct iw_request_info *info,
977 union iwreq_data *wrqu, char *extra)
978{
979 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
980 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
981 int *value = (int *)extra;
982 int sub_cmd = value[0];
983 int set_value = value[1];
984 eHalStatus status;
985 int ret = 0; /* success */
986 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
987
988 switch(sub_cmd)
989 {
990
991 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -0700992 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 {
994 ret = -EIO;
995 }
996 break;
997
998 case QCSAP_PARAM_ACL_MODE:
999 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1000 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1001 {
1002 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1003 ret = -EINVAL;
1004 }
1005 else
1006 {
1007 WLANSAP_SetMode(pVosContext, set_value);
1008 }
1009 break;
1010 case QCSAP_PARAM_MAX_ASSOC:
1011 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1012 {
1013 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1014 ret = -EINVAL;
1015 }
1016 else
1017 {
1018 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1019 {
1020 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1021 "Setting it to max allowed and continuing"),
1022 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1023 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1024 }
1025 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1026 set_value, NULL, eANI_BOOLEAN_FALSE);
1027 if ( status != eHAL_STATUS_SUCCESS )
1028 {
1029 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1030 status);
1031 ret = -EIO;
1032 }
1033 }
1034 break;
1035
1036 case QCSAP_PARAM_HIDE_SSID:
1037 {
1038 eHalStatus status = eHAL_STATUS_SUCCESS;
1039 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1040 if(eHAL_STATUS_SUCCESS != status)
1041 {
1042 hddLog(VOS_TRACE_LEVEL_ERROR,
1043 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001044 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001045 return status;
1046 }
1047 break;
1048 }
1049
1050 default:
1051 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1052 sub_cmd, set_value);
1053 ret = -EINVAL;
1054 break;
1055 }
1056
1057 return ret;
1058}
1059
1060
1061int
1062static iw_softap_getparam(struct net_device *dev,
1063 struct iw_request_info *info,
1064 union iwreq_data *wrqu, char *extra)
1065{
1066 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1067 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1068 int *value = (int *)extra;
1069 int sub_cmd = value[0];
1070 eHalStatus status;
1071 int ret = 0; /* success */
1072 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1073
1074 switch (sub_cmd)
1075 {
1076 case QCSAP_PARAM_MAX_ASSOC:
1077 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1078 if (eHAL_STATUS_SUCCESS != status)
1079 {
1080 ret = -EIO;
1081 }
1082 break;
1083
1084 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001085 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 {
1087 ret = -EIO;
1088 }
1089 *value = 0;
1090 break;
1091
1092 case QCSAP_PARAM_MODULE_DOWN_IND:
1093 {
1094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001095 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1097#ifdef WLAN_BTAMP_FEATURE
1098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001099 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1101#endif
1102 *value = 0;
1103 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001104 }
1105
1106 case QCSAP_PARAM_GET_WLAN_DBG:
1107 {
1108 vos_trace_display();
1109 *value = 0;
1110 break;
1111 }
1112
1113 case QCSAP_PARAM_AUTO_CHANNEL:
1114 {
1115 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1116 break;
1117 }
1118
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 default:
1120 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1121 ret = -EINVAL;
1122 break;
1123
1124 }
1125
1126 return ret;
1127}
1128
1129/* Usage:
1130 BLACK_LIST = 0
1131 WHITE_LIST = 1
1132 ADD MAC = 0
1133 REMOVE MAC = 1
1134
1135 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1136 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1137 while using this ioctl
1138
1139 Syntax:
1140 iwpriv softap.0 modify_acl
1141 <6 octet mac addr> <list type> <cmd type>
1142
1143 Examples:
1144 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1145 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1146 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1147 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1148*/
1149int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1150 union iwreq_data *wrqu, char *extra)
1151{
1152 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1153 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1154 v_BYTE_t *value = (v_BYTE_t*)extra;
1155 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1156 int listType, cmd, i;
1157 int ret = 0; /* success */
1158
1159 ENTER();
1160 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1161 {
1162 pPeerStaMac[i] = *(value+i);
1163 }
1164 listType = (int)(*(value+i));
1165 i++;
1166 cmd = (int)(*(value+i));
1167
1168 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 -07001169 __func__, pPeerStaMac[0], pPeerStaMac[1], pPeerStaMac[2],
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 pPeerStaMac[3], pPeerStaMac[4], pPeerStaMac[5], listType, cmd);
1171
1172 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1173 != VOS_STATUS_SUCCESS)
1174 {
1175 hddLog(LOGE, FL("Modify ACL failed\n"));
1176 ret = -EIO;
1177 }
1178 EXIT();
1179 return ret;
1180}
1181
1182int
1183static iw_softap_getchannel(struct net_device *dev,
1184 struct iw_request_info *info,
1185 union iwreq_data *wrqu, char *extra)
1186{
1187 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1188
Jeff Johnson43971f52012-07-17 12:26:56 -07001189 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001190
Jeff Johnson43971f52012-07-17 12:26:56 -07001191 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 return 0;
1193}
1194
Jeff Johnsone7245742012-09-05 17:12:55 -07001195int
1196static iw_softap_set_tx_power(struct net_device *dev,
1197 struct iw_request_info *info,
1198 union iwreq_data *wrqu, char *extra)
1199{
1200 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1201 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1202 int cmd_len = wrqu->data.length;
1203 int *value = (int *) kmalloc(cmd_len+1, GFP_KERNEL);
1204 int set_value;
1205 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1206 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1207
1208 if(value == NULL)
1209 return -ENOMEM;
1210
1211 if(copy_from_user((char *) value, (char*)(wrqu->data.pointer), cmd_len)) {
1212 hddLog(VOS_TRACE_LEVEL_FATAL, "%s -- copy_from_user --data pointer failed! bailing",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001213 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001214 kfree(value);
1215 return -EFAULT;
1216 }
1217
1218 set_value = value[0];
1219 kfree(value);
1220
1221 if( sme_SetMaxTxPower(hHal, bssid, selfMac, set_value) !=
1222 eHAL_STATUS_SUCCESS )
1223 {
1224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
1225 __func__);
1226 return -EIO;
1227 }
1228
1229 return 0;
1230}
1231
Jeff Johnson295189b2012-06-20 16:38:30 -07001232#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1233
1234int
1235static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1236 struct iw_request_info *info,
1237 union iwreq_data *wrqu, char *extra)
1238{
1239 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1240 unsigned char *pmaclist;
1241 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
1242 int cnt = 0, len;
1243
1244
1245 pmaclist = wrqu->data.pointer + sizeof(unsigned long int);
1246 len = wrqu->data.length;
1247
1248 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
1249 while((cnt < WLAN_MAX_STA_COUNT) && (len > (sizeof(v_MACADDR_t)+1))) {
1250 if (TRUE == pStaInfo[cnt].isUsed) {
1251
1252 if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
1253 memcpy((void *)pmaclist, (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t));
1254 pmaclist += sizeof(v_MACADDR_t);
1255 len -= sizeof(v_MACADDR_t);
1256 }
1257 }
1258 cnt++;
1259 }
1260 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
1261
1262 *pmaclist = '\0';
1263
1264 wrqu->data.length -= len;
1265
1266 *(unsigned long int *)(wrqu->data.pointer) = wrqu->data.length;
1267
1268 return 0;
1269}
1270
1271/* Usage:
1272 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1273 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1274 while using this ioctl
1275
1276 Syntax:
1277 iwpriv softap.0 disassoc_sta <6 octet mac address>
1278
1279 e.g.
1280 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1281 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1282*/
1283
1284int
1285static iw_softap_disassoc_sta(struct net_device *dev,
1286 struct iw_request_info *info,
1287 union iwreq_data *wrqu, char *extra)
1288{
1289 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1290 v_U8_t *peerMacAddr;
1291
1292 ENTER();
1293 /* the comparison below is needed since if iwpriv tool is used for calling this ioctl
1294 * data is passed in extra (less than 16 octets); however in android wifi framework
1295 * data is placed in wrqu->data.pointer.
1296 */
1297 if ((v_U8_t*)wrqu == (v_U8_t*)extra)
1298 peerMacAddr = (v_U8_t *)(extra);
1299 else
1300 peerMacAddr = (v_U8_t *)(wrqu->data.pointer);
1301
1302 hddLog(LOG1, "data %02x:%02x:%02x:%02x:%02x:%02x",
1303 peerMacAddr[0], peerMacAddr[1], peerMacAddr[2],
1304 peerMacAddr[3], peerMacAddr[4], peerMacAddr[5]);
1305 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1306 EXIT();
1307 return 0;
1308}
1309
1310int
1311static iw_softap_ap_stats(struct net_device *dev,
1312 struct iw_request_info *info,
1313 union iwreq_data *wrqu, char *extra)
1314{
1315 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1316 WLANTL_TRANSFER_STA_TYPE statBuffer;
1317 char *pstatbuf;
1318 int len = wrqu->data.length;
1319 pstatbuf = wrqu->data.pointer;
1320
1321 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &statBuffer, (v_BOOL_t)wrqu->data.flags);
1322
1323 len = snprintf(pstatbuf, len,
1324 "RUF=%d RMF=%d RBF=%d "
1325 "RUB=%d RMB=%d RBB=%d "
1326 "TUF=%d TMF=%d TBF=%d "
1327 "TUB=%d TMB=%d TBB=%d",
1328 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, (int)statBuffer.rxBCFcnt,
1329 (int)statBuffer.rxUCBcnt, (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1330 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, (int)statBuffer.txBCFcnt,
1331 (int)statBuffer.txUCBcnt, (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt
1332 );
1333
1334 wrqu->data.length -= len;
1335 return 0;
1336}
1337
1338int
1339static iw_softap_commit(struct net_device *dev,
1340 struct iw_request_info *info,
1341 union iwreq_data *wrqu, char *extra)
1342{
1343 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1344 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1345 hdd_hostapd_state_t *pHostapdState;
1346 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1347 tpWLAN_SAPEventCB pSapEventCallback;
1348 tsap_Config_t *pConfig;
1349 s_CommitConfig_t *pCommitConfig;
1350 struct qc_mac_acl_entry *acl_entry = NULL;
1351 v_SINT_t i = 0, num_mac = 0;
1352 v_U32_t status = 0;
1353 eCsrAuthType RSNAuthType;
1354 eCsrEncryptionType RSNEncryptType;
1355 eCsrEncryptionType mcRSNEncryptType;
1356
1357 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1358 pCommitConfig = (s_CommitConfig_t *)extra;
1359
1360 pConfig = kmalloc(sizeof(tsap_Config_t), GFP_KERNEL);
1361 if(NULL == pConfig) {
1362 hddLog(LOG1, "VOS unable to allocate memory\n");
1363 return -ENOMEM;
1364 }
1365 pConfig->beacon_int = pCommitConfig->beacon_int;
1366 pConfig->channel = pCommitConfig->channel;
1367
1368 /*Protection parameter to enable or disable*/
1369 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1370 pConfig->dtim_period = pCommitConfig->dtim_period;
1371 switch(pCommitConfig->hw_mode )
1372 {
1373 case eQC_DOT11_MODE_11A:
1374 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
1375 break;
1376 case eQC_DOT11_MODE_11B:
1377 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
1378 break;
1379 case eQC_DOT11_MODE_11G:
1380 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
1381 break;
1382
1383 case eQC_DOT11_MODE_11N:
1384 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1385 break;
1386 case eQC_DOT11_MODE_11G_ONLY:
1387 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1388 break;
1389 case eQC_DOT11_MODE_11N_ONLY:
1390 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
1391 break;
1392 default:
1393 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1394 break;
1395
1396 }
1397
1398 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
1399 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
1400 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
1401 pConfig->authType = eSAP_SHARED_KEY;
1402 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
1403 pConfig->authType = eSAP_OPEN_SYSTEM;
1404 else
1405 pConfig->authType = eSAP_AUTO_SWITCH;
1406
1407 pConfig->privacy = pCommitConfig->privacy;
1408 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
1409 pConfig->wps_state = pCommitConfig->wps_state;
1410 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1411 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
1412 if(pConfig->RSNWPAReqIELength){
1413 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
1414 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
1415 // The actual processing may eventually be more extensive than this.
1416 // Right now, just consume any PMKIDs that are sent in by the app.
1417 status = hdd_softap_unpackIE(
1418#if defined(FEATURE_WLAN_NON_INTEGRATED_SOC)
1419 vos_get_context( VOS_MODULE_ID_HAL, pVosContext),
1420#else
1421 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
1422#endif
1423 &RSNEncryptType,
1424 &mcRSNEncryptType,
1425 &RSNAuthType,
1426 pConfig->pRSNWPAReqIE[1]+2,
1427 pConfig->pRSNWPAReqIE );
1428
1429 if( VOS_STATUS_SUCCESS == status )
1430 {
1431 // Now copy over all the security attributes you have parsed out
1432 //TODO: Need to handle mixed mode
1433 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1434 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1435 hddLog( LOG1, FL("%s: CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d\n"),
1436 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1437 }
1438 }
1439 }
1440 else
1441 {
1442 /* If no RSNIE, set encrypt type to NONE*/
1443 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1444 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1445 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d\n"),
1446 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
1447 }
1448
1449 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
1450 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
1451 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
1452 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1453
1454 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
1455
1456 // ht_capab is not what the name conveys,this is used for protection bitmap
1457 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1458
1459 if (pCommitConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1460 num_mac = pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1461 else
1462 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
1463 acl_entry = pCommitConfig->accept_mac;
1464 for (i = 0; i < num_mac; i++)
1465 {
1466 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1467 acl_entry++;
1468 }
1469 if (pCommitConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1470 num_mac = pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1471 else
1472 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
1473 acl_entry = pCommitConfig->deny_mac;
1474 for (i = 0; i < num_mac; i++)
1475 {
1476 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1477 acl_entry++;
1478 }
1479 //Uapsd Enabled Bit
1480 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1481 //Enable OBSS protection
1482 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1483 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
1484
1485 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1486 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1487 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int, (int)pConfig->channel);
1488 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1489 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy, pConfig->authType);
1490 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1491 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1492 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),pConfig->protEnabled, pConfig->obssProtEnabled);
1493 hddLog(LOGW,FL("DisableIntraBssFwd = %d\n"),(WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
1494
1495 pSapEventCallback = hdd_hostapd_SAPEventCB;
1496 pConfig->persona = pHostapdAdapter->device_mode;
1497 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
1498 {
1499 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1500 }
1501
1502 kfree(pConfig);
1503
1504 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1505 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1506
1507 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1508 {
1509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos wait for single_event failed!!\n"));
1510 VOS_ASSERT(0);
1511 }
1512
1513 pHostapdState->bCommit = TRUE;
1514 if(pHostapdState->vosStatus)
1515 {
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001516 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001517 }
1518 else
1519 {
1520 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1521 WLANSAP_Update_WpsIe ( pVosContext );
1522 return 0;
1523 }
1524}
1525static
1526int iw_softap_setmlme(struct net_device *dev,
1527 struct iw_request_info *info,
1528 union iwreq_data *wrqu, char *extra)
1529{
1530 struct sQcSapreq_mlme *pmlme;
1531 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
1532 v_MACADDR_t destAddress;
1533 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
1534 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
1535 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
1536 switch(pmlme->im_op)
1537 {
1538 case QCSAP_MLME_AUTHORIZE:
1539 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
1540 break;
1541 case QCSAP_MLME_ASSOC:
1542 //TODO:inform to TL after associating (not needed as we do in sapCallback)
1543 break;
1544 case QCSAP_MLME_UNAUTHORIZE:
1545 //TODO: send the disassoc to station
1546 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
1547 break;
1548 case QCSAP_MLME_DISASSOC:
1549 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
1550 break;
1551 case QCSAP_MLME_DEAUTH:
1552 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
1553 break;
1554 case QCSAP_MLME_MICFAILURE:
1555 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
1556 break;
1557 default:
1558 break;
1559 }
1560 return 0;
1561}
1562
1563static int iw_softap_set_channel_range(struct net_device *dev,
1564 struct iw_request_info *info,
1565 union iwreq_data *wrqu, char *extra)
1566{
1567 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1568 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001569 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001570
1571 int *value = (int *)extra;
1572 int startChannel = value[0];
1573 int endChannel = value[1];
1574 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07001575 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07001576 int ret = 0; /* success */
1577
1578 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
1579 if(status != VOS_STATUS_SUCCESS)
1580 {
1581 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d\n"),
1582 startChannel,endChannel, band);
1583 ret = -EINVAL;
1584 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08001585
1586 pHddCtx->is_dynamic_channel_range_set = 1;
1587
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 return ret;
1589}
1590
1591int iw_softap_get_channel_list(struct net_device *dev,
1592 struct iw_request_info *info,
1593 union iwreq_data *wrqu, char *extra)
1594{
1595 v_U32_t num_channels = 0;
1596 v_U8_t i = 0;
1597 v_U8_t bandStartChannel = RF_CHAN_1;
1598 v_U8_t bandEndChannel = RF_CHAN_165;
1599 v_U32_t temp_num_channels = 0;
1600 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001601 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1603 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001604 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001605 eCsrBand curBand = eCSR_BAND_ALL;
1606
1607 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
1608 {
1609 hddLog(LOGE,FL("not able get the current frequency band\n"));
1610 return -EIO;
1611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001612 wrqu->data.length = sizeof(tChannelListInfo);
1613 ENTER();
1614
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001615 if (eCSR_BAND_24 == curBand)
1616 {
1617 bandStartChannel = RF_CHAN_1;
1618 bandEndChannel = RF_CHAN_14;
1619 }
1620 else if (eCSR_BAND_5G == curBand)
1621 {
1622 bandStartChannel = RF_CHAN_36;
1623 bandEndChannel = RF_CHAN_165;
1624 }
1625
1626 hddLog(LOG1, FL("\n nBandCapability = %d, bandStartChannel = %hu, "
1627 "bandEndChannel = %hu \n"), pHddCtx->cfg_ini->nBandCapability,
1628 bandStartChannel, bandEndChannel );
1629
Jeff Johnson295189b2012-06-20 16:38:30 -07001630 for( i = bandStartChannel; i <= bandEndChannel; i++ )
1631 {
1632 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
1633 {
1634 channel_list->channels[num_channels] = rfChannels[i].channelNum;
1635 num_channels++;
1636 }
1637 }
1638
1639 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
1640
1641 temp_num_channels = num_channels;
1642
1643 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
1644 {
1645 hddLog(LOG1,FL("Failed to get Domain ID, %d \n"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001646 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 }
1648
1649 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
1650 {
1651 for(i = 0; i < temp_num_channels; i++)
1652 {
1653
1654 if((channel_list->channels[i] > 35) &&
1655 (channel_list->channels[i] < 49))
1656 {
1657 vos_mem_move(&channel_list->channels[i],
1658 &channel_list->channels[i+1],
1659 temp_num_channels - (i-1));
1660 num_channels--;
1661 temp_num_channels--;
1662 i--;
1663 }
1664 }
1665 }
1666
1667 hddLog(LOG1,FL(" number of channels %d\n"), num_channels);
1668
1669 if (num_channels > IW_MAX_FREQUENCIES)
1670 {
1671 num_channels = IW_MAX_FREQUENCIES;
1672 }
1673
1674 channel_list->num_channels = num_channels;
1675 EXIT();
1676
1677 return 0;
1678}
1679
1680static
1681int iw_get_genie(struct net_device *dev,
1682 struct iw_request_info *info,
1683 union iwreq_data *wrqu, char *extra)
1684{
1685 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1686 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1687 eHalStatus status;
1688 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
1689 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
1690 ENTER();
1691 hddLog(LOG1,FL("getGEN_IE ioctl\n"));
1692 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
1693 status = WLANSap_getstationIE_information(pVosContext,
1694 &length,
1695 genIeBytes);
1696 wrqu->data.length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
1697 vos_mem_copy( wrqu->data.pointer, (v_VOID_t*)genIeBytes, wrqu->data.length);
1698
1699 hddLog(LOG1,FL(" RSN IE of %d bytes returned\n"), wrqu->data.length );
1700
1701
1702 EXIT();
1703 return 0;
1704}
1705static
1706int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
1707 struct iw_request_info *info,
1708 union iwreq_data *wrqu, char *extra)
1709{
1710 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1711 sQcSapreq_WPSPBCProbeReqIES_t *pWPSPBCProbeReqIEs;
1712 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1713 ENTER();
1714
1715 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl\n"));
1716
1717 pWPSPBCProbeReqIEs = (sQcSapreq_WPSPBCProbeReqIES_t *)(wrqu->data.pointer);
1718 pWPSPBCProbeReqIEs->probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
1719 vos_mem_copy(pWPSPBCProbeReqIEs->probeReqIE, pHddApCtx->WPSPBCProbeReq.probeReqIE, pWPSPBCProbeReqIEs->probeReqIELen);
1720 vos_mem_copy(pWPSPBCProbeReqIEs->macaddr, pHddApCtx->WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
1721 wrqu->data.length = 12 + pWPSPBCProbeReqIEs->probeReqIELen;
1722 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pWPSPBCProbeReqIEs->macaddr));
1723 up(&pHddApCtx->semWpsPBCOverlapInd);
1724 EXIT();
1725 return 0;
1726}
1727
1728/**---------------------------------------------------------------------------
1729
1730 \brief iw_set_auth_hostap() -
1731 This function sets the auth type received from the wpa_supplicant.
1732
1733 \param - dev - Pointer to the net device.
1734 - info - Pointer to the iw_request_info.
1735 - wrqu - Pointer to the iwreq_data.
1736 - extra - Pointer to the data.
1737 \return - 0 for success, non zero for failure
1738
1739 --------------------------------------------------------------------------*/
1740int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
1741 union iwreq_data *wrqu,char *extra)
1742{
1743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1744 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1745
1746 ENTER();
1747 switch(wrqu->param.flags & IW_AUTH_INDEX)
1748 {
1749 case IW_AUTH_TKIP_COUNTERMEASURES:
1750 {
1751 if(wrqu->param.value) {
1752 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1753 "Counter Measure started %d", wrqu->param.value);
1754 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
1755 }
1756 else {
1757 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1758 "Counter Measure stopped=%d", wrqu->param.value);
1759 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
1760 }
1761
1762 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
1763 wrqu->param.value);
1764 }
1765 break;
1766
1767 default:
1768
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001769 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001770 wrqu->param.flags & IW_AUTH_INDEX);
1771 break;
1772 }
1773
1774 EXIT();
1775 return 0;
1776}
1777
1778static int iw_set_ap_encodeext(struct net_device *dev,
1779 struct iw_request_info *info,
1780 union iwreq_data *wrqu, char *extra)
1781{
1782 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1783 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1784 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07001785 int retval = 0;
1786 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001787 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1788 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1789 int key_index;
1790 struct iw_point *encoding = &wrqu->encoding;
1791 tCsrRoamSetKey setKey;
1792// tCsrRoamRemoveKey RemoveKey;
1793 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07001794
Jeff Johnson295189b2012-06-20 16:38:30 -07001795 ENTER();
1796
1797 key_index = encoding->flags & IW_ENCODE_INDEX;
1798
1799 if(key_index > 0) {
1800
1801 /*Convert from 1-based to 0-based keying*/
1802 key_index--;
1803 }
1804 if(!ext->key_len) {
1805#if 0
1806 /*Set the encrytion type to NONE*/
1807#if 0
1808 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
1809#endif
1810
1811 RemoveKey.keyId = key_index;
1812 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1813 /*Key direction for group is RX only*/
1814 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1815 }
1816 else {
1817 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1818 }
1819 switch(ext->alg)
1820 {
1821 case IW_ENCODE_ALG_NONE:
1822 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1823 break;
1824 case IW_ENCODE_ALG_WEP:
1825 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1826 break;
1827 case IW_ENCODE_ALG_TKIP:
1828 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07001829 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 case IW_ENCODE_ALG_CCMP:
1831 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
1832 break;
1833 default:
1834 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1835 break;
1836 }
1837 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 -07001838 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 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 -07001840 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 );
Jeff Johnson43971f52012-07-17 12:26:56 -07001842 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
1843 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 {
1845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07001846 __LINE__, vstatus );
1847 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001848 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001849#endif
1850 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07001851
Jeff Johnson43971f52012-07-17 12:26:56 -07001852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001853
1854 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
1855
1856 setKey.keyId = key_index;
1857 setKey.keyLength = ext->key_len;
1858
1859 if(ext->key_len <= CSR_MAX_KEY_LEN) {
1860 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
1861 }
1862
1863 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1864 /*Key direction for group is RX only*/
1865 setKey.keyDirection = eSIR_RX_ONLY;
1866 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1867 }
1868 else {
1869
1870 setKey.keyDirection = eSIR_TX_RX;
1871 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1872 }
1873 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1874 {
1875 setKey.keyDirection = eSIR_TX_DEFAULT;
1876 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1877 }
1878
1879 /*For supplicant pae role is zero*/
1880 setKey.paeRole = 0;
1881
1882 switch(ext->alg)
1883 {
1884 case IW_ENCODE_ALG_NONE:
1885 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1886 break;
1887
1888 case IW_ENCODE_ALG_WEP:
1889 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1890 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001891 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 break;
1893
1894 case IW_ENCODE_ALG_TKIP:
1895 {
1896 v_U8_t *pKey = &setKey.Key[0];
1897
1898 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
1899
1900 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
1901
1902 /*Supplicant sends the 32bytes key in this order
1903
1904 |--------------|----------|----------|
1905 | Tk1 |TX-MIC | RX Mic |
1906 |--------------|----------|----------|
1907 <---16bytes---><--8bytes--><--8bytes-->
1908
1909 */
1910 /*Sme expects the 32 bytes key to be in the below order
1911
1912 |--------------|----------|----------|
1913 | Tk1 |RX-MIC | TX Mic |
1914 |--------------|----------|----------|
1915 <---16bytes---><--8bytes--><--8bytes-->
1916 */
1917 /* Copy the Temporal Key 1 (TK1) */
1918 vos_mem_copy(pKey,ext->key,16);
1919
1920 /*Copy the rx mic first*/
1921 vos_mem_copy(&pKey[16],&ext->key[24],8);
1922
1923 /*Copy the tx mic */
1924 vos_mem_copy(&pKey[24],&ext->key[16],8);
1925
1926 }
1927 break;
1928
1929 case IW_ENCODE_ALG_CCMP:
1930 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
1931 break;
1932
1933 default:
1934 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1935 break;
1936 }
1937
1938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001939 ("%s:EncryptionType:%d key_len:%d, :%d, KeyId:%d \n"),__func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 setKey.keyId);
1941 for(i=0; i< ext->key_len; i++)
1942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1943 ("%02x"), setKey.Key[i]);
1944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1945 ("\n"));
Jeff Johnson43971f52012-07-17 12:26:56 -07001946
1947 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
1948 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 {
1950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07001951 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
1952 retval = -EINVAL;
1953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001954
Jeff Johnson43971f52012-07-17 12:26:56 -07001955 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07001956}
Jeff Johnson43971f52012-07-17 12:26:56 -07001957
1958
Jeff Johnson295189b2012-06-20 16:38:30 -07001959static int iw_set_ap_mlme(struct net_device *dev,
1960 struct iw_request_info *info,
1961 union iwreq_data *wrqu,
1962 char *extra)
1963{
1964#if 0
1965 hdd_adapter_t *pAdapter = (netdev_priv(dev));
1966 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1967
1968 ENTER();
1969
1970 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
1971 switch (mlme->cmd) {
1972 case IW_MLME_DISASSOC:
1973 case IW_MLME_DEAUTH:
1974 hddLog(LOG1, "Station disassociate");
1975 if( pAdapter->conn_info.connState == eConnectionState_Associated )
1976 {
1977 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
1978
1979 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
1980 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
1981
1982 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
1983
1984 //clear all the reason codes
1985 if (status != 0)
1986 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001987 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 -07001988 }
1989
1990 netif_stop_queue(dev);
1991 netif_carrier_off(dev);
1992 }
1993 else
1994 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001995 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 -07001996 }
1997 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001998 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate \n", __func__, (int)mlme->cmd );
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 return -EINVAL;
2000 }//end of switch
2001 EXIT();
2002#endif
2003 return 0;
2004// return status;
2005}
2006
2007static int iw_get_ap_rts_threshold(struct net_device *dev,
2008 struct iw_request_info *info,
2009 union iwreq_data *wrqu, char *extra)
2010{
2011 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2012 v_U32_t status = 0;
2013
2014 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2015
2016 return status;
2017}
2018
2019static int iw_get_ap_frag_threshold(struct net_device *dev,
2020 struct iw_request_info *info,
2021 union iwreq_data *wrqu, char *extra)
2022{
2023 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2024 v_U32_t status = 0;
2025
2026 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2027
2028 return status;
2029}
2030
2031static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2032 struct iw_freq *fwrq, char *extra)
2033{
Jeff Johnsone7245742012-09-05 17:12:55 -07002034 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2036 tHalHandle hHal;
2037 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002038 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002039
2040 ENTER();
2041
2042 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2044 "%s:LOGP in Progress. Ignore!!!",__func__);
2045 return status;
2046 }
2047
2048 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2049 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2050
2051 if(pHostapdState->bssState == BSS_STOP )
2052 {
2053 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2054 != eHAL_STATUS_SUCCESS)
2055 {
2056 return -EIO;
2057 }
2058 else
2059 {
2060 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002061 if( TRUE == status)
2062 {
2063 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2064 * iwlist & iwconfig command shows frequency into proper
2065 * format (2.412 GHz instead of 246.2 MHz)*/
2066 fwrq->m = freq;
2067 fwrq->e = MHZ;
2068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 }
2070 }
2071 else
2072 {
2073 channel = pHddApCtx->operatingChannel;
2074 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002075 if( TRUE == status)
2076 {
2077 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2078 * iwlist & iwconfig command shows frequency into proper
2079 * format (2.412 GHz instead of 246.2 MHz)*/
2080 fwrq->m = freq;
2081 fwrq->e = MHZ;
2082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002084 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002085}
2086
2087static int iw_softap_setwpsie(struct net_device *dev,
2088 struct iw_request_info *info,
2089 union iwreq_data *wrqu,
2090 char *extra)
2091{
2092 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2093 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2094 hdd_hostapd_state_t *pHostapdState;
2095 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2096 u_int8_t *wps_genie = wrqu->data.pointer;
2097 u_int8_t *pos;
2098 tpSap_WPSIE pSap_WPSIe;
2099 u_int8_t WPSIeType;
2100 u_int16_t length;
2101 ENTER();
2102
2103 if(!wrqu->data.length)
2104 return 0;
2105
2106 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2107 if (NULL == pSap_WPSIe)
2108 {
2109 hddLog(LOGE, "VOS unable to allocate memory\n");
2110 return -ENOMEM;
2111 }
2112 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2113
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002114 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 -07002115 WPSIeType = wps_genie[0];
2116 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2117 {
2118 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2119 wps_genie = wps_genie + 1;
2120 switch ( wps_genie[0] )
2121 {
2122 case DOT11F_EID_WPA:
2123 if (wps_genie[1] < 2 + 4)
2124 {
2125 vos_mem_free(pSap_WPSIe);
2126 return -EINVAL;
2127 }
2128 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2129 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002130 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 pos = &wps_genie[6];
2132 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2133 {
2134 switch((u_int16_t)(*pos<<8) | *(pos+1))
2135 {
2136 case HDD_WPS_ELEM_VERSION:
2137 pos += 4;
2138 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
2139 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
2140 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2141 pos += 1;
2142 break;
2143
2144 case HDD_WPS_ELEM_WPS_STATE:
2145 pos +=4;
2146 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
2147 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
2148 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2149 pos += 1;
2150 break;
2151 case HDD_WPS_ELEM_APSETUPLOCK:
2152 pos += 4;
2153 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
2154 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
2155 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2156 pos += 1;
2157 break;
2158 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2159 pos += 4;
2160 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
2161 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
2162 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2163 pos += 1;
2164 break;
2165 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2166 pos += 4;
2167 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2168 hddLog(LOG1, "Password ID: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
2169 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2170 pos += 2;
2171 break;
2172 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2173 pos += 4;
2174 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2175 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
2176 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2177 pos += 2;
2178 break;
2179
2180 case HDD_WPS_ELEM_UUID_E:
2181 pos += 2;
2182 length = *pos<<8 | *(pos+1);
2183 pos += 2;
2184 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2185 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2186 pos += length;
2187 break;
2188 case HDD_WPS_ELEM_RF_BANDS:
2189 pos += 4;
2190 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
2191 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
2192 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2193 pos += 1;
2194 break;
2195
2196 default:
2197 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)\n", (*pos<<8 | *(pos+1)));
2198 vos_mem_free(pSap_WPSIe);
2199 return -EINVAL;
2200 }
2201 }
2202 }
2203 else {
2204 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002205 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002206 }
2207 break;
2208
2209 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002210 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 vos_mem_free(pSap_WPSIe);
2212 return 0;
2213 }
2214 }
2215 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2216 {
2217 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2218 wps_genie = wps_genie + 1;
2219 switch ( wps_genie[0] )
2220 {
2221 case DOT11F_EID_WPA:
2222 if (wps_genie[1] < 2 + 4)
2223 {
2224 vos_mem_free(pSap_WPSIe);
2225 return -EINVAL;
2226 }
2227 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2228 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002229 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002230 pos = &wps_genie[6];
2231 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2232 {
2233 switch((u_int16_t)(*pos<<8) | *(pos+1))
2234 {
2235 case HDD_WPS_ELEM_VERSION:
2236 pos += 4;
2237 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
2238 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
2239 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2240 pos += 1;
2241 break;
2242
2243 case HDD_WPS_ELEM_WPS_STATE:
2244 pos +=4;
2245 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
2246 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
2247 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2248 pos += 1;
2249 break;
2250 case HDD_WPS_ELEM_APSETUPLOCK:
2251 pos += 4;
2252 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
2253 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
2254 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2255 pos += 1;
2256 break;
2257 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2258 pos += 4;
2259 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
2260 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
2261 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2262 pos += 1;
2263 break;
2264 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2265 pos += 4;
2266 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2267 hddLog(LOG1, "Password ID: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
2268 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2269 pos += 2;
2270 break;
2271 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2272 pos += 4;
2273 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2274 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2275 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2276 pos += 2;
2277 break;
2278 case HDD_WPS_ELEM_RSP_TYPE:
2279 pos += 4;
2280 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
2281 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
2282 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2283 pos += 1;
2284 break;
2285 case HDD_WPS_ELEM_UUID_E:
2286 pos += 2;
2287 length = *pos<<8 | *(pos+1);
2288 pos += 2;
2289 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2290 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2291 pos += length;
2292 break;
2293
2294 case HDD_WPS_ELEM_MANUFACTURER:
2295 pos += 2;
2296 length = *pos<<8 | *(pos+1);
2297 pos += 2;
2298 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2299 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2300 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2301 pos += length;
2302 break;
2303
2304 case HDD_WPS_ELEM_MODEL_NAME:
2305 pos += 2;
2306 length = *pos<<8 | *(pos+1);
2307 pos += 2;
2308 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2309 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2310 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2311 pos += length;
2312 break;
2313 case HDD_WPS_ELEM_MODEL_NUM:
2314 pos += 2;
2315 length = *pos<<8 | *(pos+1);
2316 pos += 2;
2317 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2318 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2319 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2320 pos += length;
2321 break;
2322 case HDD_WPS_ELEM_SERIAL_NUM:
2323 pos += 2;
2324 length = *pos<<8 | *(pos+1);
2325 pos += 2;
2326 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2327 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2328 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2329 pos += length;
2330 break;
2331 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2332 pos += 4;
2333 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
2334 hddLog(LOG1, "primary dev category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
2335 pos += 2;
2336
2337 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
2338 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x\n", pos[0], pos[1], pos[2], pos[3]);
2339 pos += 4;
2340 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
2341 hddLog(LOG1, "primary dev sub category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
2342 pos += 2;
2343 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2344 break;
2345 case HDD_WPS_ELEM_DEVICE_NAME:
2346 pos += 2;
2347 length = *pos<<8 | *(pos+1);
2348 pos += 2;
2349 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2350 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2351 pos += length;
2352 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2353 break;
2354 case HDD_WPS_ELEM_CONFIG_METHODS:
2355 pos += 4;
2356 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
2357 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2358 pos += 2;
2359 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2360 break;
2361
2362 case HDD_WPS_ELEM_RF_BANDS:
2363 pos += 4;
2364 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
2365 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
2366 pos += 1;
2367 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2368 break;
2369 } // switch
2370 }
2371 }
2372 else
2373 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002374 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 }
2376
2377 } // switch
2378 }
2379 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2380 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2381 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2382 {
2383 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2384 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2385 WLANSAP_Update_WpsIe ( pVosContext );
2386 }
2387
2388 vos_mem_free(pSap_WPSIe);
2389 EXIT();
2390 return halStatus;
2391}
2392
2393static int iw_softap_stopbss(struct net_device *dev,
2394 struct iw_request_info *info,
2395 union iwreq_data *wrqu,
2396 char *extra)
2397{
2398 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2399 VOS_STATUS status = VOS_STATUS_SUCCESS;
2400 ENTER();
2401 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2402 {
2403 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2404 {
2405 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2406
2407 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2408
2409 if (!VOS_IS_STATUS_SUCCESS(status))
2410 {
2411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2412 ("ERROR: HDD vos wait for single_event failed!!\n"));
2413 VOS_ASSERT(0);
2414 }
2415 }
2416 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2417 }
2418 EXIT();
2419 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2420}
2421
2422static int iw_softap_version(struct net_device *dev,
2423 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002424 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07002425 char *extra)
2426{
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002428
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08002430 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002431 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07002432 return 0;
2433}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002434
2435VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf)
2436{
2437 v_U8_t i;
2438
2439 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2440 {
2441 if(pAdapter->aStaInfo[i].isUsed)
2442 {
2443 pBuf += snprintf(pBuf, WE_GET_STA_INFO_SIZE, "staIndex = %d staAddress =.%02x:%02x:%02x:%02x:%02x:%02x\n",
2444 pAdapter->aStaInfo[i].ucSTAId,
2445 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
2446 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
2447 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
2448 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
2449 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
2450 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
2451 }
2452 }
2453 return VOS_STATUS_SUCCESS;
2454}
2455
2456static int iw_softap_get_sta_info(struct net_device *dev,
2457 struct iw_request_info *info,
2458 union iwreq_data *wrqu,
2459 char *extra)
2460{
2461 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2462 VOS_STATUS status;
2463 ENTER();
2464 status = hdd_softap_get_sta_info(pHostapdAdapter, extra);
2465 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
2466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n",__func__);
2467 return -EINVAL;
2468 }
2469 wrqu->data.length = strlen(extra);
2470 EXIT();
2471 return 0;
2472}
2473
Jeff Johnson295189b2012-06-20 16:38:30 -07002474static int iw_set_ap_genie(struct net_device *dev,
2475 struct iw_request_info *info,
2476 union iwreq_data *wrqu,
2477 char *extra)
2478{
2479
2480 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2481 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2482 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2483 u_int8_t *genie = wrqu->data.pointer;
2484
2485 ENTER();
2486
2487 if(!wrqu->data.length)
2488 {
2489 EXIT();
2490 return 0;
2491 }
2492
2493 switch (genie[0])
2494 {
2495 case DOT11F_EID_WPA:
2496 case DOT11F_EID_RSN:
2497 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
2498 {
2499 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
2500 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
2501 }
2502 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
2503 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, wrqu->data.pointer, wrqu->data.length);
2504 break;
2505
2506 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002507 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002508 halStatus = 0;
2509 }
2510
2511 EXIT();
2512 return halStatus;
2513}
2514
2515static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
2516{
2517 eHalStatus hstatus;
2518 long lrc;
2519 struct statsContext context;
2520
2521 if (NULL == pAdapter)
2522 {
2523 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Padapter is NULL", __func__);
2524 return VOS_STATUS_E_FAULT;
2525 }
2526
2527 init_completion(&context.completion);
2528 context.pAdapter = pAdapter;
2529 context.magic = STATS_CONTEXT_MAGIC;
2530 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
2531 eCSR_HDD,
2532 SME_GLOBAL_CLASSA_STATS,
2533 hdd_GetClassA_statisticsCB,
2534 0, // not periodic
2535 FALSE, //non-cached results
2536 staid,
2537 &context);
2538 if (eHAL_STATUS_SUCCESS != hstatus)
2539 {
2540 hddLog(VOS_TRACE_LEVEL_ERROR,
2541 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002542 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002543 }
2544 else
2545 {
2546 lrc = wait_for_completion_interruptible_timeout(&context.completion,
2547 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2548 context.magic = 0;
2549 if (lrc <= 0)
2550 {
2551 hddLog(VOS_TRACE_LEVEL_ERROR,
2552 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002553 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 msleep(50);
2555 }
2556 }
2557 return VOS_STATUS_SUCCESS;
2558}
2559
2560int iw_get_softap_linkspeed(struct net_device *dev,
2561 struct iw_request_info *info,
2562 union iwreq_data *wrqu,
2563 char *extra)
2564
2565{
2566 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2567 char *pLinkSpeed = (char*)extra;
2568 v_U16_t link_speed;
2569 unsigned short staId;
2570 int len = sizeof(v_U16_t)+1;
2571 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
2572 VOS_STATUS status;
2573 int rc;
2574
2575 if ( hdd_string_to_hex ((char *)wrqu->data.pointer, wrqu->data.length, macAddress ) )
2576 {
2577 hddLog(VOS_TRACE_LEVEL_FATAL, "ERROR: Command not found");
2578 return -EINVAL;
2579 }
2580
2581 status = hdd_softap_GetStaId(pHostapdAdapter, (v_MACADDR_t *)macAddress, (void *)(&staId));
2582
2583 if (!VOS_IS_STATUS_SUCCESS(status ))
2584 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002585 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 -07002586 link_speed = 0;
2587 }
2588 else
2589 {
2590 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
2591 if (!VOS_IS_STATUS_SUCCESS(status ))
2592 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve SME statistics", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002594 return -EINVAL;
2595 }
2596 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
2597 }
2598
2599 wrqu->data.length = len;
2600 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
2601 if ((rc < 0) || (rc >= len))
2602 {
2603 // encoding or length error?
2604 hddLog(VOS_TRACE_LEVEL_ERROR,
2605 "%s: Unable to encode link speed, got [%s]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002606 __func__, pLinkSpeed);
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 return -EIO;
2608 }
2609
2610 return 0;
2611}
2612
2613static const iw_handler hostapd_handler[] =
2614{
2615 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2616 (iw_handler) NULL, /* SIOCGIWNAME */
2617 (iw_handler) NULL, /* SIOCSIWNWID */
2618 (iw_handler) NULL, /* SIOCGIWNWID */
2619 (iw_handler) NULL, /* SIOCSIWFREQ */
2620 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
2621 (iw_handler) NULL, /* SIOCSIWMODE */
2622 (iw_handler) NULL, /* SIOCGIWMODE */
2623 (iw_handler) NULL, /* SIOCSIWSENS */
2624 (iw_handler) NULL, /* SIOCGIWSENS */
2625 (iw_handler) NULL, /* SIOCSIWRANGE */
2626 (iw_handler) NULL, /* SIOCGIWRANGE */
2627 (iw_handler) NULL, /* SIOCSIWPRIV */
2628 (iw_handler) NULL, /* SIOCGIWPRIV */
2629 (iw_handler) NULL, /* SIOCSIWSTATS */
2630 (iw_handler) NULL, /* SIOCGIWSTATS */
2631 (iw_handler) NULL, /* SIOCSIWSPY */
2632 (iw_handler) NULL, /* SIOCGIWSPY */
2633 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2634 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2635 (iw_handler) NULL, /* SIOCSIWAP */
2636 (iw_handler) NULL, /* SIOCGIWAP */
2637 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
2638 (iw_handler) NULL, /* SIOCGIWAPLIST */
2639 (iw_handler) NULL, /* SIOCSIWSCAN */
2640 (iw_handler) NULL, /* SIOCGIWSCAN */
2641 (iw_handler) NULL, /* SIOCSIWESSID */
2642 (iw_handler) NULL, /* SIOCGIWESSID */
2643 (iw_handler) NULL, /* SIOCSIWNICKN */
2644 (iw_handler) NULL, /* SIOCGIWNICKN */
2645 (iw_handler) NULL, /* -- hole -- */
2646 (iw_handler) NULL, /* -- hole -- */
2647 (iw_handler) NULL, /* SIOCSIWRATE */
2648 (iw_handler) NULL, /* SIOCGIWRATE */
2649 (iw_handler) NULL, /* SIOCSIWRTS */
2650 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
2651 (iw_handler) NULL, /* SIOCSIWFRAG */
2652 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
2653 (iw_handler) NULL, /* SIOCSIWTXPOW */
2654 (iw_handler) NULL, /* SIOCGIWTXPOW */
2655 (iw_handler) NULL, /* SIOCSIWRETRY */
2656 (iw_handler) NULL, /* SIOCGIWRETRY */
2657 (iw_handler) NULL, /* SIOCSIWENCODE */
2658 (iw_handler) NULL, /* SIOCGIWENCODE */
2659 (iw_handler) NULL, /* SIOCSIWPOWER */
2660 (iw_handler) NULL, /* SIOCGIWPOWER */
2661 (iw_handler) NULL, /* -- hole -- */
2662 (iw_handler) NULL, /* -- hole -- */
2663 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
2664 (iw_handler) NULL, /* SIOCGIWGENIE */
2665 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
2666 (iw_handler) NULL, /* SIOCGIWAUTH */
2667 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
2668 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
2669 (iw_handler) NULL, /* SIOCSIWPMKSA */
2670};
2671
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002672#define IW_PRIV_TYPE_OPTIE (IW_PRIV_TYPE_BYTE | QCSAP_MAX_OPT_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002673#define IW_PRIV_TYPE_MLME \
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002674 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
Jeff Johnson295189b2012-06-20 16:38:30 -07002675
2676static const struct iw_priv_args hostapd_private_args[] = {
2677 { QCSAP_IOCTL_SETPARAM,
2678 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
2679 { QCSAP_IOCTL_SETPARAM,
2680 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2681 { QCSAP_PARAM_MAX_ASSOC,
2682 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
2683 { QCSAP_PARAM_HIDE_SSID,
2684 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
2685 { QCSAP_IOCTL_GETPARAM,
2686 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2687 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
2688 { QCSAP_IOCTL_GETPARAM, 0,
2689 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2690 { QCSAP_PARAM_MAX_ASSOC, 0,
2691 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07002692 { QCSAP_PARAM_GET_WLAN_DBG, 0,
2693 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
2694 { QCSAP_PARAM_AUTO_CHANNEL, 0,
2695 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
2697 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
2698 { QCSAP_PARAM_CLR_ACL, 0,
2699 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
2700 { QCSAP_PARAM_ACL_MODE,
2701 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
2702 { QCSAP_IOCTL_COMMIT,
2703 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
2704 { QCSAP_IOCTL_SETMLME,
2705 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
2706 { QCSAP_IOCTL_GET_STAWPAIE,
2707 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
2708 { QCSAP_IOCTL_SETWPAIE,
2709 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
2710 { QCSAP_IOCTL_STOPBSS,
2711 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
2712 { QCSAP_IOCTL_VERSION, 0,
2713 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002714 { QCSAP_IOCTL_GET_STA_INFO, 0,
2715 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002716 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
2717 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED | 1, 0, "getProbeReqIEs" },
2718 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07002719 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002720 { QCSAP_IOCTL_ASSOC_STA_MACADDR, 0,
2721 IW_PRIV_TYPE_BYTE | /*((WLAN_MAX_STA_COUNT*6)+100)*/1 , "get_assoc_stamac" },
2722 { QCSAP_IOCTL_DISASSOC_STA,
2723 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
2724 { QCSAP_IOCTL_AP_STATS,
2725 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
2726 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
2727 IW_PRIV_TYPE_CHAR | 18,
2728 IW_PRIV_TYPE_CHAR | 3, "getLinkSpeed" },
2729
2730 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
2731 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
2732 /* handlers for sub-ioctl */
2733 { WE_SET_WLAN_DBG,
2734 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
2735 0,
2736 "setwlandbg" },
2737
2738 /* handlers for main ioctl */
2739 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
2740 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2741 0,
2742 "" },
2743
2744 /* handlers for sub-ioctl */
2745 { WE_LOG_DUMP_CMD,
2746 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2747 0,
2748 "dump" },
2749#ifdef WLAN_FEATURE_P2P
2750 { WE_P2P_NOA_CMD,
2751 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2752 0,
2753 "SetP2pPs" },
2754#endif
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08002755 /* handlers for sub ioctl */
2756 {
2757 WE_MCC_CONFIG_CREDENTIAL,
2758 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2759 0,
2760 "setMccCrdnl" },
2761
2762 /* handlers for sub ioctl */
2763 {
2764 WE_MCC_CONFIG_PARAMS,
2765 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2766 0,
2767 "setMccConfig" },
2768
Jeff Johnson295189b2012-06-20 16:38:30 -07002769 /* handlers for main ioctl */
2770 { QCSAP_IOCTL_MODIFY_ACL,
2771 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
2772 0,
2773 "modify_acl" },
2774
2775 /* handlers for main ioctl */
2776 { QCSAP_IOCTL_GET_CHANNEL_LIST,
2777 0,
2778 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
2779 "getChannelList" },
2780
Jeff Johnsone7245742012-09-05 17:12:55 -07002781 /* handlers for main ioctl */
2782 { QCSAP_IOCTL_SET_TX_POWER,
2783 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
2784 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05302785 "setTxPower" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002786};
Jeff Johnsone7245742012-09-05 17:12:55 -07002787
Jeff Johnson295189b2012-06-20 16:38:30 -07002788static const iw_handler hostapd_private[] = {
2789 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
2790 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
2791 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
2792 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
2793 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
2794 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
2795 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
2796 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
2797 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
2798 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
2799 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
2800 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
2801 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
2802 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
2803 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
2804 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
2805 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
2806 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002807 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07002808 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
2809 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
Jeff Johnson295189b2012-06-20 16:38:30 -07002810};
2811const struct iw_handler_def hostapd_handler_def = {
2812 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
2813 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
2814 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
2815 .standard = (iw_handler *)hostapd_handler,
2816 .private = (iw_handler *)hostapd_private,
2817 .private_args = hostapd_private_args,
2818 .get_wireless_stats = NULL,
2819};
2820#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2821struct net_device_ops net_ops_struct = {
2822 .ndo_open = hdd_hostapd_open,
2823 .ndo_stop = hdd_hostapd_stop,
2824 .ndo_uninit = hdd_hostapd_uninit,
2825 .ndo_start_xmit = hdd_softap_hard_start_xmit,
2826 .ndo_tx_timeout = hdd_softap_tx_timeout,
2827 .ndo_get_stats = hdd_softap_stats,
2828 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
2829 .ndo_do_ioctl = hdd_hostapd_ioctl,
2830 .ndo_change_mtu = hdd_hostapd_change_mtu,
2831 .ndo_select_queue = hdd_hostapd_select_queue,
2832 };
2833#endif
2834
2835int hdd_set_hostapd(hdd_adapter_t *pAdapter)
2836{
2837 return VOS_STATUS_SUCCESS;
2838}
2839
2840void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
2841{
2842#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2843 pWlanHostapdDev->netdev_ops = &net_ops_struct;
2844#else
2845 pWlanHostapdDev->open = hdd_hostapd_open;
2846 pWlanHostapdDev->stop = hdd_hostapd_stop;
2847 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
2848 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
2849 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
2850 pWlanHostapdDev->get_stats = hdd_softap_stats;
2851 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
2852 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
2853#endif
2854}
2855
2856VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
2857{
2858 hdd_hostapd_state_t * phostapdBuf;
2859 struct net_device *dev = pAdapter->dev;
2860 VOS_STATUS status;
2861 ENTER();
2862 // Allocate the Wireless Extensions state structure
2863 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
2864
2865 // Zero the memory. This zeros the profile structure.
2866 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
2867
2868 // Set up the pointer to the Wireless Extensions state structure
2869 // NOP
2870 status = hdd_set_hostapd(pAdapter);
2871 if(!VOS_IS_STATUS_SUCCESS(status)) {
2872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!\n"));
2873 return status;
2874 }
2875
2876 status = vos_event_init(&phostapdBuf->vosEvent);
2877 if (!VOS_IS_STATUS_SUCCESS(status))
2878 {
2879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!\n"));
2880 return status;
2881 }
2882
2883 init_completion(&pAdapter->session_close_comp_var);
2884 init_completion(&pAdapter->session_open_comp_var);
2885
2886 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
2887
2888 // Register as a wireless device
2889 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
2890
2891 //Initialize the data path module
2892 status = hdd_softap_init_tx_rx(pAdapter);
2893 if ( !VOS_IS_STATUS_SUCCESS( status ))
2894 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002896 }
2897
2898#ifdef CONFIG_CFG80211
2899 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
2900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002901 EXIT();
2902 return status;
2903}
2904
2905hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
2906{
2907 struct net_device *pWlanHostapdDev = NULL;
2908 hdd_adapter_t *pHostapdAdapter = NULL;
2909 v_CONTEXT_t pVosContext= NULL;
2910
2911#ifdef CONFIG_CFG80211
2912 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
2913#else
2914 pWlanHostapdDev = alloc_etherdev_mq(sizeof(hdd_adapter_t), NUM_TX_QUEUES);
2915#endif
2916
2917 if (pWlanHostapdDev != NULL)
2918 {
2919 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
2920
2921 //Init the net_device structure
2922 ether_setup(pWlanHostapdDev);
2923
2924 //Initialize the adapter context to zeros.
2925 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
2926 pHostapdAdapter->dev = pWlanHostapdDev;
2927 pHostapdAdapter->pHddCtx = pHddCtx;
2928 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
2929
2930 //Get the Global VOSS context.
2931 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2932 //Save the adapter context in global context for future.
2933 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
2934
2935 //Init the net_device structure
2936 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
2937
2938 hdd_set_ap_ops( pHostapdAdapter->dev );
2939
2940 pWlanHostapdDev->tx_queue_len = NET_DEV_TX_QUEUE_LEN;
2941 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
2942 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
2943
2944 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
2945 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
2946
2947 pWlanHostapdDev->destructor = free_netdev;
2948#ifdef CONFIG_CFG80211
2949 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
2950 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
2951 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
2952 init_completion(&pHostapdAdapter->tx_action_cnf_event);
2953#endif
2954 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
2955 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
2956#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2957 init_completion(&pHostapdAdapter->offchannel_tx_event);
2958#endif
2959
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
2961 }
2962 return pHostapdAdapter;
2963}
2964
2965VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
2966{
2967 struct net_device *dev = pAdapter->dev;
2968 VOS_STATUS status = VOS_STATUS_SUCCESS;
2969
2970 ENTER();
2971
2972 if( rtnl_lock_held )
2973 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08002974 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 if( dev_alloc_name(dev, dev->name) < 0 )
2976 {
2977 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
2978 return VOS_STATUS_E_FAILURE;
2979 }
2980 }
2981 if (register_netdevice(dev))
2982 {
2983 hddLog(VOS_TRACE_LEVEL_FATAL,
2984 "%s:Failed:register_netdevice", __func__);
2985 return VOS_STATUS_E_FAILURE;
2986 }
2987 }
2988 else
2989 {
2990 if (register_netdev(dev))
2991 {
2992 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
2993 return VOS_STATUS_E_FAILURE;
2994 }
2995 }
2996 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
2997
2998 EXIT();
2999 return status;
3000}
3001
3002VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3003{
3004 ENTER();
3005
3006 hdd_softap_deinit_tx_rx(pAdapter);
3007
3008 /* if we are being called during driver unload, then the dev has already
3009 been invalidated. if we are being called at other times, then we can
3010 detatch the wireless device handlers */
3011 if (pAdapter->dev)
3012 {
3013 pAdapter->dev->wireless_handlers = NULL;
3014 }
3015 EXIT();
3016 return 0;
3017}