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