blob: 0e442a4944fe855ec3c16770b53f41a412f14c96 [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 }
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800647 if (wake_lock_active(&pHddCtx->sap_wake_lock))
648 {
649 wake_unlock(&pHddCtx->sap_wake_lock);
650 }
651 wake_lock_timeout(&pHddCtx->sap_wake_lock, HDD_SAP_WAKE_LOCK_DURATION);
Jeff Johnson295189b2012-06-20 16:38:30 -0700652#ifdef CONFIG_CFG80211
653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
654 {
655 struct station_info staInfo;
656 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
657
658 memset(&staInfo, 0, sizeof(staInfo));
659 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
660 {
661 staInfo.assoc_req_ies =
662 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
663 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700665 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
666#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700667 cfg80211_new_sta(dev,
668 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
669 &staInfo, GFP_KERNEL);
670 }
671 else
672 {
673 hddLog(LOGE, FL(" Assoc Ie length is too long \n"));
674 }
675 }
676#endif
677#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800678 pScanInfo = &pHddCtx->scan_info;
679 // Lets do abort scan to ensure smooth authentication for client
680 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
681 {
682 hdd_abort_mac_scan(pHddCtx);
683 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700684
685 break;
686 case eSAP_STA_DISASSOC_EVENT:
687 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800688 sizeof(v_MACADDR_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
690 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
691 hddLog(LOG1," User initiated disassociation");
692 else
693 hddLog(LOG1," MAC initiated disassociation");
694 we_event = IWEVEXPIRED;
695 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
696 if (!VOS_IS_STATUS_SUCCESS(vos_status))
697 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700698 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 -0700699 return VOS_STATUS_E_FAILURE;
700 }
701 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
702
703 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
704 {
705 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
706 // Start AP inactivity timer if no stations associated with it
707 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
708 {
709 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
710 {
711 bApActive = TRUE;
712 break;
713 }
714 }
715 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
716
717 if (bApActive == FALSE)
718 {
719 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
720 {
721 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
722 if (!VOS_IS_STATUS_SUCCESS(vos_status))
723 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
724 }
725 else
726 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
727 }
728 }
729#ifdef CONFIG_CFG80211
730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
731 cfg80211_del_sta(dev,
732 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
733 GFP_KERNEL);
734#endif
735#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800736 //Update the beacon Interval if it is P2P GO
737 hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 break;
739 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
740 {
741 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
742 union iwreq_data wreq;
743
744 down(&pHddApCtx->semWpsPBCOverlapInd);
745 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
746
747 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
748 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
749
750 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
751 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
752 memset(&wreq, 0, sizeof(wreq));
753 wreq.data.length = strlen(message); // This is length of message
754 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
755
756 return VOS_STATUS_SUCCESS;
757 }
758 case eSAP_ASSOC_STA_CALLBACK_EVENT:
759 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
760 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
761 { // List of associated stations
762 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
763 {
764 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
765 i+1,
766 pAssocStasArray->assocId,
767 pAssocStasArray->staId,
768 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
769 pAssocStasArray++;
770 }
771 }
772 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
773 return VOS_STATUS_SUCCESS;
774#ifdef WLAN_FEATURE_P2P
775 case eSAP_INDICATE_MGMT_FRAME:
776 hdd_indicateMgmtFrame( pHostapdAdapter,
777 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
778 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
779 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530780 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 return VOS_STATUS_SUCCESS;
782 case eSAP_REMAIN_CHAN_READY:
783 hdd_remainChanReadyHandler( pHostapdAdapter );
784 return VOS_STATUS_SUCCESS;
785 case eSAP_SEND_ACTION_CNF:
786 hdd_sendActionCnf( pHostapdAdapter,
787 ( eSAP_STATUS_SUCCESS ==
788 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
789 TRUE : FALSE );
790 return VOS_STATUS_SUCCESS;
791#endif
792 case eSAP_UNKNOWN_STA_JOIN:
793 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
794 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
795 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
796 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
797 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
798 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
799 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
800 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
801 wrqu.data.pointer = unknownSTAEvent;
802 wrqu.data.length = strlen(unknownSTAEvent);
803 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
804 hddLog(LOG1,"%s\n", unknownSTAEvent);
805 break;
806
807 case eSAP_MAX_ASSOC_EXCEEDED:
808 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
809 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
810 " one or more devices to enable the new device connection",
811 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
812 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
813 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
814 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
815 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
816 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
817 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
818 wrqu.data.pointer = maxAssocExceededEvent;
819 wrqu.data.length = strlen(maxAssocExceededEvent);
820 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
821 hddLog(LOG1,"%s\n", maxAssocExceededEvent);
822 break;
823 case eSAP_STA_ASSOC_IND:
824 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800825
826 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
827 hddLog(LOG1, FL(" Disconnecting all the P2P Clients....\n"));
828 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
829 return VOS_STATUS_SUCCESS;
830
831 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
832 hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
833 return VOS_STATUS_SUCCESS;
834
Jeff Johnson295189b2012-06-20 16:38:30 -0700835 default:
836 hddLog(LOG1,"SAP message is not handled\n");
837 goto stopbss;
838 return VOS_STATUS_SUCCESS;
839 }
840 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
841 return VOS_STATUS_SUCCESS;
842
843stopbss :
844 {
845 v_BYTE_t we_custom_event[64];
846 char *stopBssEvent = "STOP-BSS.response";//17
847 int event_len = strlen(stopBssEvent);
848
849 hddLog(LOG1, FL("BSS stop status = %s"),
850 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
851 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
852
853 /* Change the BSS state now since, as we are shutting things down,
854 * we don't want interfaces to become re-enabled */
855 pHostapdState->bssState = BSS_STOP;
856
857 /* Stop the pkts from n/w stack as we are going to free all of
858 * the TX WMM queues for all STAID's */
859 hdd_hostapd_stop(dev);
860
861 /* reclaim all resources allocated to the BSS */
862 hdd_softap_stop_bss(pHostapdAdapter);
863
864 /* notify userspace that the BSS has stopped */
865 memset(&we_custom_event, '\0', sizeof(we_custom_event));
866 memcpy(&we_custom_event, stopBssEvent, event_len);
867 memset(&wrqu, 0, sizeof(wrqu));
868 wrqu.data.length = event_len;
869 we_event = IWEVCUSTOM;
870 we_custom_event_generic = we_custom_event;
871 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
872 }
873 return VOS_STATUS_SUCCESS;
874}
875int hdd_softap_unpackIE(
876 tHalHandle halHandle,
877 eCsrEncryptionType *pEncryptType,
878 eCsrEncryptionType *mcEncryptType,
879 eCsrAuthType *pAuthType,
880 u_int16_t gen_ie_len,
881 u_int8_t *gen_ie )
882{
883 tDot11fIERSN dot11RSNIE;
884 tDot11fIEWPA dot11WPAIE;
885
886 tANI_U8 *pRsnIe;
887 tANI_U16 RSNIeLen;
888
889 if (NULL == halHandle)
890 {
891 hddLog(LOGE, FL("Error haHandle returned NULL\n"));
892 return -EINVAL;
893 }
894
895 // Validity checks
896 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
897 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
898 return -EINVAL;
899 // Type check
900 if ( gen_ie[0] == DOT11F_EID_RSN)
901 {
902 // Validity checks
903 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
904 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
905 {
906 return VOS_STATUS_E_FAILURE;
907 }
908 // Skip past the EID byte and length byte
909 pRsnIe = gen_ie + 2;
910 RSNIeLen = gen_ie_len - 2;
911 // Unpack the RSN IE
912 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
913 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
914 pRsnIe,
915 RSNIeLen,
916 &dot11RSNIE);
917 // Copy out the encryption and authentication types
918 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700919 __func__, dot11RSNIE.pwise_cipher_suite_count );
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 hddLog(LOG1, FL("%s: authentication suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700921 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 /*Here we have followed the apple base code,
923 but probably I suspect we can do something different*/
924 //dot11RSNIE.akm_suite_count
925 // Just translate the FIRST one
926 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
927 //dot11RSNIE.pwise_cipher_suite_count
928 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
929 //dot11RSNIE.gp_cipher_suite_count
930 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
931 // Set the PMKSA ID Cache for this interface
932
933 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
934 } else
935 if (gen_ie[0] == DOT11F_EID_WPA)
936 {
937 // Validity checks
938 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
939 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
940 {
941 return VOS_STATUS_E_FAILURE;
942 }
943 // Skip past the EID byte and length byte - and four byte WiFi OUI
944 pRsnIe = gen_ie + 2 + 4;
945 RSNIeLen = gen_ie_len - (2 + 4);
946 // Unpack the WPA IE
947 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
948 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
949 pRsnIe,
950 RSNIeLen,
951 &dot11WPAIE);
952 // Copy out the encryption and authentication types
953 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700954 __func__, dot11WPAIE.unicast_cipher_count );
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 hddLog(LOG1, FL("%s: WPA authentication suite count: %d\n"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700956 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 //dot11WPAIE.auth_suite_count
958 // Just translate the FIRST one
959 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
960 //dot11WPAIE.unicast_cipher_count
961 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
962 //dot11WPAIE.unicast_cipher_count
963 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
964 }
965 else
966 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700967 hddLog(LOGW, FL("%s: gen_ie[0]: %d\n"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 return VOS_STATUS_E_FAILURE;
969 }
970 return VOS_STATUS_SUCCESS;
971}
972int
973static iw_softap_setparam(struct net_device *dev,
974 struct iw_request_info *info,
975 union iwreq_data *wrqu, char *extra)
976{
977 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
978 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
979 int *value = (int *)extra;
980 int sub_cmd = value[0];
981 int set_value = value[1];
982 eHalStatus status;
983 int ret = 0; /* success */
984 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
985
986 switch(sub_cmd)
987 {
988
989 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -0700990 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -0700991 {
992 ret = -EIO;
993 }
994 break;
995
996 case QCSAP_PARAM_ACL_MODE:
997 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
998 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
999 {
1000 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1001 ret = -EINVAL;
1002 }
1003 else
1004 {
1005 WLANSAP_SetMode(pVosContext, set_value);
1006 }
1007 break;
1008 case QCSAP_PARAM_MAX_ASSOC:
1009 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1010 {
1011 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1012 ret = -EINVAL;
1013 }
1014 else
1015 {
1016 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1017 {
1018 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1019 "Setting it to max allowed and continuing"),
1020 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1021 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1022 }
1023 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1024 set_value, NULL, eANI_BOOLEAN_FALSE);
1025 if ( status != eHAL_STATUS_SUCCESS )
1026 {
1027 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1028 status);
1029 ret = -EIO;
1030 }
1031 }
1032 break;
1033
1034 case QCSAP_PARAM_HIDE_SSID:
1035 {
1036 eHalStatus status = eHAL_STATUS_SUCCESS;
1037 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1038 if(eHAL_STATUS_SUCCESS != status)
1039 {
1040 hddLog(VOS_TRACE_LEVEL_ERROR,
1041 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001042 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 return status;
1044 }
1045 break;
1046 }
1047
1048 default:
1049 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1050 sub_cmd, set_value);
1051 ret = -EINVAL;
1052 break;
1053 }
1054
1055 return ret;
1056}
1057
1058
1059int
1060static iw_softap_getparam(struct net_device *dev,
1061 struct iw_request_info *info,
1062 union iwreq_data *wrqu, char *extra)
1063{
1064 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1065 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1066 int *value = (int *)extra;
1067 int sub_cmd = value[0];
1068 eHalStatus status;
1069 int ret = 0; /* success */
1070 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1071
1072 switch (sub_cmd)
1073 {
1074 case QCSAP_PARAM_MAX_ASSOC:
1075 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1076 if (eHAL_STATUS_SUCCESS != status)
1077 {
1078 ret = -EIO;
1079 }
1080 break;
1081
1082 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001083 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 {
1085 ret = -EIO;
1086 }
1087 *value = 0;
1088 break;
1089
1090 case QCSAP_PARAM_MODULE_DOWN_IND:
1091 {
1092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001093 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001094 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1095#ifdef WLAN_BTAMP_FEATURE
1096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001097 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001098 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1099#endif
1100 *value = 0;
1101 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001102 }
1103
1104 case QCSAP_PARAM_GET_WLAN_DBG:
1105 {
1106 vos_trace_display();
1107 *value = 0;
1108 break;
1109 }
1110
1111 case QCSAP_PARAM_AUTO_CHANNEL:
1112 {
1113 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1114 break;
1115 }
1116
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 default:
1118 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1119 ret = -EINVAL;
1120 break;
1121
1122 }
1123
1124 return ret;
1125}
1126
1127/* Usage:
1128 BLACK_LIST = 0
1129 WHITE_LIST = 1
1130 ADD MAC = 0
1131 REMOVE MAC = 1
1132
1133 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1134 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1135 while using this ioctl
1136
1137 Syntax:
1138 iwpriv softap.0 modify_acl
1139 <6 octet mac addr> <list type> <cmd type>
1140
1141 Examples:
1142 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1143 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1144 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1145 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1146*/
1147int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1148 union iwreq_data *wrqu, char *extra)
1149{
1150 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1151 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1152 v_BYTE_t *value = (v_BYTE_t*)extra;
1153 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1154 int listType, cmd, i;
1155 int ret = 0; /* success */
1156
1157 ENTER();
1158 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1159 {
1160 pPeerStaMac[i] = *(value+i);
1161 }
1162 listType = (int)(*(value+i));
1163 i++;
1164 cmd = (int)(*(value+i));
1165
1166 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 -07001167 __func__, pPeerStaMac[0], pPeerStaMac[1], pPeerStaMac[2],
Jeff Johnson295189b2012-06-20 16:38:30 -07001168 pPeerStaMac[3], pPeerStaMac[4], pPeerStaMac[5], listType, cmd);
1169
1170 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1171 != VOS_STATUS_SUCCESS)
1172 {
1173 hddLog(LOGE, FL("Modify ACL failed\n"));
1174 ret = -EIO;
1175 }
1176 EXIT();
1177 return ret;
1178}
1179
1180int
1181static iw_softap_getchannel(struct net_device *dev,
1182 struct iw_request_info *info,
1183 union iwreq_data *wrqu, char *extra)
1184{
1185 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1186
Jeff Johnson43971f52012-07-17 12:26:56 -07001187 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001188
Jeff Johnson43971f52012-07-17 12:26:56 -07001189 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 return 0;
1191}
1192
Jeff Johnsone7245742012-09-05 17:12:55 -07001193int
1194static iw_softap_set_tx_power(struct net_device *dev,
1195 struct iw_request_info *info,
1196 union iwreq_data *wrqu, char *extra)
1197{
1198 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1199 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1200 int cmd_len = wrqu->data.length;
1201 int *value = (int *) kmalloc(cmd_len+1, GFP_KERNEL);
1202 int set_value;
1203 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1204 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1205
1206 if(value == NULL)
1207 return -ENOMEM;
1208
1209 if(copy_from_user((char *) value, (char*)(wrqu->data.pointer), cmd_len)) {
1210 hddLog(VOS_TRACE_LEVEL_FATAL, "%s -- copy_from_user --data pointer failed! bailing",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001211 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001212 kfree(value);
1213 return -EFAULT;
1214 }
1215
1216 set_value = value[0];
1217 kfree(value);
1218
1219 if( sme_SetMaxTxPower(hHal, bssid, selfMac, set_value) !=
1220 eHAL_STATUS_SUCCESS )
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
1223 __func__);
1224 return -EIO;
1225 }
1226
1227 return 0;
1228}
1229
Jeff Johnson295189b2012-06-20 16:38:30 -07001230#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1231
1232int
1233static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1234 struct iw_request_info *info,
1235 union iwreq_data *wrqu, char *extra)
1236{
1237 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1238 unsigned char *pmaclist;
1239 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
1240 int cnt = 0, len;
1241
1242
1243 pmaclist = wrqu->data.pointer + sizeof(unsigned long int);
1244 len = wrqu->data.length;
1245
1246 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
1247 while((cnt < WLAN_MAX_STA_COUNT) && (len > (sizeof(v_MACADDR_t)+1))) {
1248 if (TRUE == pStaInfo[cnt].isUsed) {
1249
1250 if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
1251 memcpy((void *)pmaclist, (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t));
1252 pmaclist += sizeof(v_MACADDR_t);
1253 len -= sizeof(v_MACADDR_t);
1254 }
1255 }
1256 cnt++;
1257 }
1258 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
1259
1260 *pmaclist = '\0';
1261
1262 wrqu->data.length -= len;
1263
1264 *(unsigned long int *)(wrqu->data.pointer) = wrqu->data.length;
1265
1266 return 0;
1267}
1268
1269/* Usage:
1270 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1271 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1272 while using this ioctl
1273
1274 Syntax:
1275 iwpriv softap.0 disassoc_sta <6 octet mac address>
1276
1277 e.g.
1278 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1279 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1280*/
1281
1282int
1283static iw_softap_disassoc_sta(struct net_device *dev,
1284 struct iw_request_info *info,
1285 union iwreq_data *wrqu, char *extra)
1286{
1287 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1288 v_U8_t *peerMacAddr;
1289
1290 ENTER();
1291 /* the comparison below is needed since if iwpriv tool is used for calling this ioctl
1292 * data is passed in extra (less than 16 octets); however in android wifi framework
1293 * data is placed in wrqu->data.pointer.
1294 */
1295 if ((v_U8_t*)wrqu == (v_U8_t*)extra)
1296 peerMacAddr = (v_U8_t *)(extra);
1297 else
1298 peerMacAddr = (v_U8_t *)(wrqu->data.pointer);
1299
1300 hddLog(LOG1, "data %02x:%02x:%02x:%02x:%02x:%02x",
1301 peerMacAddr[0], peerMacAddr[1], peerMacAddr[2],
1302 peerMacAddr[3], peerMacAddr[4], peerMacAddr[5]);
1303 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1304 EXIT();
1305 return 0;
1306}
1307
1308int
1309static iw_softap_ap_stats(struct net_device *dev,
1310 struct iw_request_info *info,
1311 union iwreq_data *wrqu, char *extra)
1312{
1313 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1314 WLANTL_TRANSFER_STA_TYPE statBuffer;
1315 char *pstatbuf;
1316 int len = wrqu->data.length;
1317 pstatbuf = wrqu->data.pointer;
1318
1319 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &statBuffer, (v_BOOL_t)wrqu->data.flags);
1320
1321 len = snprintf(pstatbuf, len,
1322 "RUF=%d RMF=%d RBF=%d "
1323 "RUB=%d RMB=%d RBB=%d "
1324 "TUF=%d TMF=%d TBF=%d "
1325 "TUB=%d TMB=%d TBB=%d",
1326 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, (int)statBuffer.rxBCFcnt,
1327 (int)statBuffer.rxUCBcnt, (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1328 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, (int)statBuffer.txBCFcnt,
1329 (int)statBuffer.txUCBcnt, (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt
1330 );
1331
1332 wrqu->data.length -= len;
1333 return 0;
1334}
1335
1336int
1337static iw_softap_commit(struct net_device *dev,
1338 struct iw_request_info *info,
1339 union iwreq_data *wrqu, char *extra)
1340{
1341 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1342 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1343 hdd_hostapd_state_t *pHostapdState;
1344 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1345 tpWLAN_SAPEventCB pSapEventCallback;
1346 tsap_Config_t *pConfig;
1347 s_CommitConfig_t *pCommitConfig;
1348 struct qc_mac_acl_entry *acl_entry = NULL;
1349 v_SINT_t i = 0, num_mac = 0;
1350 v_U32_t status = 0;
1351 eCsrAuthType RSNAuthType;
1352 eCsrEncryptionType RSNEncryptType;
1353 eCsrEncryptionType mcRSNEncryptType;
1354
1355 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1356 pCommitConfig = (s_CommitConfig_t *)extra;
1357
1358 pConfig = kmalloc(sizeof(tsap_Config_t), GFP_KERNEL);
1359 if(NULL == pConfig) {
1360 hddLog(LOG1, "VOS unable to allocate memory\n");
1361 return -ENOMEM;
1362 }
1363 pConfig->beacon_int = pCommitConfig->beacon_int;
1364 pConfig->channel = pCommitConfig->channel;
1365
1366 /*Protection parameter to enable or disable*/
1367 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1368 pConfig->dtim_period = pCommitConfig->dtim_period;
1369 switch(pCommitConfig->hw_mode )
1370 {
1371 case eQC_DOT11_MODE_11A:
1372 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
1373 break;
1374 case eQC_DOT11_MODE_11B:
1375 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
1376 break;
1377 case eQC_DOT11_MODE_11G:
1378 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
1379 break;
1380
1381 case eQC_DOT11_MODE_11N:
1382 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1383 break;
1384 case eQC_DOT11_MODE_11G_ONLY:
1385 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1386 break;
1387 case eQC_DOT11_MODE_11N_ONLY:
1388 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
1389 break;
1390 default:
1391 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1392 break;
1393
1394 }
1395
1396 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
1397 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
1398 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
1399 pConfig->authType = eSAP_SHARED_KEY;
1400 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
1401 pConfig->authType = eSAP_OPEN_SYSTEM;
1402 else
1403 pConfig->authType = eSAP_AUTO_SWITCH;
1404
1405 pConfig->privacy = pCommitConfig->privacy;
1406 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
1407 pConfig->wps_state = pCommitConfig->wps_state;
1408 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1409 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
1410 if(pConfig->RSNWPAReqIELength){
1411 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
1412 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
1413 // The actual processing may eventually be more extensive than this.
1414 // Right now, just consume any PMKIDs that are sent in by the app.
1415 status = hdd_softap_unpackIE(
1416#if defined(FEATURE_WLAN_NON_INTEGRATED_SOC)
1417 vos_get_context( VOS_MODULE_ID_HAL, pVosContext),
1418#else
1419 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
1420#endif
1421 &RSNEncryptType,
1422 &mcRSNEncryptType,
1423 &RSNAuthType,
1424 pConfig->pRSNWPAReqIE[1]+2,
1425 pConfig->pRSNWPAReqIE );
1426
1427 if( VOS_STATUS_SUCCESS == status )
1428 {
1429 // Now copy over all the security attributes you have parsed out
1430 //TODO: Need to handle mixed mode
1431 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1432 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1433 hddLog( LOG1, FL("%s: CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d\n"),
1434 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1435 }
1436 }
1437 }
1438 else
1439 {
1440 /* If no RSNIE, set encrypt type to NONE*/
1441 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1442 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1443 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d\n"),
1444 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
1445 }
1446
1447 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
1448 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
1449 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
1450 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1451
1452 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
1453
1454 // ht_capab is not what the name conveys,this is used for protection bitmap
1455 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1456
1457 if (pCommitConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1458 num_mac = pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1459 else
1460 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
1461 acl_entry = pCommitConfig->accept_mac;
1462 for (i = 0; i < num_mac; i++)
1463 {
1464 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1465 acl_entry++;
1466 }
1467 if (pCommitConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1468 num_mac = pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1469 else
1470 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
1471 acl_entry = pCommitConfig->deny_mac;
1472 for (i = 0; i < num_mac; i++)
1473 {
1474 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1475 acl_entry++;
1476 }
1477 //Uapsd Enabled Bit
1478 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1479 //Enable OBSS protection
1480 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1481 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
1482
1483 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1484 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1485 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int, (int)pConfig->channel);
1486 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1487 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy, pConfig->authType);
1488 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1489 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1490 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),pConfig->protEnabled, pConfig->obssProtEnabled);
1491 hddLog(LOGW,FL("DisableIntraBssFwd = %d\n"),(WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
1492
1493 pSapEventCallback = hdd_hostapd_SAPEventCB;
1494 pConfig->persona = pHostapdAdapter->device_mode;
1495 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
1496 {
1497 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1498 }
1499
1500 kfree(pConfig);
1501
1502 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1503 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1504
1505 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1506 {
1507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos wait for single_event failed!!\n"));
1508 VOS_ASSERT(0);
1509 }
1510
1511 pHostapdState->bCommit = TRUE;
1512 if(pHostapdState->vosStatus)
1513 {
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001514 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 }
1516 else
1517 {
1518 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1519 WLANSAP_Update_WpsIe ( pVosContext );
1520 return 0;
1521 }
1522}
1523static
1524int iw_softap_setmlme(struct net_device *dev,
1525 struct iw_request_info *info,
1526 union iwreq_data *wrqu, char *extra)
1527{
1528 struct sQcSapreq_mlme *pmlme;
1529 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
1530 v_MACADDR_t destAddress;
1531 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
1532 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
1533 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
1534 switch(pmlme->im_op)
1535 {
1536 case QCSAP_MLME_AUTHORIZE:
1537 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
1538 break;
1539 case QCSAP_MLME_ASSOC:
1540 //TODO:inform to TL after associating (not needed as we do in sapCallback)
1541 break;
1542 case QCSAP_MLME_UNAUTHORIZE:
1543 //TODO: send the disassoc to station
1544 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
1545 break;
1546 case QCSAP_MLME_DISASSOC:
1547 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
1548 break;
1549 case QCSAP_MLME_DEAUTH:
1550 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
1551 break;
1552 case QCSAP_MLME_MICFAILURE:
1553 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
1554 break;
1555 default:
1556 break;
1557 }
1558 return 0;
1559}
1560
1561static int iw_softap_set_channel_range(struct net_device *dev,
1562 struct iw_request_info *info,
1563 union iwreq_data *wrqu, char *extra)
1564{
1565 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1566 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001567 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001568
1569 int *value = (int *)extra;
1570 int startChannel = value[0];
1571 int endChannel = value[1];
1572 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07001573 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07001574 int ret = 0; /* success */
1575
1576 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
1577 if(status != VOS_STATUS_SUCCESS)
1578 {
1579 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d\n"),
1580 startChannel,endChannel, band);
1581 ret = -EINVAL;
1582 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08001583
1584 pHddCtx->is_dynamic_channel_range_set = 1;
1585
Jeff Johnson295189b2012-06-20 16:38:30 -07001586 return ret;
1587}
1588
1589int iw_softap_get_channel_list(struct net_device *dev,
1590 struct iw_request_info *info,
1591 union iwreq_data *wrqu, char *extra)
1592{
1593 v_U32_t num_channels = 0;
1594 v_U8_t i = 0;
1595 v_U8_t bandStartChannel = RF_CHAN_1;
1596 v_U8_t bandEndChannel = RF_CHAN_165;
1597 v_U32_t temp_num_channels = 0;
1598 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001599 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001600 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1601 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001603 eCsrBand curBand = eCSR_BAND_ALL;
1604
1605 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
1606 {
1607 hddLog(LOGE,FL("not able get the current frequency band\n"));
1608 return -EIO;
1609 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001610 wrqu->data.length = sizeof(tChannelListInfo);
1611 ENTER();
1612
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07001613 if (eCSR_BAND_24 == curBand)
1614 {
1615 bandStartChannel = RF_CHAN_1;
1616 bandEndChannel = RF_CHAN_14;
1617 }
1618 else if (eCSR_BAND_5G == curBand)
1619 {
1620 bandStartChannel = RF_CHAN_36;
1621 bandEndChannel = RF_CHAN_165;
1622 }
1623
1624 hddLog(LOG1, FL("\n nBandCapability = %d, bandStartChannel = %hu, "
1625 "bandEndChannel = %hu \n"), pHddCtx->cfg_ini->nBandCapability,
1626 bandStartChannel, bandEndChannel );
1627
Jeff Johnson295189b2012-06-20 16:38:30 -07001628 for( i = bandStartChannel; i <= bandEndChannel; i++ )
1629 {
1630 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
1631 {
1632 channel_list->channels[num_channels] = rfChannels[i].channelNum;
1633 num_channels++;
1634 }
1635 }
1636
1637 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
1638
1639 temp_num_channels = num_channels;
1640
1641 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
1642 {
1643 hddLog(LOG1,FL("Failed to get Domain ID, %d \n"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001644 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 }
1646
1647 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
1648 {
1649 for(i = 0; i < temp_num_channels; i++)
1650 {
1651
1652 if((channel_list->channels[i] > 35) &&
1653 (channel_list->channels[i] < 49))
1654 {
1655 vos_mem_move(&channel_list->channels[i],
1656 &channel_list->channels[i+1],
1657 temp_num_channels - (i-1));
1658 num_channels--;
1659 temp_num_channels--;
1660 i--;
1661 }
1662 }
1663 }
1664
1665 hddLog(LOG1,FL(" number of channels %d\n"), num_channels);
1666
1667 if (num_channels > IW_MAX_FREQUENCIES)
1668 {
1669 num_channels = IW_MAX_FREQUENCIES;
1670 }
1671
1672 channel_list->num_channels = num_channels;
1673 EXIT();
1674
1675 return 0;
1676}
1677
1678static
1679int iw_get_genie(struct net_device *dev,
1680 struct iw_request_info *info,
1681 union iwreq_data *wrqu, char *extra)
1682{
1683 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1684 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1685 eHalStatus status;
1686 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
1687 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
1688 ENTER();
1689 hddLog(LOG1,FL("getGEN_IE ioctl\n"));
1690 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
1691 status = WLANSap_getstationIE_information(pVosContext,
1692 &length,
1693 genIeBytes);
1694 wrqu->data.length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
1695 vos_mem_copy( wrqu->data.pointer, (v_VOID_t*)genIeBytes, wrqu->data.length);
1696
1697 hddLog(LOG1,FL(" RSN IE of %d bytes returned\n"), wrqu->data.length );
1698
1699
1700 EXIT();
1701 return 0;
1702}
1703static
1704int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
1705 struct iw_request_info *info,
1706 union iwreq_data *wrqu, char *extra)
1707{
1708 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1709 sQcSapreq_WPSPBCProbeReqIES_t *pWPSPBCProbeReqIEs;
1710 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1711 ENTER();
1712
1713 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl\n"));
1714
1715 pWPSPBCProbeReqIEs = (sQcSapreq_WPSPBCProbeReqIES_t *)(wrqu->data.pointer);
1716 pWPSPBCProbeReqIEs->probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
1717 vos_mem_copy(pWPSPBCProbeReqIEs->probeReqIE, pHddApCtx->WPSPBCProbeReq.probeReqIE, pWPSPBCProbeReqIEs->probeReqIELen);
1718 vos_mem_copy(pWPSPBCProbeReqIEs->macaddr, pHddApCtx->WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
1719 wrqu->data.length = 12 + pWPSPBCProbeReqIEs->probeReqIELen;
1720 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pWPSPBCProbeReqIEs->macaddr));
1721 up(&pHddApCtx->semWpsPBCOverlapInd);
1722 EXIT();
1723 return 0;
1724}
1725
1726/**---------------------------------------------------------------------------
1727
1728 \brief iw_set_auth_hostap() -
1729 This function sets the auth type received from the wpa_supplicant.
1730
1731 \param - dev - Pointer to the net device.
1732 - info - Pointer to the iw_request_info.
1733 - wrqu - Pointer to the iwreq_data.
1734 - extra - Pointer to the data.
1735 \return - 0 for success, non zero for failure
1736
1737 --------------------------------------------------------------------------*/
1738int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
1739 union iwreq_data *wrqu,char *extra)
1740{
1741 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1742 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1743
1744 ENTER();
1745 switch(wrqu->param.flags & IW_AUTH_INDEX)
1746 {
1747 case IW_AUTH_TKIP_COUNTERMEASURES:
1748 {
1749 if(wrqu->param.value) {
1750 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1751 "Counter Measure started %d", wrqu->param.value);
1752 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
1753 }
1754 else {
1755 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1756 "Counter Measure stopped=%d", wrqu->param.value);
1757 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
1758 }
1759
1760 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
1761 wrqu->param.value);
1762 }
1763 break;
1764
1765 default:
1766
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001767 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 wrqu->param.flags & IW_AUTH_INDEX);
1769 break;
1770 }
1771
1772 EXIT();
1773 return 0;
1774}
1775
1776static int iw_set_ap_encodeext(struct net_device *dev,
1777 struct iw_request_info *info,
1778 union iwreq_data *wrqu, char *extra)
1779{
1780 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1781 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1782 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07001783 int retval = 0;
1784 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1786 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1787 int key_index;
1788 struct iw_point *encoding = &wrqu->encoding;
1789 tCsrRoamSetKey setKey;
1790// tCsrRoamRemoveKey RemoveKey;
1791 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07001792
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 ENTER();
1794
1795 key_index = encoding->flags & IW_ENCODE_INDEX;
1796
1797 if(key_index > 0) {
1798
1799 /*Convert from 1-based to 0-based keying*/
1800 key_index--;
1801 }
1802 if(!ext->key_len) {
1803#if 0
1804 /*Set the encrytion type to NONE*/
1805#if 0
1806 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
1807#endif
1808
1809 RemoveKey.keyId = key_index;
1810 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1811 /*Key direction for group is RX only*/
1812 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1813 }
1814 else {
1815 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1816 }
1817 switch(ext->alg)
1818 {
1819 case IW_ENCODE_ALG_NONE:
1820 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1821 break;
1822 case IW_ENCODE_ALG_WEP:
1823 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1824 break;
1825 case IW_ENCODE_ALG_TKIP:
1826 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07001827 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001828 case IW_ENCODE_ALG_CCMP:
1829 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
1830 break;
1831 default:
1832 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1833 break;
1834 }
1835 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 -07001836 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001837 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 -07001838 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 );
Jeff Johnson43971f52012-07-17 12:26:56 -07001840 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
1841 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07001842 {
1843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07001844 __LINE__, vstatus );
1845 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001846 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001847#endif
1848 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07001849
Jeff Johnson43971f52012-07-17 12:26:56 -07001850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001851
1852 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
1853
1854 setKey.keyId = key_index;
1855 setKey.keyLength = ext->key_len;
1856
1857 if(ext->key_len <= CSR_MAX_KEY_LEN) {
1858 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
1859 }
1860
1861 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1862 /*Key direction for group is RX only*/
1863 setKey.keyDirection = eSIR_RX_ONLY;
1864 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1865 }
1866 else {
1867
1868 setKey.keyDirection = eSIR_TX_RX;
1869 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1870 }
1871 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1872 {
1873 setKey.keyDirection = eSIR_TX_DEFAULT;
1874 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1875 }
1876
1877 /*For supplicant pae role is zero*/
1878 setKey.paeRole = 0;
1879
1880 switch(ext->alg)
1881 {
1882 case IW_ENCODE_ALG_NONE:
1883 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1884 break;
1885
1886 case IW_ENCODE_ALG_WEP:
1887 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1888 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001889 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 break;
1891
1892 case IW_ENCODE_ALG_TKIP:
1893 {
1894 v_U8_t *pKey = &setKey.Key[0];
1895
1896 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
1897
1898 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
1899
1900 /*Supplicant sends the 32bytes key in this order
1901
1902 |--------------|----------|----------|
1903 | Tk1 |TX-MIC | RX Mic |
1904 |--------------|----------|----------|
1905 <---16bytes---><--8bytes--><--8bytes-->
1906
1907 */
1908 /*Sme expects the 32 bytes key to be in the below order
1909
1910 |--------------|----------|----------|
1911 | Tk1 |RX-MIC | TX Mic |
1912 |--------------|----------|----------|
1913 <---16bytes---><--8bytes--><--8bytes-->
1914 */
1915 /* Copy the Temporal Key 1 (TK1) */
1916 vos_mem_copy(pKey,ext->key,16);
1917
1918 /*Copy the rx mic first*/
1919 vos_mem_copy(&pKey[16],&ext->key[24],8);
1920
1921 /*Copy the tx mic */
1922 vos_mem_copy(&pKey[24],&ext->key[16],8);
1923
1924 }
1925 break;
1926
1927 case IW_ENCODE_ALG_CCMP:
1928 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
1929 break;
1930
1931 default:
1932 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1933 break;
1934 }
1935
1936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001937 ("%s:EncryptionType:%d key_len:%d, :%d, KeyId:%d \n"),__func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 setKey.keyId);
1939 for(i=0; i< ext->key_len; i++)
1940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1941 ("%02x"), setKey.Key[i]);
1942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1943 ("\n"));
Jeff Johnson43971f52012-07-17 12:26:56 -07001944
1945 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
1946 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 {
1948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07001949 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
1950 retval = -EINVAL;
1951 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001952
Jeff Johnson43971f52012-07-17 12:26:56 -07001953 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07001954}
Jeff Johnson43971f52012-07-17 12:26:56 -07001955
1956
Jeff Johnson295189b2012-06-20 16:38:30 -07001957static int iw_set_ap_mlme(struct net_device *dev,
1958 struct iw_request_info *info,
1959 union iwreq_data *wrqu,
1960 char *extra)
1961{
1962#if 0
1963 hdd_adapter_t *pAdapter = (netdev_priv(dev));
1964 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1965
1966 ENTER();
1967
1968 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
1969 switch (mlme->cmd) {
1970 case IW_MLME_DISASSOC:
1971 case IW_MLME_DEAUTH:
1972 hddLog(LOG1, "Station disassociate");
1973 if( pAdapter->conn_info.connState == eConnectionState_Associated )
1974 {
1975 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
1976
1977 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
1978 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
1979
1980 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
1981
1982 //clear all the reason codes
1983 if (status != 0)
1984 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001985 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 -07001986 }
1987
1988 netif_stop_queue(dev);
1989 netif_carrier_off(dev);
1990 }
1991 else
1992 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001993 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 -07001994 }
1995 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001996 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate \n", __func__, (int)mlme->cmd );
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 return -EINVAL;
1998 }//end of switch
1999 EXIT();
2000#endif
2001 return 0;
2002// return status;
2003}
2004
2005static int iw_get_ap_rts_threshold(struct net_device *dev,
2006 struct iw_request_info *info,
2007 union iwreq_data *wrqu, char *extra)
2008{
2009 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2010 v_U32_t status = 0;
2011
2012 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2013
2014 return status;
2015}
2016
2017static int iw_get_ap_frag_threshold(struct net_device *dev,
2018 struct iw_request_info *info,
2019 union iwreq_data *wrqu, char *extra)
2020{
2021 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2022 v_U32_t status = 0;
2023
2024 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2025
2026 return status;
2027}
2028
2029static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2030 struct iw_freq *fwrq, char *extra)
2031{
Jeff Johnsone7245742012-09-05 17:12:55 -07002032 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2034 tHalHandle hHal;
2035 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002036 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002037
2038 ENTER();
2039
2040 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2042 "%s:LOGP in Progress. Ignore!!!",__func__);
2043 return status;
2044 }
2045
2046 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2047 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2048
2049 if(pHostapdState->bssState == BSS_STOP )
2050 {
2051 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2052 != eHAL_STATUS_SUCCESS)
2053 {
2054 return -EIO;
2055 }
2056 else
2057 {
2058 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002059 if( TRUE == status)
2060 {
2061 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2062 * iwlist & iwconfig command shows frequency into proper
2063 * format (2.412 GHz instead of 246.2 MHz)*/
2064 fwrq->m = freq;
2065 fwrq->e = MHZ;
2066 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 }
2068 }
2069 else
2070 {
2071 channel = pHddApCtx->operatingChannel;
2072 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002073 if( TRUE == status)
2074 {
2075 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2076 * iwlist & iwconfig command shows frequency into proper
2077 * format (2.412 GHz instead of 246.2 MHz)*/
2078 fwrq->m = freq;
2079 fwrq->e = MHZ;
2080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002082 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002083}
2084
2085static int iw_softap_setwpsie(struct net_device *dev,
2086 struct iw_request_info *info,
2087 union iwreq_data *wrqu,
2088 char *extra)
2089{
2090 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2091 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2092 hdd_hostapd_state_t *pHostapdState;
2093 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2094 u_int8_t *wps_genie = wrqu->data.pointer;
2095 u_int8_t *pos;
2096 tpSap_WPSIE pSap_WPSIe;
2097 u_int8_t WPSIeType;
2098 u_int16_t length;
2099 ENTER();
2100
2101 if(!wrqu->data.length)
2102 return 0;
2103
2104 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2105 if (NULL == pSap_WPSIe)
2106 {
2107 hddLog(LOGE, "VOS unable to allocate memory\n");
2108 return -ENOMEM;
2109 }
2110 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2111
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002112 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 -07002113 WPSIeType = wps_genie[0];
2114 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2115 {
2116 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2117 wps_genie = wps_genie + 1;
2118 switch ( wps_genie[0] )
2119 {
2120 case DOT11F_EID_WPA:
2121 if (wps_genie[1] < 2 + 4)
2122 {
2123 vos_mem_free(pSap_WPSIe);
2124 return -EINVAL;
2125 }
2126 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2127 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002128 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 pos = &wps_genie[6];
2130 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2131 {
2132 switch((u_int16_t)(*pos<<8) | *(pos+1))
2133 {
2134 case HDD_WPS_ELEM_VERSION:
2135 pos += 4;
2136 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
2137 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
2138 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2139 pos += 1;
2140 break;
2141
2142 case HDD_WPS_ELEM_WPS_STATE:
2143 pos +=4;
2144 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
2145 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
2146 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2147 pos += 1;
2148 break;
2149 case HDD_WPS_ELEM_APSETUPLOCK:
2150 pos += 4;
2151 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
2152 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
2153 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2154 pos += 1;
2155 break;
2156 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2157 pos += 4;
2158 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
2159 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
2160 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2161 pos += 1;
2162 break;
2163 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2164 pos += 4;
2165 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2166 hddLog(LOG1, "Password ID: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
2167 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2168 pos += 2;
2169 break;
2170 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2171 pos += 4;
2172 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2173 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
2174 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2175 pos += 2;
2176 break;
2177
2178 case HDD_WPS_ELEM_UUID_E:
2179 pos += 2;
2180 length = *pos<<8 | *(pos+1);
2181 pos += 2;
2182 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2183 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2184 pos += length;
2185 break;
2186 case HDD_WPS_ELEM_RF_BANDS:
2187 pos += 4;
2188 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
2189 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
2190 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2191 pos += 1;
2192 break;
2193
2194 default:
2195 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)\n", (*pos<<8 | *(pos+1)));
2196 vos_mem_free(pSap_WPSIe);
2197 return -EINVAL;
2198 }
2199 }
2200 }
2201 else {
2202 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002203 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 }
2205 break;
2206
2207 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002208 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 vos_mem_free(pSap_WPSIe);
2210 return 0;
2211 }
2212 }
2213 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2214 {
2215 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2216 wps_genie = wps_genie + 1;
2217 switch ( wps_genie[0] )
2218 {
2219 case DOT11F_EID_WPA:
2220 if (wps_genie[1] < 2 + 4)
2221 {
2222 vos_mem_free(pSap_WPSIe);
2223 return -EINVAL;
2224 }
2225 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2226 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002227 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 pos = &wps_genie[6];
2229 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2230 {
2231 switch((u_int16_t)(*pos<<8) | *(pos+1))
2232 {
2233 case HDD_WPS_ELEM_VERSION:
2234 pos += 4;
2235 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
2236 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
2237 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2238 pos += 1;
2239 break;
2240
2241 case HDD_WPS_ELEM_WPS_STATE:
2242 pos +=4;
2243 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
2244 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
2245 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2246 pos += 1;
2247 break;
2248 case HDD_WPS_ELEM_APSETUPLOCK:
2249 pos += 4;
2250 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
2251 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
2252 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2253 pos += 1;
2254 break;
2255 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2256 pos += 4;
2257 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
2258 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
2259 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2260 pos += 1;
2261 break;
2262 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2263 pos += 4;
2264 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2265 hddLog(LOG1, "Password ID: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
2266 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2267 pos += 2;
2268 break;
2269 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2270 pos += 4;
2271 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2272 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2273 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2274 pos += 2;
2275 break;
2276 case HDD_WPS_ELEM_RSP_TYPE:
2277 pos += 4;
2278 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
2279 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
2280 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2281 pos += 1;
2282 break;
2283 case HDD_WPS_ELEM_UUID_E:
2284 pos += 2;
2285 length = *pos<<8 | *(pos+1);
2286 pos += 2;
2287 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2288 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2289 pos += length;
2290 break;
2291
2292 case HDD_WPS_ELEM_MANUFACTURER:
2293 pos += 2;
2294 length = *pos<<8 | *(pos+1);
2295 pos += 2;
2296 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2297 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2298 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2299 pos += length;
2300 break;
2301
2302 case HDD_WPS_ELEM_MODEL_NAME:
2303 pos += 2;
2304 length = *pos<<8 | *(pos+1);
2305 pos += 2;
2306 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2307 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2308 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2309 pos += length;
2310 break;
2311 case HDD_WPS_ELEM_MODEL_NUM:
2312 pos += 2;
2313 length = *pos<<8 | *(pos+1);
2314 pos += 2;
2315 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2316 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2317 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2318 pos += length;
2319 break;
2320 case HDD_WPS_ELEM_SERIAL_NUM:
2321 pos += 2;
2322 length = *pos<<8 | *(pos+1);
2323 pos += 2;
2324 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2325 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2326 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2327 pos += length;
2328 break;
2329 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2330 pos += 4;
2331 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
2332 hddLog(LOG1, "primary dev category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
2333 pos += 2;
2334
2335 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
2336 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x\n", pos[0], pos[1], pos[2], pos[3]);
2337 pos += 4;
2338 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
2339 hddLog(LOG1, "primary dev sub category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
2340 pos += 2;
2341 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2342 break;
2343 case HDD_WPS_ELEM_DEVICE_NAME:
2344 pos += 2;
2345 length = *pos<<8 | *(pos+1);
2346 pos += 2;
2347 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2348 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2349 pos += length;
2350 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2351 break;
2352 case HDD_WPS_ELEM_CONFIG_METHODS:
2353 pos += 4;
2354 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
2355 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2356 pos += 2;
2357 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2358 break;
2359
2360 case HDD_WPS_ELEM_RF_BANDS:
2361 pos += 4;
2362 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
2363 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
2364 pos += 1;
2365 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2366 break;
2367 } // switch
2368 }
2369 }
2370 else
2371 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002372 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002373 }
2374
2375 } // switch
2376 }
2377 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2378 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2379 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2380 {
2381 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2382 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2383 WLANSAP_Update_WpsIe ( pVosContext );
2384 }
2385
2386 vos_mem_free(pSap_WPSIe);
2387 EXIT();
2388 return halStatus;
2389}
2390
2391static int iw_softap_stopbss(struct net_device *dev,
2392 struct iw_request_info *info,
2393 union iwreq_data *wrqu,
2394 char *extra)
2395{
2396 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2397 VOS_STATUS status = VOS_STATUS_SUCCESS;
2398 ENTER();
2399 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2400 {
2401 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2402 {
2403 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2404
2405 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2406
2407 if (!VOS_IS_STATUS_SUCCESS(status))
2408 {
2409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 ("ERROR: HDD vos wait for single_event failed!!\n"));
2411 VOS_ASSERT(0);
2412 }
2413 }
2414 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2415 }
2416 EXIT();
2417 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2418}
2419
2420static int iw_softap_version(struct net_device *dev,
2421 struct iw_request_info *info,
2422 union iwreq_data *wrqu,
2423 char *extra)
2424{
2425#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
2426 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2427 VOS_STATUS status;
2428 ENTER();
2429 status = hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
2430 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
2431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n",__func__);
2432 return -EINVAL;
2433 }
2434 EXIT();
2435#endif//TODO need to handle in prima
2436 return 0;
2437}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002438
2439VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf)
2440{
2441 v_U8_t i;
2442
2443 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2444 {
2445 if(pAdapter->aStaInfo[i].isUsed)
2446 {
2447 pBuf += snprintf(pBuf, WE_GET_STA_INFO_SIZE, "staIndex = %d staAddress =.%02x:%02x:%02x:%02x:%02x:%02x\n",
2448 pAdapter->aStaInfo[i].ucSTAId,
2449 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
2450 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
2451 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
2452 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
2453 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
2454 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
2455 }
2456 }
2457 return VOS_STATUS_SUCCESS;
2458}
2459
2460static int iw_softap_get_sta_info(struct net_device *dev,
2461 struct iw_request_info *info,
2462 union iwreq_data *wrqu,
2463 char *extra)
2464{
2465 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2466 VOS_STATUS status;
2467 ENTER();
2468 status = hdd_softap_get_sta_info(pHostapdAdapter, extra);
2469 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
2470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n",__func__);
2471 return -EINVAL;
2472 }
2473 wrqu->data.length = strlen(extra);
2474 EXIT();
2475 return 0;
2476}
2477
Jeff Johnson295189b2012-06-20 16:38:30 -07002478static int iw_set_ap_genie(struct net_device *dev,
2479 struct iw_request_info *info,
2480 union iwreq_data *wrqu,
2481 char *extra)
2482{
2483
2484 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2485 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2486 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2487 u_int8_t *genie = wrqu->data.pointer;
2488
2489 ENTER();
2490
2491 if(!wrqu->data.length)
2492 {
2493 EXIT();
2494 return 0;
2495 }
2496
2497 switch (genie[0])
2498 {
2499 case DOT11F_EID_WPA:
2500 case DOT11F_EID_RSN:
2501 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
2502 {
2503 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
2504 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
2505 }
2506 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
2507 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, wrqu->data.pointer, wrqu->data.length);
2508 break;
2509
2510 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002511 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 halStatus = 0;
2513 }
2514
2515 EXIT();
2516 return halStatus;
2517}
2518
2519static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
2520{
2521 eHalStatus hstatus;
2522 long lrc;
2523 struct statsContext context;
2524
2525 if (NULL == pAdapter)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Padapter is NULL", __func__);
2528 return VOS_STATUS_E_FAULT;
2529 }
2530
2531 init_completion(&context.completion);
2532 context.pAdapter = pAdapter;
2533 context.magic = STATS_CONTEXT_MAGIC;
2534 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
2535 eCSR_HDD,
2536 SME_GLOBAL_CLASSA_STATS,
2537 hdd_GetClassA_statisticsCB,
2538 0, // not periodic
2539 FALSE, //non-cached results
2540 staid,
2541 &context);
2542 if (eHAL_STATUS_SUCCESS != hstatus)
2543 {
2544 hddLog(VOS_TRACE_LEVEL_ERROR,
2545 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002546 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 }
2548 else
2549 {
2550 lrc = wait_for_completion_interruptible_timeout(&context.completion,
2551 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2552 context.magic = 0;
2553 if (lrc <= 0)
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR,
2556 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002557 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 msleep(50);
2559 }
2560 }
2561 return VOS_STATUS_SUCCESS;
2562}
2563
2564int iw_get_softap_linkspeed(struct net_device *dev,
2565 struct iw_request_info *info,
2566 union iwreq_data *wrqu,
2567 char *extra)
2568
2569{
2570 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2571 char *pLinkSpeed = (char*)extra;
2572 v_U16_t link_speed;
2573 unsigned short staId;
2574 int len = sizeof(v_U16_t)+1;
2575 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
2576 VOS_STATUS status;
2577 int rc;
2578
2579 if ( hdd_string_to_hex ((char *)wrqu->data.pointer, wrqu->data.length, macAddress ) )
2580 {
2581 hddLog(VOS_TRACE_LEVEL_FATAL, "ERROR: Command not found");
2582 return -EINVAL;
2583 }
2584
2585 status = hdd_softap_GetStaId(pHostapdAdapter, (v_MACADDR_t *)macAddress, (void *)(&staId));
2586
2587 if (!VOS_IS_STATUS_SUCCESS(status ))
2588 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002589 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 -07002590 link_speed = 0;
2591 }
2592 else
2593 {
2594 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
2595 if (!VOS_IS_STATUS_SUCCESS(status ))
2596 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve SME statistics", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 return -EINVAL;
2599 }
2600 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
2601 }
2602
2603 wrqu->data.length = len;
2604 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
2605 if ((rc < 0) || (rc >= len))
2606 {
2607 // encoding or length error?
2608 hddLog(VOS_TRACE_LEVEL_ERROR,
2609 "%s: Unable to encode link speed, got [%s]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002610 __func__, pLinkSpeed);
Jeff Johnson295189b2012-06-20 16:38:30 -07002611 return -EIO;
2612 }
2613
2614 return 0;
2615}
2616
2617static const iw_handler hostapd_handler[] =
2618{
2619 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2620 (iw_handler) NULL, /* SIOCGIWNAME */
2621 (iw_handler) NULL, /* SIOCSIWNWID */
2622 (iw_handler) NULL, /* SIOCGIWNWID */
2623 (iw_handler) NULL, /* SIOCSIWFREQ */
2624 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
2625 (iw_handler) NULL, /* SIOCSIWMODE */
2626 (iw_handler) NULL, /* SIOCGIWMODE */
2627 (iw_handler) NULL, /* SIOCSIWSENS */
2628 (iw_handler) NULL, /* SIOCGIWSENS */
2629 (iw_handler) NULL, /* SIOCSIWRANGE */
2630 (iw_handler) NULL, /* SIOCGIWRANGE */
2631 (iw_handler) NULL, /* SIOCSIWPRIV */
2632 (iw_handler) NULL, /* SIOCGIWPRIV */
2633 (iw_handler) NULL, /* SIOCSIWSTATS */
2634 (iw_handler) NULL, /* SIOCGIWSTATS */
2635 (iw_handler) NULL, /* SIOCSIWSPY */
2636 (iw_handler) NULL, /* SIOCGIWSPY */
2637 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2638 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2639 (iw_handler) NULL, /* SIOCSIWAP */
2640 (iw_handler) NULL, /* SIOCGIWAP */
2641 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
2642 (iw_handler) NULL, /* SIOCGIWAPLIST */
2643 (iw_handler) NULL, /* SIOCSIWSCAN */
2644 (iw_handler) NULL, /* SIOCGIWSCAN */
2645 (iw_handler) NULL, /* SIOCSIWESSID */
2646 (iw_handler) NULL, /* SIOCGIWESSID */
2647 (iw_handler) NULL, /* SIOCSIWNICKN */
2648 (iw_handler) NULL, /* SIOCGIWNICKN */
2649 (iw_handler) NULL, /* -- hole -- */
2650 (iw_handler) NULL, /* -- hole -- */
2651 (iw_handler) NULL, /* SIOCSIWRATE */
2652 (iw_handler) NULL, /* SIOCGIWRATE */
2653 (iw_handler) NULL, /* SIOCSIWRTS */
2654 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
2655 (iw_handler) NULL, /* SIOCSIWFRAG */
2656 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
2657 (iw_handler) NULL, /* SIOCSIWTXPOW */
2658 (iw_handler) NULL, /* SIOCGIWTXPOW */
2659 (iw_handler) NULL, /* SIOCSIWRETRY */
2660 (iw_handler) NULL, /* SIOCGIWRETRY */
2661 (iw_handler) NULL, /* SIOCSIWENCODE */
2662 (iw_handler) NULL, /* SIOCGIWENCODE */
2663 (iw_handler) NULL, /* SIOCSIWPOWER */
2664 (iw_handler) NULL, /* SIOCGIWPOWER */
2665 (iw_handler) NULL, /* -- hole -- */
2666 (iw_handler) NULL, /* -- hole -- */
2667 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
2668 (iw_handler) NULL, /* SIOCGIWGENIE */
2669 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
2670 (iw_handler) NULL, /* SIOCGIWAUTH */
2671 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
2672 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
2673 (iw_handler) NULL, /* SIOCSIWPMKSA */
2674};
2675
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002676#define IW_PRIV_TYPE_OPTIE (IW_PRIV_TYPE_BYTE | QCSAP_MAX_OPT_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002677#define IW_PRIV_TYPE_MLME \
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -08002678 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
Jeff Johnson295189b2012-06-20 16:38:30 -07002679
2680static const struct iw_priv_args hostapd_private_args[] = {
2681 { QCSAP_IOCTL_SETPARAM,
2682 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
2683 { QCSAP_IOCTL_SETPARAM,
2684 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2685 { QCSAP_PARAM_MAX_ASSOC,
2686 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
2687 { QCSAP_PARAM_HIDE_SSID,
2688 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
2689 { QCSAP_IOCTL_GETPARAM,
2690 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2691 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
2692 { QCSAP_IOCTL_GETPARAM, 0,
2693 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2694 { QCSAP_PARAM_MAX_ASSOC, 0,
2695 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07002696 { QCSAP_PARAM_GET_WLAN_DBG, 0,
2697 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
2698 { QCSAP_PARAM_AUTO_CHANNEL, 0,
2699 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002700 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
2701 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
2702 { QCSAP_PARAM_CLR_ACL, 0,
2703 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
2704 { QCSAP_PARAM_ACL_MODE,
2705 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
2706 { QCSAP_IOCTL_COMMIT,
2707 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
2708 { QCSAP_IOCTL_SETMLME,
2709 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
2710 { QCSAP_IOCTL_GET_STAWPAIE,
2711 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
2712 { QCSAP_IOCTL_SETWPAIE,
2713 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
2714 { QCSAP_IOCTL_STOPBSS,
2715 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
2716 { QCSAP_IOCTL_VERSION, 0,
2717 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002718 { QCSAP_IOCTL_GET_STA_INFO, 0,
2719 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002720 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
2721 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED | 1, 0, "getProbeReqIEs" },
2722 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07002723 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002724 { QCSAP_IOCTL_ASSOC_STA_MACADDR, 0,
2725 IW_PRIV_TYPE_BYTE | /*((WLAN_MAX_STA_COUNT*6)+100)*/1 , "get_assoc_stamac" },
2726 { QCSAP_IOCTL_DISASSOC_STA,
2727 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
2728 { QCSAP_IOCTL_AP_STATS,
2729 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
2730 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
2731 IW_PRIV_TYPE_CHAR | 18,
2732 IW_PRIV_TYPE_CHAR | 3, "getLinkSpeed" },
2733
2734 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
2735 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
2736 /* handlers for sub-ioctl */
2737 { WE_SET_WLAN_DBG,
2738 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
2739 0,
2740 "setwlandbg" },
2741
2742 /* handlers for main ioctl */
2743 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
2744 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2745 0,
2746 "" },
2747
2748 /* handlers for sub-ioctl */
2749 { WE_LOG_DUMP_CMD,
2750 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2751 0,
2752 "dump" },
2753#ifdef WLAN_FEATURE_P2P
2754 { WE_P2P_NOA_CMD,
2755 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2756 0,
2757 "SetP2pPs" },
2758#endif
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08002759 /* handlers for sub ioctl */
2760 {
2761 WE_MCC_CONFIG_CREDENTIAL,
2762 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2763 0,
2764 "setMccCrdnl" },
2765
2766 /* handlers for sub ioctl */
2767 {
2768 WE_MCC_CONFIG_PARAMS,
2769 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2770 0,
2771 "setMccConfig" },
2772
Jeff Johnson295189b2012-06-20 16:38:30 -07002773 /* handlers for main ioctl */
2774 { QCSAP_IOCTL_MODIFY_ACL,
2775 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
2776 0,
2777 "modify_acl" },
2778
2779 /* handlers for main ioctl */
2780 { QCSAP_IOCTL_GET_CHANNEL_LIST,
2781 0,
2782 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
2783 "getChannelList" },
2784
Jeff Johnsone7245742012-09-05 17:12:55 -07002785 /* handlers for main ioctl */
2786 { QCSAP_IOCTL_SET_TX_POWER,
2787 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
2788 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05302789 "setTxPower" },
Jeff Johnson295189b2012-06-20 16:38:30 -07002790};
Jeff Johnsone7245742012-09-05 17:12:55 -07002791
Jeff Johnson295189b2012-06-20 16:38:30 -07002792static const iw_handler hostapd_private[] = {
2793 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
2794 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
2795 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
2796 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
2797 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
2798 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
2799 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
2800 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
2801 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
2802 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
2803 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
2804 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
2805 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
2806 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
2807 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
2808 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
2809 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
2810 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08002811 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07002812 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
2813 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
Jeff Johnson295189b2012-06-20 16:38:30 -07002814};
2815const struct iw_handler_def hostapd_handler_def = {
2816 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
2817 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
2818 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
2819 .standard = (iw_handler *)hostapd_handler,
2820 .private = (iw_handler *)hostapd_private,
2821 .private_args = hostapd_private_args,
2822 .get_wireless_stats = NULL,
2823};
2824#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2825struct net_device_ops net_ops_struct = {
2826 .ndo_open = hdd_hostapd_open,
2827 .ndo_stop = hdd_hostapd_stop,
2828 .ndo_uninit = hdd_hostapd_uninit,
2829 .ndo_start_xmit = hdd_softap_hard_start_xmit,
2830 .ndo_tx_timeout = hdd_softap_tx_timeout,
2831 .ndo_get_stats = hdd_softap_stats,
2832 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
2833 .ndo_do_ioctl = hdd_hostapd_ioctl,
2834 .ndo_change_mtu = hdd_hostapd_change_mtu,
2835 .ndo_select_queue = hdd_hostapd_select_queue,
2836 };
2837#endif
2838
2839int hdd_set_hostapd(hdd_adapter_t *pAdapter)
2840{
2841 return VOS_STATUS_SUCCESS;
2842}
2843
2844void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
2845{
2846#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2847 pWlanHostapdDev->netdev_ops = &net_ops_struct;
2848#else
2849 pWlanHostapdDev->open = hdd_hostapd_open;
2850 pWlanHostapdDev->stop = hdd_hostapd_stop;
2851 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
2852 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
2853 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
2854 pWlanHostapdDev->get_stats = hdd_softap_stats;
2855 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
2856 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
2857#endif
2858}
2859
2860VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
2861{
2862 hdd_hostapd_state_t * phostapdBuf;
2863 struct net_device *dev = pAdapter->dev;
2864 VOS_STATUS status;
2865 ENTER();
2866 // Allocate the Wireless Extensions state structure
2867 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
2868
2869 // Zero the memory. This zeros the profile structure.
2870 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
2871
2872 // Set up the pointer to the Wireless Extensions state structure
2873 // NOP
2874 status = hdd_set_hostapd(pAdapter);
2875 if(!VOS_IS_STATUS_SUCCESS(status)) {
2876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!\n"));
2877 return status;
2878 }
2879
2880 status = vos_event_init(&phostapdBuf->vosEvent);
2881 if (!VOS_IS_STATUS_SUCCESS(status))
2882 {
2883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!\n"));
2884 return status;
2885 }
2886
2887 init_completion(&pAdapter->session_close_comp_var);
2888 init_completion(&pAdapter->session_open_comp_var);
2889
2890 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
2891
2892 // Register as a wireless device
2893 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
2894
2895 //Initialize the data path module
2896 status = hdd_softap_init_tx_rx(pAdapter);
2897 if ( !VOS_IS_STATUS_SUCCESS( status ))
2898 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002899 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002900 }
2901
2902#ifdef CONFIG_CFG80211
2903 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
2904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002905 EXIT();
2906 return status;
2907}
2908
2909hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
2910{
2911 struct net_device *pWlanHostapdDev = NULL;
2912 hdd_adapter_t *pHostapdAdapter = NULL;
2913 v_CONTEXT_t pVosContext= NULL;
2914
2915#ifdef CONFIG_CFG80211
2916 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
2917#else
2918 pWlanHostapdDev = alloc_etherdev_mq(sizeof(hdd_adapter_t), NUM_TX_QUEUES);
2919#endif
2920
2921 if (pWlanHostapdDev != NULL)
2922 {
2923 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
2924
2925 //Init the net_device structure
2926 ether_setup(pWlanHostapdDev);
2927
2928 //Initialize the adapter context to zeros.
2929 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
2930 pHostapdAdapter->dev = pWlanHostapdDev;
2931 pHostapdAdapter->pHddCtx = pHddCtx;
2932 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
2933
2934 //Get the Global VOSS context.
2935 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2936 //Save the adapter context in global context for future.
2937 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
2938
2939 //Init the net_device structure
2940 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
2941
2942 hdd_set_ap_ops( pHostapdAdapter->dev );
2943
2944 pWlanHostapdDev->tx_queue_len = NET_DEV_TX_QUEUE_LEN;
2945 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
2946 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
2947
2948 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
2949 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
2950
2951 pWlanHostapdDev->destructor = free_netdev;
2952#ifdef CONFIG_CFG80211
2953 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
2954 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
2955 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
2956 init_completion(&pHostapdAdapter->tx_action_cnf_event);
2957#endif
2958 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
2959 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
2960#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2961 init_completion(&pHostapdAdapter->offchannel_tx_event);
2962#endif
2963
Jeff Johnson295189b2012-06-20 16:38:30 -07002964 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
2965 }
2966 return pHostapdAdapter;
2967}
2968
2969VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
2970{
2971 struct net_device *dev = pAdapter->dev;
2972 VOS_STATUS status = VOS_STATUS_SUCCESS;
2973
2974 ENTER();
2975
2976 if( rtnl_lock_held )
2977 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08002978 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07002979 if( dev_alloc_name(dev, dev->name) < 0 )
2980 {
2981 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
2982 return VOS_STATUS_E_FAILURE;
2983 }
2984 }
2985 if (register_netdevice(dev))
2986 {
2987 hddLog(VOS_TRACE_LEVEL_FATAL,
2988 "%s:Failed:register_netdevice", __func__);
2989 return VOS_STATUS_E_FAILURE;
2990 }
2991 }
2992 else
2993 {
2994 if (register_netdev(dev))
2995 {
2996 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
2997 return VOS_STATUS_E_FAILURE;
2998 }
2999 }
3000 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3001
3002 EXIT();
3003 return status;
3004}
3005
3006VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3007{
3008 ENTER();
3009
3010 hdd_softap_deinit_tx_rx(pAdapter);
3011
3012 /* if we are being called during driver unload, then the dev has already
3013 been invalidated. if we are being called at other times, then we can
3014 detatch the wireless device handlers */
3015 if (pAdapter->dev)
3016 {
3017 pAdapter->dev->wireless_handlers = NULL;
3018 }
3019 EXIT();
3020 return 0;
3021}