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