blob: 410b09ce7ff51080acd150557a430dbef68b27f1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
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,
201 "%s: HDD adapter context is Null", __FUNCTION__);
202 ret = -ENODEV;
203 goto exit;
204 }
205
206 if ((!ifr) && (!ifr->ifr_data))
207 {
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,
222 "%s: failed to allocate memory\n", __FUNCTION__);
223 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
248 }
249exit:
250 if (command)
251 {
252 kfree(command);
253 }
254 return ret;
255}
256
257/**---------------------------------------------------------------------------
258
259 \brief hdd_hostapd_set_mac_address() -
260 This function sets the user specified mac address using
261 the command ifconfig wlanX hw ether <mac adress>.
262
263 \param - dev - Pointer to the net device.
264 - addr - Pointer to the sockaddr.
265 \return - 0 for success, non zero for failure
266
267 --------------------------------------------------------------------------*/
268
269static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
270{
271 struct sockaddr *psta_mac_addr = addr;
272 ENTER();
273 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
274 EXIT();
275 return 0;
276}
277void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
278{
279 struct net_device *dev = (struct net_device *)usrDataForCallback;
280 v_BYTE_t we_custom_event[64];
281 union iwreq_data wrqu;
282#ifdef DISABLE_CONCURRENCY_AUTOSAVE
283 VOS_STATUS vos_status;
284 hdd_adapter_t *pHostapdAdapter;
285 hdd_ap_ctx_t *pHddApCtx;
286#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
287
288 /* event_name space-delimiter driver_module_name */
289 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
290 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
291 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
292
293 ENTER();
294
295#ifdef DISABLE_CONCURRENCY_AUTOSAVE
296 if (vos_concurrent_sessions_running())
297 {
298 /*
299 This timer routine is going to be called only when AP
300 persona is up.
301 If there are concurrent sessions running we do not want
302 to shut down the Bss.Instead we run the timer again so
303 that if Autosave is enabled next time and other session
304 was down only then we bring down AP
305 */
306 pHostapdAdapter = netdev_priv(dev);
307 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
308 vos_status = vos_timer_start(
309 &pHddApCtx->hdd_ap_inactivity_timer,
310 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
311 * 1000);
312 if (!VOS_IS_STATUS_SUCCESS(vos_status))
313 {
314 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
315 }
316 EXIT();
317 return;
318 }
319#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
320 memset(&we_custom_event, '\0', sizeof(we_custom_event));
321 memcpy(&we_custom_event, autoShutEvent, event_len);
322
323 memset(&wrqu, 0, sizeof(wrqu));
324 wrqu.data.length = event_len;
325
326 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
327 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
328
329 EXIT();
330}
331
332
333VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
334{
335 hdd_adapter_t *pHostapdAdapter;
336 hdd_ap_ctx_t *pHddApCtx;
337 hdd_hostapd_state_t *pHostapdState;
338 struct net_device *dev;
339 eSapHddEvent sapEvent;
340 union iwreq_data wrqu;
341 v_BYTE_t *we_custom_event_generic = NULL;
342 int we_event = 0;
343 int i = 0;
344 v_U8_t staId;
345 VOS_STATUS vos_status;
346 v_BOOL_t bWPSState;
347 v_BOOL_t bApActive = FALSE;
348 v_BOOL_t bAuthRequired = TRUE;
349 tpSap_AssocMacAddr pAssocStasArray = NULL;
350 char unknownSTAEvent[IW_CUSTOM_MAX+1];
351 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
352 v_BYTE_t we_custom_start_event[64];
353 char *startBssEvent;
354
355 dev = (struct net_device *)usrDataForCallback;
356 pHostapdAdapter = netdev_priv(dev);
357 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
358 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
359 sapEvent = pSapEvent->sapHddEventCode;
360 memset(&wrqu, '\0', sizeof(wrqu));
361
362 switch(sapEvent)
363 {
364 case eSAP_START_BSS_EVENT :
365 hddLog(LOG1, FL("BSS configured status = %s, channel = %lu, bc sta Id = %d\n"),
366 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
367 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
368 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
369
370 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
371 vos_status = vos_event_set(&pHostapdState->vosEvent);
372
373 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
374 {
375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!\n"));
376 goto stopbss;
377 }
378 else
379 {
380 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
381 //@@@ need wep logic here to set privacy bit
382 hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
383 }
384
385 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
386 {
387 // AP Inactivity timer init and start
388 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
389 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
390 if (!VOS_IS_STATUS_SUCCESS(vos_status))
391 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
392
393 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
394 if (!VOS_IS_STATUS_SUCCESS(vos_status))
395 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
396
397 }
398 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
399 pHostapdState->bssState = BSS_START;
400
401 // Send current operating channel of SoftAP to BTC-ES
402 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
403
404#ifdef CONFIG_CFG80211
405 //Check if there is any group key pending to set.
406 if( pHddApCtx->groupKey.keyLength )
407 {
408 if( eHAL_STATUS_SUCCESS != WLANSAP_SetKeySta(
409 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
410 &pHddApCtx->groupKey ) )
411 {
412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
413 "%s: WLANSAP_SetKeySta failed", __func__);
414 }
415 pHddApCtx->groupKey.keyLength = 0;
416 }
417 else if ( pHddApCtx->wepKey[0].keyLength )
418 {
419 int i=0;
420 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
421 {
422 if( eHAL_STATUS_SUCCESS != WLANSAP_SetKeySta(
423 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
424 &pHddApCtx->wepKey[i] ) )
425 {
426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
427 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
428 }
429 pHddApCtx->wepKey[i].keyLength = 0;
430 }
431 }
432#endif
433 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
434 startBssEvent = "SOFTAP.enabled";
435 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
436 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
437 memset(&wrqu, 0, sizeof(wrqu));
438 wrqu.data.length = strlen(startBssEvent);
439 we_event = IWEVCUSTOM;
440 we_custom_event_generic = we_custom_start_event;
441
442 break; //Event will be sent after Switch-Case stmt
443
444 case eSAP_STOP_BSS_EVENT:
445 hddLog(LOG1, FL("BSS stop status = %s\n"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
446 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
447
448 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
449 vos_event_set(&pHostapdState->vosEvent);
450 goto stopbss;
451 case eSAP_STA_SET_KEY_EVENT:
452 //TODO: forward the message to hostapd once implementtation is done for now just print
453 hddLog(LOG1, FL("SET Key: configured status = %s\n"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
454 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
455 return VOS_STATUS_SUCCESS;
456 case eSAP_STA_DEL_KEY_EVENT:
457 //TODO: forward the message to hostapd once implementtation is done for now just print
458 hddLog(LOG1, FL("Event received %s\n"),"eSAP_STA_DEL_KEY_EVENT");
459 return VOS_STATUS_SUCCESS;
460 case eSAP_STA_MIC_FAILURE_EVENT:
461 {
462 struct iw_michaelmicfailure msg;
463 memset(&msg, '\0', sizeof(msg));
464 msg.src_addr.sa_family = ARPHRD_ETHER;
465 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(msg.src_addr.sa_data));
466 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(msg.src_addr.sa_data));
467 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eCSR_ROAM_RESULT_MIC_ERROR_GROUP)
468 msg.flags = IW_MICFAILURE_GROUP;
469 else
470 msg.flags = IW_MICFAILURE_PAIRWISE;
471 memset(&wrqu, 0, sizeof(wrqu));
472 wrqu.data.length = sizeof(msg);
473 we_event = IWEVMICHAELMICFAILURE;
474 we_custom_event_generic = (v_BYTE_t *)&msg;
475 }
476#ifdef CONFIG_CFG80211
477 /* inform mic failure to nl80211 */
478 cfg80211_michael_mic_failure(dev,
479 pSapEvent->sapevt.
480 sapStationMICFailureEvent.staMac.bytes,
481 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSIR_TRUE) ?
482 NL80211_KEYTYPE_GROUP :
483 NL80211_KEYTYPE_PAIRWISE),
484 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
485 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
486 GFP_KERNEL);
487#endif
488 break;
489
490 case eSAP_STA_ASSOC_EVENT:
491 case eSAP_STA_REASSOC_EVENT:
492 wrqu.addr.sa_family = ARPHRD_ETHER;
493 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
494 sizeof(wrqu.addr.sa_data));
495 hddLog(LOG1, " associated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
496 we_event = IWEVREGISTERED;
497
498 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
499
500 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
501 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
502 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
503 {
504 bAuthRequired = FALSE;
505 }
506
507 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
508 {
509 hdd_softap_RegisterSTA( pHostapdAdapter,
510 TRUE,
511 pHddApCtx->uPrivacy,
512 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
513 0,
514 0,
515 (v_MACADDR_t *)wrqu.addr.sa_data,
516 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
517 }
518 else
519 {
520 hdd_softap_RegisterSTA( pHostapdAdapter,
521 FALSE,
522 pHddApCtx->uPrivacy,
523 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
524 0,
525 0,
526 (v_MACADDR_t *)wrqu.addr.sa_data,
527 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
528 }
529
530 // Stop AP inactivity timer
531 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
532 {
533 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
534 if (!VOS_IS_STATUS_SUCCESS(vos_status))
535 hddLog(LOGE, FL("Failed to start AP inactivity timer\n"));
536 }
537#ifdef CONFIG_CFG80211
538#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
539 {
540 struct station_info staInfo;
541 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
542
543 memset(&staInfo, 0, sizeof(staInfo));
544 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
545 {
546 staInfo.assoc_req_ies =
547 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
548 staInfo.assoc_req_ies_len = iesLen;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
550 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
551#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700552 cfg80211_new_sta(dev,
553 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
554 &staInfo, GFP_KERNEL);
555 }
556 else
557 {
558 hddLog(LOGE, FL(" Assoc Ie length is too long \n"));
559 }
560 }
561#endif
562#endif
563
564 break;
565 case eSAP_STA_DISASSOC_EVENT:
566 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
567 sizeof(wrqu.addr.sa_data));
568 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(wrqu.addr.sa_data));
569 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
570 hddLog(LOG1," User initiated disassociation");
571 else
572 hddLog(LOG1," MAC initiated disassociation");
573 we_event = IWEVEXPIRED;
574 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
575 if (!VOS_IS_STATUS_SUCCESS(vos_status))
576 {
577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD Failed to find sta id!!\n"));
578 return VOS_STATUS_E_FAILURE;
579 }
580 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
581
582 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
583 {
584 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
585 // Start AP inactivity timer if no stations associated with it
586 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
587 {
588 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
589 {
590 bApActive = TRUE;
591 break;
592 }
593 }
594 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
595
596 if (bApActive == FALSE)
597 {
598 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
599 {
600 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
601 if (!VOS_IS_STATUS_SUCCESS(vos_status))
602 hddLog(LOGE, FL("Failed to init AP inactivity timer\n"));
603 }
604 else
605 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
606 }
607 }
608#ifdef CONFIG_CFG80211
609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
610 cfg80211_del_sta(dev,
611 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
612 GFP_KERNEL);
613#endif
614#endif
615 break;
616 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
617 {
618 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
619 union iwreq_data wreq;
620
621 down(&pHddApCtx->semWpsPBCOverlapInd);
622 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
623
624 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
625 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
626
627 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
628 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR"\n", MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
629 memset(&wreq, 0, sizeof(wreq));
630 wreq.data.length = strlen(message); // This is length of message
631 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
632
633 return VOS_STATUS_SUCCESS;
634 }
635 case eSAP_ASSOC_STA_CALLBACK_EVENT:
636 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
637 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
638 { // List of associated stations
639 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
640 {
641 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
642 i+1,
643 pAssocStasArray->assocId,
644 pAssocStasArray->staId,
645 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
646 pAssocStasArray++;
647 }
648 }
649 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
650 return VOS_STATUS_SUCCESS;
651#ifdef WLAN_FEATURE_P2P
652 case eSAP_INDICATE_MGMT_FRAME:
653 hdd_indicateMgmtFrame( pHostapdAdapter,
654 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
655 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
656 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
657 pSapEvent->sapevt.sapManagementFrameInfo.rxChan);
658 return VOS_STATUS_SUCCESS;
659 case eSAP_REMAIN_CHAN_READY:
660 hdd_remainChanReadyHandler( pHostapdAdapter );
661 return VOS_STATUS_SUCCESS;
662 case eSAP_SEND_ACTION_CNF:
663 hdd_sendActionCnf( pHostapdAdapter,
664 ( eSAP_STATUS_SUCCESS ==
665 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
666 TRUE : FALSE );
667 return VOS_STATUS_SUCCESS;
668#endif
669 case eSAP_UNKNOWN_STA_JOIN:
670 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
671 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
672 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
673 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
674 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
675 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
676 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
677 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
678 wrqu.data.pointer = unknownSTAEvent;
679 wrqu.data.length = strlen(unknownSTAEvent);
680 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
681 hddLog(LOG1,"%s\n", unknownSTAEvent);
682 break;
683
684 case eSAP_MAX_ASSOC_EXCEEDED:
685 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
686 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
687 " one or more devices to enable the new device connection",
688 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
689 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
690 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
691 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
692 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
693 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
694 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
695 wrqu.data.pointer = maxAssocExceededEvent;
696 wrqu.data.length = strlen(maxAssocExceededEvent);
697 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
698 hddLog(LOG1,"%s\n", maxAssocExceededEvent);
699 break;
700 case eSAP_STA_ASSOC_IND:
701 return VOS_STATUS_SUCCESS;
702 default:
703 hddLog(LOG1,"SAP message is not handled\n");
704 goto stopbss;
705 return VOS_STATUS_SUCCESS;
706 }
707 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
708 return VOS_STATUS_SUCCESS;
709
710stopbss :
711 {
712 v_BYTE_t we_custom_event[64];
713 char *stopBssEvent = "STOP-BSS.response";//17
714 int event_len = strlen(stopBssEvent);
715
716 hddLog(LOG1, FL("BSS stop status = %s"),
717 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
718 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
719
720 /* Change the BSS state now since, as we are shutting things down,
721 * we don't want interfaces to become re-enabled */
722 pHostapdState->bssState = BSS_STOP;
723
724 /* Stop the pkts from n/w stack as we are going to free all of
725 * the TX WMM queues for all STAID's */
726 hdd_hostapd_stop(dev);
727
728 /* reclaim all resources allocated to the BSS */
729 hdd_softap_stop_bss(pHostapdAdapter);
730
731 /* notify userspace that the BSS has stopped */
732 memset(&we_custom_event, '\0', sizeof(we_custom_event));
733 memcpy(&we_custom_event, stopBssEvent, event_len);
734 memset(&wrqu, 0, sizeof(wrqu));
735 wrqu.data.length = event_len;
736 we_event = IWEVCUSTOM;
737 we_custom_event_generic = we_custom_event;
738 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
739 }
740 return VOS_STATUS_SUCCESS;
741}
742int hdd_softap_unpackIE(
743 tHalHandle halHandle,
744 eCsrEncryptionType *pEncryptType,
745 eCsrEncryptionType *mcEncryptType,
746 eCsrAuthType *pAuthType,
747 u_int16_t gen_ie_len,
748 u_int8_t *gen_ie )
749{
750 tDot11fIERSN dot11RSNIE;
751 tDot11fIEWPA dot11WPAIE;
752
753 tANI_U8 *pRsnIe;
754 tANI_U16 RSNIeLen;
755
756 if (NULL == halHandle)
757 {
758 hddLog(LOGE, FL("Error haHandle returned NULL\n"));
759 return -EINVAL;
760 }
761
762 // Validity checks
763 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
764 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
765 return -EINVAL;
766 // Type check
767 if ( gen_ie[0] == DOT11F_EID_RSN)
768 {
769 // Validity checks
770 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
771 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
772 {
773 return VOS_STATUS_E_FAILURE;
774 }
775 // Skip past the EID byte and length byte
776 pRsnIe = gen_ie + 2;
777 RSNIeLen = gen_ie_len - 2;
778 // Unpack the RSN IE
779 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
780 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
781 pRsnIe,
782 RSNIeLen,
783 &dot11RSNIE);
784 // Copy out the encryption and authentication types
785 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d\n"),
786 __FUNCTION__, dot11RSNIE.pwise_cipher_suite_count );
787 hddLog(LOG1, FL("%s: authentication suite count: %d\n"),
788 __FUNCTION__, dot11RSNIE.akm_suite_count);
789 /*Here we have followed the apple base code,
790 but probably I suspect we can do something different*/
791 //dot11RSNIE.akm_suite_count
792 // Just translate the FIRST one
793 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
794 //dot11RSNIE.pwise_cipher_suite_count
795 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
796 //dot11RSNIE.gp_cipher_suite_count
797 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
798 // Set the PMKSA ID Cache for this interface
799
800 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
801 } else
802 if (gen_ie[0] == DOT11F_EID_WPA)
803 {
804 // Validity checks
805 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
806 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
807 {
808 return VOS_STATUS_E_FAILURE;
809 }
810 // Skip past the EID byte and length byte - and four byte WiFi OUI
811 pRsnIe = gen_ie + 2 + 4;
812 RSNIeLen = gen_ie_len - (2 + 4);
813 // Unpack the WPA IE
814 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
815 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
816 pRsnIe,
817 RSNIeLen,
818 &dot11WPAIE);
819 // Copy out the encryption and authentication types
820 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d\n"),
821 __FUNCTION__, dot11WPAIE.unicast_cipher_count );
822 hddLog(LOG1, FL("%s: WPA authentication suite count: %d\n"),
823 __FUNCTION__, dot11WPAIE.auth_suite_count);
824 //dot11WPAIE.auth_suite_count
825 // Just translate the FIRST one
826 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
827 //dot11WPAIE.unicast_cipher_count
828 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
829 //dot11WPAIE.unicast_cipher_count
830 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
831 }
832 else
833 {
834 hddLog(LOGW, FL("%s: gen_ie[0]: %d\n"), __FUNCTION__, gen_ie[0]);
835 return VOS_STATUS_E_FAILURE;
836 }
837 return VOS_STATUS_SUCCESS;
838}
839int
840static iw_softap_setparam(struct net_device *dev,
841 struct iw_request_info *info,
842 union iwreq_data *wrqu, char *extra)
843{
844 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
845 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
846 int *value = (int *)extra;
847 int sub_cmd = value[0];
848 int set_value = value[1];
849 eHalStatus status;
850 int ret = 0; /* success */
851 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
852
853 switch(sub_cmd)
854 {
855
856 case QCSAP_PARAM_CLR_ACL:
857 if ( eHAL_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
858 {
859 ret = -EIO;
860 }
861 break;
862
863 case QCSAP_PARAM_ACL_MODE:
864 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
865 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
866 {
867 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
868 ret = -EINVAL;
869 }
870 else
871 {
872 WLANSAP_SetMode(pVosContext, set_value);
873 }
874 break;
875 case QCSAP_PARAM_MAX_ASSOC:
876 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
877 {
878 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
879 ret = -EINVAL;
880 }
881 else
882 {
883 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
884 {
885 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
886 "Setting it to max allowed and continuing"),
887 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
888 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
889 }
890 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
891 set_value, NULL, eANI_BOOLEAN_FALSE);
892 if ( status != eHAL_STATUS_SUCCESS )
893 {
894 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
895 status);
896 ret = -EIO;
897 }
898 }
899 break;
900
901 case QCSAP_PARAM_HIDE_SSID:
902 {
903 eHalStatus status = eHAL_STATUS_SUCCESS;
904 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
905 if(eHAL_STATUS_SUCCESS != status)
906 {
907 hddLog(VOS_TRACE_LEVEL_ERROR,
908 "%s: QCSAP_PARAM_HIDE_SSID failed",
909 __FUNCTION__);
910 return status;
911 }
912 break;
913 }
914
915 default:
916 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
917 sub_cmd, set_value);
918 ret = -EINVAL;
919 break;
920 }
921
922 return ret;
923}
924
925
926int
927static iw_softap_getparam(struct net_device *dev,
928 struct iw_request_info *info,
929 union iwreq_data *wrqu, char *extra)
930{
931 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
932 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
933 int *value = (int *)extra;
934 int sub_cmd = value[0];
935 eHalStatus status;
936 int ret = 0; /* success */
937 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
938
939 switch (sub_cmd)
940 {
941 case QCSAP_PARAM_MAX_ASSOC:
942 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
943 if (eHAL_STATUS_SUCCESS != status)
944 {
945 ret = -EIO;
946 }
947 break;
948
949 case QCSAP_PARAM_CLR_ACL:
950 if ( eHAL_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
951 {
952 ret = -EIO;
953 }
954 *value = 0;
955 break;
956
957 case QCSAP_PARAM_MODULE_DOWN_IND:
958 {
959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
960 "%s: sending WLAN_MODULE_DOWN_IND", __FUNCTION__);
961 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
962#ifdef WLAN_BTAMP_FEATURE
963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
964 "%s: Take down AMP PAL", __FUNCTION__);
965 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
966#endif
967 *value = 0;
968 break;
969 }
970
971 default:
972 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
973 ret = -EINVAL;
974 break;
975
976 }
977
978 return ret;
979}
980
981/* Usage:
982 BLACK_LIST = 0
983 WHITE_LIST = 1
984 ADD MAC = 0
985 REMOVE MAC = 1
986
987 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
988 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
989 while using this ioctl
990
991 Syntax:
992 iwpriv softap.0 modify_acl
993 <6 octet mac addr> <list type> <cmd type>
994
995 Examples:
996 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
997 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
998 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
999 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1000*/
1001int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1002 union iwreq_data *wrqu, char *extra)
1003{
1004 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1005 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1006 v_BYTE_t *value = (v_BYTE_t*)extra;
1007 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1008 int listType, cmd, i;
1009 int ret = 0; /* success */
1010
1011 ENTER();
1012 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1013 {
1014 pPeerStaMac[i] = *(value+i);
1015 }
1016 listType = (int)(*(value+i));
1017 i++;
1018 cmd = (int)(*(value+i));
1019
1020 hddLog(LOG1, "%s: SAP Modify ACL arg0 %02x:%02x:%02x:%02x:%02x:%02x arg1 %d arg2 %d\n",
1021 __FUNCTION__, pPeerStaMac[0], pPeerStaMac[1], pPeerStaMac[2],
1022 pPeerStaMac[3], pPeerStaMac[4], pPeerStaMac[5], listType, cmd);
1023
1024 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1025 != VOS_STATUS_SUCCESS)
1026 {
1027 hddLog(LOGE, FL("Modify ACL failed\n"));
1028 ret = -EIO;
1029 }
1030 EXIT();
1031 return ret;
1032}
1033
1034int
1035static iw_softap_getchannel(struct net_device *dev,
1036 struct iw_request_info *info,
1037 union iwreq_data *wrqu, char *extra)
1038{
1039 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1040
1041 *(v_U32_t *)(wrqu->data.pointer) = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
1042
1043 wrqu->data.length = sizeof((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel);
1044
1045 return 0;
1046}
1047
1048#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1049
1050int
1051static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1052 struct iw_request_info *info,
1053 union iwreq_data *wrqu, char *extra)
1054{
1055 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1056 unsigned char *pmaclist;
1057 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
1058 int cnt = 0, len;
1059
1060
1061 pmaclist = wrqu->data.pointer + sizeof(unsigned long int);
1062 len = wrqu->data.length;
1063
1064 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
1065 while((cnt < WLAN_MAX_STA_COUNT) && (len > (sizeof(v_MACADDR_t)+1))) {
1066 if (TRUE == pStaInfo[cnt].isUsed) {
1067
1068 if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
1069 memcpy((void *)pmaclist, (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t));
1070 pmaclist += sizeof(v_MACADDR_t);
1071 len -= sizeof(v_MACADDR_t);
1072 }
1073 }
1074 cnt++;
1075 }
1076 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
1077
1078 *pmaclist = '\0';
1079
1080 wrqu->data.length -= len;
1081
1082 *(unsigned long int *)(wrqu->data.pointer) = wrqu->data.length;
1083
1084 return 0;
1085}
1086
1087/* Usage:
1088 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1089 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1090 while using this ioctl
1091
1092 Syntax:
1093 iwpriv softap.0 disassoc_sta <6 octet mac address>
1094
1095 e.g.
1096 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1097 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1098*/
1099
1100int
1101static iw_softap_disassoc_sta(struct net_device *dev,
1102 struct iw_request_info *info,
1103 union iwreq_data *wrqu, char *extra)
1104{
1105 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1106 v_U8_t *peerMacAddr;
1107
1108 ENTER();
1109 /* the comparison below is needed since if iwpriv tool is used for calling this ioctl
1110 * data is passed in extra (less than 16 octets); however in android wifi framework
1111 * data is placed in wrqu->data.pointer.
1112 */
1113 if ((v_U8_t*)wrqu == (v_U8_t*)extra)
1114 peerMacAddr = (v_U8_t *)(extra);
1115 else
1116 peerMacAddr = (v_U8_t *)(wrqu->data.pointer);
1117
1118 hddLog(LOG1, "data %02x:%02x:%02x:%02x:%02x:%02x",
1119 peerMacAddr[0], peerMacAddr[1], peerMacAddr[2],
1120 peerMacAddr[3], peerMacAddr[4], peerMacAddr[5]);
1121 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1122 EXIT();
1123 return 0;
1124}
1125
1126int
1127static iw_softap_ap_stats(struct net_device *dev,
1128 struct iw_request_info *info,
1129 union iwreq_data *wrqu, char *extra)
1130{
1131 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1132 WLANTL_TRANSFER_STA_TYPE statBuffer;
1133 char *pstatbuf;
1134 int len = wrqu->data.length;
1135 pstatbuf = wrqu->data.pointer;
1136
1137 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &statBuffer, (v_BOOL_t)wrqu->data.flags);
1138
1139 len = snprintf(pstatbuf, len,
1140 "RUF=%d RMF=%d RBF=%d "
1141 "RUB=%d RMB=%d RBB=%d "
1142 "TUF=%d TMF=%d TBF=%d "
1143 "TUB=%d TMB=%d TBB=%d",
1144 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, (int)statBuffer.rxBCFcnt,
1145 (int)statBuffer.rxUCBcnt, (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1146 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, (int)statBuffer.txBCFcnt,
1147 (int)statBuffer.txUCBcnt, (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt
1148 );
1149
1150 wrqu->data.length -= len;
1151 return 0;
1152}
1153
1154int
1155static iw_softap_commit(struct net_device *dev,
1156 struct iw_request_info *info,
1157 union iwreq_data *wrqu, char *extra)
1158{
1159 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1160 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1161 hdd_hostapd_state_t *pHostapdState;
1162 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1163 tpWLAN_SAPEventCB pSapEventCallback;
1164 tsap_Config_t *pConfig;
1165 s_CommitConfig_t *pCommitConfig;
1166 struct qc_mac_acl_entry *acl_entry = NULL;
1167 v_SINT_t i = 0, num_mac = 0;
1168 v_U32_t status = 0;
1169 eCsrAuthType RSNAuthType;
1170 eCsrEncryptionType RSNEncryptType;
1171 eCsrEncryptionType mcRSNEncryptType;
1172
1173 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1174 pCommitConfig = (s_CommitConfig_t *)extra;
1175
1176 pConfig = kmalloc(sizeof(tsap_Config_t), GFP_KERNEL);
1177 if(NULL == pConfig) {
1178 hddLog(LOG1, "VOS unable to allocate memory\n");
1179 return -ENOMEM;
1180 }
1181 pConfig->beacon_int = pCommitConfig->beacon_int;
1182 pConfig->channel = pCommitConfig->channel;
1183
1184 /*Protection parameter to enable or disable*/
1185 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1186 pConfig->dtim_period = pCommitConfig->dtim_period;
1187 switch(pCommitConfig->hw_mode )
1188 {
1189 case eQC_DOT11_MODE_11A:
1190 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
1191 break;
1192 case eQC_DOT11_MODE_11B:
1193 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
1194 break;
1195 case eQC_DOT11_MODE_11G:
1196 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
1197 break;
1198
1199 case eQC_DOT11_MODE_11N:
1200 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1201 break;
1202 case eQC_DOT11_MODE_11G_ONLY:
1203 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1204 break;
1205 case eQC_DOT11_MODE_11N_ONLY:
1206 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
1207 break;
1208 default:
1209 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1210 break;
1211
1212 }
1213
1214 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
1215 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
1216 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
1217 pConfig->authType = eSAP_SHARED_KEY;
1218 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
1219 pConfig->authType = eSAP_OPEN_SYSTEM;
1220 else
1221 pConfig->authType = eSAP_AUTO_SWITCH;
1222
1223 pConfig->privacy = pCommitConfig->privacy;
1224 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
1225 pConfig->wps_state = pCommitConfig->wps_state;
1226 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
1227 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
1228 if(pConfig->RSNWPAReqIELength){
1229 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
1230 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
1231 // The actual processing may eventually be more extensive than this.
1232 // Right now, just consume any PMKIDs that are sent in by the app.
1233 status = hdd_softap_unpackIE(
1234#if defined(FEATURE_WLAN_NON_INTEGRATED_SOC)
1235 vos_get_context( VOS_MODULE_ID_HAL, pVosContext),
1236#else
1237 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
1238#endif
1239 &RSNEncryptType,
1240 &mcRSNEncryptType,
1241 &RSNAuthType,
1242 pConfig->pRSNWPAReqIE[1]+2,
1243 pConfig->pRSNWPAReqIE );
1244
1245 if( VOS_STATUS_SUCCESS == status )
1246 {
1247 // Now copy over all the security attributes you have parsed out
1248 //TODO: Need to handle mixed mode
1249 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1250 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1251 hddLog( LOG1, FL("%s: CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d\n"),
1252 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1253 }
1254 }
1255 }
1256 else
1257 {
1258 /* If no RSNIE, set encrypt type to NONE*/
1259 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1260 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
1261 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d\n"),
1262 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
1263 }
1264
1265 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
1266 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
1267 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
1268 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1269
1270 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
1271
1272 // ht_capab is not what the name conveys,this is used for protection bitmap
1273 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1274
1275 if (pCommitConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1276 num_mac = pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1277 else
1278 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
1279 acl_entry = pCommitConfig->accept_mac;
1280 for (i = 0; i < num_mac; i++)
1281 {
1282 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1283 acl_entry++;
1284 }
1285 if (pCommitConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1286 num_mac = pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1287 else
1288 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
1289 acl_entry = pCommitConfig->deny_mac;
1290 for (i = 0; i < num_mac; i++)
1291 {
1292 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
1293 acl_entry++;
1294 }
1295 //Uapsd Enabled Bit
1296 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1297 //Enable OBSS protection
1298 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
1299 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
1300
1301 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
1302 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
1303 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int, (int)pConfig->channel);
1304 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
1305 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy, pConfig->authType);
1306 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
1307 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
1308 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),pConfig->protEnabled, pConfig->obssProtEnabled);
1309 hddLog(LOGW,FL("DisableIntraBssFwd = %d\n"),(WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
1310
1311 pSapEventCallback = hdd_hostapd_SAPEventCB;
1312 pConfig->persona = pHostapdAdapter->device_mode;
1313 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
1314 {
1315 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1316 }
1317
1318 kfree(pConfig);
1319
1320 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1321 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
1322
1323 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1324 {
1325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos wait for single_event failed!!\n"));
1326 VOS_ASSERT(0);
1327 }
1328
1329 pHostapdState->bCommit = TRUE;
1330 if(pHostapdState->vosStatus)
1331 {
1332 return -1;
1333 }
1334 else
1335 {
1336 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1337 WLANSAP_Update_WpsIe ( pVosContext );
1338 return 0;
1339 }
1340}
1341static
1342int iw_softap_setmlme(struct net_device *dev,
1343 struct iw_request_info *info,
1344 union iwreq_data *wrqu, char *extra)
1345{
1346 struct sQcSapreq_mlme *pmlme;
1347 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
1348 v_MACADDR_t destAddress;
1349 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
1350 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
1351 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
1352 switch(pmlme->im_op)
1353 {
1354 case QCSAP_MLME_AUTHORIZE:
1355 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
1356 break;
1357 case QCSAP_MLME_ASSOC:
1358 //TODO:inform to TL after associating (not needed as we do in sapCallback)
1359 break;
1360 case QCSAP_MLME_UNAUTHORIZE:
1361 //TODO: send the disassoc to station
1362 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
1363 break;
1364 case QCSAP_MLME_DISASSOC:
1365 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
1366 break;
1367 case QCSAP_MLME_DEAUTH:
1368 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
1369 break;
1370 case QCSAP_MLME_MICFAILURE:
1371 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
1372 break;
1373 default:
1374 break;
1375 }
1376 return 0;
1377}
1378
1379static int iw_softap_set_channel_range(struct net_device *dev,
1380 struct iw_request_info *info,
1381 union iwreq_data *wrqu, char *extra)
1382{
1383 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1384 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1385
1386 int *value = (int *)extra;
1387 int startChannel = value[0];
1388 int endChannel = value[1];
1389 int band = value[2];
1390 eHalStatus status;
1391 int ret = 0; /* success */
1392
1393 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
1394 if(status != VOS_STATUS_SUCCESS)
1395 {
1396 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d\n"),
1397 startChannel,endChannel, band);
1398 ret = -EINVAL;
1399 }
1400 return ret;
1401}
1402
1403int iw_softap_get_channel_list(struct net_device *dev,
1404 struct iw_request_info *info,
1405 union iwreq_data *wrqu, char *extra)
1406{
1407 v_U32_t num_channels = 0;
1408 v_U8_t i = 0;
1409 v_U8_t bandStartChannel = RF_CHAN_1;
1410 v_U8_t bandEndChannel = RF_CHAN_165;
1411 v_U32_t temp_num_channels = 0;
1412 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1413 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1414 v_REGDOMAIN_t domainIdCurrentSoftap;
1415
1416 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
1417 wrqu->data.length = sizeof(tChannelListInfo);
1418 ENTER();
1419
1420 for( i = bandStartChannel; i <= bandEndChannel; i++ )
1421 {
1422 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
1423 {
1424 channel_list->channels[num_channels] = rfChannels[i].channelNum;
1425 num_channels++;
1426 }
1427 }
1428
1429 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
1430
1431 temp_num_channels = num_channels;
1432
1433 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
1434 {
1435 hddLog(LOG1,FL("Failed to get Domain ID, %d \n"),domainIdCurrentSoftap);
1436 return -1;
1437 }
1438
1439 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
1440 {
1441 for(i = 0; i < temp_num_channels; i++)
1442 {
1443
1444 if((channel_list->channels[i] > 35) &&
1445 (channel_list->channels[i] < 49))
1446 {
1447 vos_mem_move(&channel_list->channels[i],
1448 &channel_list->channels[i+1],
1449 temp_num_channels - (i-1));
1450 num_channels--;
1451 temp_num_channels--;
1452 i--;
1453 }
1454 }
1455 }
1456
1457 hddLog(LOG1,FL(" number of channels %d\n"), num_channels);
1458
1459 if (num_channels > IW_MAX_FREQUENCIES)
1460 {
1461 num_channels = IW_MAX_FREQUENCIES;
1462 }
1463
1464 channel_list->num_channels = num_channels;
1465 EXIT();
1466
1467 return 0;
1468}
1469
1470static
1471int iw_get_genie(struct net_device *dev,
1472 struct iw_request_info *info,
1473 union iwreq_data *wrqu, char *extra)
1474{
1475 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1476 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1477 eHalStatus status;
1478 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
1479 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
1480 ENTER();
1481 hddLog(LOG1,FL("getGEN_IE ioctl\n"));
1482 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
1483 status = WLANSap_getstationIE_information(pVosContext,
1484 &length,
1485 genIeBytes);
1486 wrqu->data.length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
1487 vos_mem_copy( wrqu->data.pointer, (v_VOID_t*)genIeBytes, wrqu->data.length);
1488
1489 hddLog(LOG1,FL(" RSN IE of %d bytes returned\n"), wrqu->data.length );
1490
1491
1492 EXIT();
1493 return 0;
1494}
1495static
1496int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
1497 struct iw_request_info *info,
1498 union iwreq_data *wrqu, char *extra)
1499{
1500 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1501 sQcSapreq_WPSPBCProbeReqIES_t *pWPSPBCProbeReqIEs;
1502 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1503 ENTER();
1504
1505 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl\n"));
1506
1507 pWPSPBCProbeReqIEs = (sQcSapreq_WPSPBCProbeReqIES_t *)(wrqu->data.pointer);
1508 pWPSPBCProbeReqIEs->probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
1509 vos_mem_copy(pWPSPBCProbeReqIEs->probeReqIE, pHddApCtx->WPSPBCProbeReq.probeReqIE, pWPSPBCProbeReqIEs->probeReqIELen);
1510 vos_mem_copy(pWPSPBCProbeReqIEs->macaddr, pHddApCtx->WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
1511 wrqu->data.length = 12 + pWPSPBCProbeReqIEs->probeReqIELen;
1512 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pWPSPBCProbeReqIEs->macaddr));
1513 up(&pHddApCtx->semWpsPBCOverlapInd);
1514 EXIT();
1515 return 0;
1516}
1517
1518/**---------------------------------------------------------------------------
1519
1520 \brief iw_set_auth_hostap() -
1521 This function sets the auth type received from the wpa_supplicant.
1522
1523 \param - dev - Pointer to the net device.
1524 - info - Pointer to the iw_request_info.
1525 - wrqu - Pointer to the iwreq_data.
1526 - extra - Pointer to the data.
1527 \return - 0 for success, non zero for failure
1528
1529 --------------------------------------------------------------------------*/
1530int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
1531 union iwreq_data *wrqu,char *extra)
1532{
1533 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1534 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1535
1536 ENTER();
1537 switch(wrqu->param.flags & IW_AUTH_INDEX)
1538 {
1539 case IW_AUTH_TKIP_COUNTERMEASURES:
1540 {
1541 if(wrqu->param.value) {
1542 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1543 "Counter Measure started %d", wrqu->param.value);
1544 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
1545 }
1546 else {
1547 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1548 "Counter Measure stopped=%d", wrqu->param.value);
1549 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
1550 }
1551
1552 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
1553 wrqu->param.value);
1554 }
1555 break;
1556
1557 default:
1558
1559 hddLog(LOGW, "%s called with unsupported auth type %d", __FUNCTION__,
1560 wrqu->param.flags & IW_AUTH_INDEX);
1561 break;
1562 }
1563
1564 EXIT();
1565 return 0;
1566}
1567
1568static int iw_set_ap_encodeext(struct net_device *dev,
1569 struct iw_request_info *info,
1570 union iwreq_data *wrqu, char *extra)
1571{
1572 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1573 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1574 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1575 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
1576 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1577 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1578 int key_index;
1579 struct iw_point *encoding = &wrqu->encoding;
1580 tCsrRoamSetKey setKey;
1581// tCsrRoamRemoveKey RemoveKey;
1582 int i;
1583 ENTER();
1584
1585 key_index = encoding->flags & IW_ENCODE_INDEX;
1586
1587 if(key_index > 0) {
1588
1589 /*Convert from 1-based to 0-based keying*/
1590 key_index--;
1591 }
1592 if(!ext->key_len) {
1593#if 0
1594 /*Set the encrytion type to NONE*/
1595#if 0
1596 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
1597#endif
1598
1599 RemoveKey.keyId = key_index;
1600 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1601 /*Key direction for group is RX only*/
1602 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1603 }
1604 else {
1605 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1606 }
1607 switch(ext->alg)
1608 {
1609 case IW_ENCODE_ALG_NONE:
1610 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1611 break;
1612 case IW_ENCODE_ALG_WEP:
1613 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1614 break;
1615 case IW_ENCODE_ALG_TKIP:
1616 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
1617 break;
1618 case IW_ENCODE_ALG_CCMP:
1619 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
1620 break;
1621 default:
1622 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1623 break;
1624 }
1625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d \n",
1626 __FUNCTION__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
1627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR"\n",
1628 __FUNCTION__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
1629 );
1630 halStatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
1631 if ( halStatus != eHAL_STATUS_SUCCESS )
1632 {
1633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
1634 __LINE__, halStatus );
1635 }
1636#endif
1637 return halStatus;
1638
1639 }
1640
1641 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
1642
1643 setKey.keyId = key_index;
1644 setKey.keyLength = ext->key_len;
1645
1646 if(ext->key_len <= CSR_MAX_KEY_LEN) {
1647 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
1648 }
1649
1650 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1651 /*Key direction for group is RX only*/
1652 setKey.keyDirection = eSIR_RX_ONLY;
1653 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
1654 }
1655 else {
1656
1657 setKey.keyDirection = eSIR_TX_RX;
1658 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1659 }
1660 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1661 {
1662 setKey.keyDirection = eSIR_TX_DEFAULT;
1663 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
1664 }
1665
1666 /*For supplicant pae role is zero*/
1667 setKey.paeRole = 0;
1668
1669 switch(ext->alg)
1670 {
1671 case IW_ENCODE_ALG_NONE:
1672 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1673 break;
1674
1675 case IW_ENCODE_ALG_WEP:
1676 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
1677 pHddApCtx->uPrivacy = 1;
1678 hddLog(LOG1, "(%s) uPrivacy=%d", __FUNCTION__, pHddApCtx->uPrivacy);
1679 break;
1680
1681 case IW_ENCODE_ALG_TKIP:
1682 {
1683 v_U8_t *pKey = &setKey.Key[0];
1684
1685 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
1686
1687 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
1688
1689 /*Supplicant sends the 32bytes key in this order
1690
1691 |--------------|----------|----------|
1692 | Tk1 |TX-MIC | RX Mic |
1693 |--------------|----------|----------|
1694 <---16bytes---><--8bytes--><--8bytes-->
1695
1696 */
1697 /*Sme expects the 32 bytes key to be in the below order
1698
1699 |--------------|----------|----------|
1700 | Tk1 |RX-MIC | TX Mic |
1701 |--------------|----------|----------|
1702 <---16bytes---><--8bytes--><--8bytes-->
1703 */
1704 /* Copy the Temporal Key 1 (TK1) */
1705 vos_mem_copy(pKey,ext->key,16);
1706
1707 /*Copy the rx mic first*/
1708 vos_mem_copy(&pKey[16],&ext->key[24],8);
1709
1710 /*Copy the tx mic */
1711 vos_mem_copy(&pKey[24],&ext->key[16],8);
1712
1713 }
1714 break;
1715
1716 case IW_ENCODE_ALG_CCMP:
1717 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
1718 break;
1719
1720 default:
1721 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
1722 break;
1723 }
1724
1725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1726 ("%s:EncryptionType:%d key_len:%d, :%d, KeyId:%d \n"),__FUNCTION__, setKey.encType, setKey.keyLength,
1727 setKey.keyId);
1728 for(i=0; i< ext->key_len; i++)
1729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1730 ("%02x"), setKey.Key[i]);
1731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1732 ("\n"));
1733 halStatus = WLANSAP_SetKeySta( pVosContext, &setKey);
1734
1735 if ( halStatus != eHAL_STATUS_SUCCESS )
1736 {
1737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1738 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, halStatus );
1739 }
1740
1741 return halStatus;
1742}
1743static int iw_set_ap_mlme(struct net_device *dev,
1744 struct iw_request_info *info,
1745 union iwreq_data *wrqu,
1746 char *extra)
1747{
1748#if 0
1749 hdd_adapter_t *pAdapter = (netdev_priv(dev));
1750 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1751
1752 ENTER();
1753
1754 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
1755 switch (mlme->cmd) {
1756 case IW_MLME_DISASSOC:
1757 case IW_MLME_DEAUTH:
1758 hddLog(LOG1, "Station disassociate");
1759 if( pAdapter->conn_info.connState == eConnectionState_Associated )
1760 {
1761 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
1762
1763 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
1764 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
1765
1766 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
1767
1768 //clear all the reason codes
1769 if (status != 0)
1770 {
1771 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d \n", __FUNCTION__, (int)mlme->cmd, (int)status );
1772 }
1773
1774 netif_stop_queue(dev);
1775 netif_carrier_off(dev);
1776 }
1777 else
1778 {
1779 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state \n", __FUNCTION__, (int)mlme->cmd );
1780 }
1781 default:
1782 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate \n", __FUNCTION__, (int)mlme->cmd );
1783 return -EINVAL;
1784 }//end of switch
1785 EXIT();
1786#endif
1787 return 0;
1788// return status;
1789}
1790
1791static int iw_get_ap_rts_threshold(struct net_device *dev,
1792 struct iw_request_info *info,
1793 union iwreq_data *wrqu, char *extra)
1794{
1795 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1796 v_U32_t status = 0;
1797
1798 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
1799
1800 return status;
1801}
1802
1803static int iw_get_ap_frag_threshold(struct net_device *dev,
1804 struct iw_request_info *info,
1805 union iwreq_data *wrqu, char *extra)
1806{
1807 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1808 v_U32_t status = 0;
1809
1810 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
1811
1812 return status;
1813}
1814
1815static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
1816 struct iw_freq *fwrq, char *extra)
1817{
1818 v_U32_t status = 0,channel,freq;
1819 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1820 tHalHandle hHal;
1821 hdd_hostapd_state_t *pHostapdState;
1822 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1823
1824 ENTER();
1825
1826 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
1827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1828 "%s:LOGP in Progress. Ignore!!!",__func__);
1829 return status;
1830 }
1831
1832 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1833 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1834
1835 if(pHostapdState->bssState == BSS_STOP )
1836 {
1837 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
1838 != eHAL_STATUS_SUCCESS)
1839 {
1840 return -EIO;
1841 }
1842 else
1843 {
1844 status = hdd_wlan_get_freq(channel, &freq);
1845 fwrq->m = freq;
1846 fwrq->e = 0;
1847 }
1848 }
1849 else
1850 {
1851 channel = pHddApCtx->operatingChannel;
1852 status = hdd_wlan_get_freq(channel, &freq);
1853 fwrq->m = freq;
1854 fwrq->e = 0;
1855 }
1856 return status;
1857}
1858
1859static int iw_softap_setwpsie(struct net_device *dev,
1860 struct iw_request_info *info,
1861 union iwreq_data *wrqu,
1862 char *extra)
1863{
1864 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1865 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1866 hdd_hostapd_state_t *pHostapdState;
1867 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
1868 u_int8_t *wps_genie = wrqu->data.pointer;
1869 u_int8_t *pos;
1870 tpSap_WPSIE pSap_WPSIe;
1871 u_int8_t WPSIeType;
1872 u_int16_t length;
1873 ENTER();
1874
1875 if(!wrqu->data.length)
1876 return 0;
1877
1878 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
1879 if (NULL == pSap_WPSIe)
1880 {
1881 hddLog(LOGE, "VOS unable to allocate memory\n");
1882 return -ENOMEM;
1883 }
1884 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
1885
1886 hddLog(LOG1,"%s WPS IE type[0x%X] IE[0x%X], LEN[%d]\n", __FUNCTION__, wps_genie[0], wps_genie[1], wps_genie[2]);
1887 WPSIeType = wps_genie[0];
1888 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
1889 {
1890 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
1891 wps_genie = wps_genie + 1;
1892 switch ( wps_genie[0] )
1893 {
1894 case DOT11F_EID_WPA:
1895 if (wps_genie[1] < 2 + 4)
1896 {
1897 vos_mem_free(pSap_WPSIe);
1898 return -EINVAL;
1899 }
1900 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
1901 {
1902 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__FUNCTION__, wps_genie[1]+2);
1903 pos = &wps_genie[6];
1904 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
1905 {
1906 switch((u_int16_t)(*pos<<8) | *(pos+1))
1907 {
1908 case HDD_WPS_ELEM_VERSION:
1909 pos += 4;
1910 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
1911 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
1912 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
1913 pos += 1;
1914 break;
1915
1916 case HDD_WPS_ELEM_WPS_STATE:
1917 pos +=4;
1918 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
1919 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
1920 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
1921 pos += 1;
1922 break;
1923 case HDD_WPS_ELEM_APSETUPLOCK:
1924 pos += 4;
1925 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
1926 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
1927 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
1928 pos += 1;
1929 break;
1930 case HDD_WPS_ELEM_SELECTEDREGISTRA:
1931 pos += 4;
1932 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
1933 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
1934 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
1935 pos += 1;
1936 break;
1937 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
1938 pos += 4;
1939 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
1940 hddLog(LOG1, "Password ID: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
1941 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
1942 pos += 2;
1943 break;
1944 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
1945 pos += 4;
1946 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
1947 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
1948 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
1949 pos += 2;
1950 break;
1951
1952 case HDD_WPS_ELEM_UUID_E:
1953 pos += 2;
1954 length = *pos<<8 | *(pos+1);
1955 pos += 2;
1956 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
1957 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
1958 pos += length;
1959 break;
1960 case HDD_WPS_ELEM_RF_BANDS:
1961 pos += 4;
1962 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
1963 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
1964 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
1965 pos += 1;
1966 break;
1967
1968 default:
1969 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)\n", (*pos<<8 | *(pos+1)));
1970 vos_mem_free(pSap_WPSIe);
1971 return -EINVAL;
1972 }
1973 }
1974 }
1975 else {
1976 hddLog (LOGE, "%s WPS IE Mismatch %X",
1977 __FUNCTION__, wps_genie[0]);
1978 }
1979 break;
1980
1981 default:
1982 hddLog (LOGE, "%s Set UNKNOWN IE %X",__FUNCTION__, wps_genie[0]);
1983 vos_mem_free(pSap_WPSIe);
1984 return 0;
1985 }
1986 }
1987 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
1988 {
1989 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
1990 wps_genie = wps_genie + 1;
1991 switch ( wps_genie[0] )
1992 {
1993 case DOT11F_EID_WPA:
1994 if (wps_genie[1] < 2 + 4)
1995 {
1996 vos_mem_free(pSap_WPSIe);
1997 return -EINVAL;
1998 }
1999 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2000 {
2001 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__FUNCTION__, wps_genie[1]+2);
2002 pos = &wps_genie[6];
2003 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2004 {
2005 switch((u_int16_t)(*pos<<8) | *(pos+1))
2006 {
2007 case HDD_WPS_ELEM_VERSION:
2008 pos += 4;
2009 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
2010 hddLog(LOG1, "WPS version %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
2011 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2012 pos += 1;
2013 break;
2014
2015 case HDD_WPS_ELEM_WPS_STATE:
2016 pos +=4;
2017 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
2018 hddLog(LOG1, "WPS State %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
2019 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2020 pos += 1;
2021 break;
2022 case HDD_WPS_ELEM_APSETUPLOCK:
2023 pos += 4;
2024 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
2025 hddLog(LOG1, "AP setup lock %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
2026 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2027 pos += 1;
2028 break;
2029 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2030 pos += 4;
2031 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
2032 hddLog(LOG1, "Selected Registra %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
2033 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2034 pos += 1;
2035 break;
2036 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2037 pos += 4;
2038 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
2039 hddLog(LOG1, "Password ID: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
2040 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2041 pos += 2;
2042 break;
2043 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2044 pos += 4;
2045 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
2046 hddLog(LOG1, "Select Registra Config Methods: %x\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2047 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2048 pos += 2;
2049 break;
2050 case HDD_WPS_ELEM_RSP_TYPE:
2051 pos += 4;
2052 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
2053 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
2054 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2055 pos += 1;
2056 break;
2057 case HDD_WPS_ELEM_UUID_E:
2058 pos += 2;
2059 length = *pos<<8 | *(pos+1);
2060 pos += 2;
2061 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2062 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2063 pos += length;
2064 break;
2065
2066 case HDD_WPS_ELEM_MANUFACTURER:
2067 pos += 2;
2068 length = *pos<<8 | *(pos+1);
2069 pos += 2;
2070 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2071 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2072 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2073 pos += length;
2074 break;
2075
2076 case HDD_WPS_ELEM_MODEL_NAME:
2077 pos += 2;
2078 length = *pos<<8 | *(pos+1);
2079 pos += 2;
2080 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2081 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2082 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2083 pos += length;
2084 break;
2085 case HDD_WPS_ELEM_MODEL_NUM:
2086 pos += 2;
2087 length = *pos<<8 | *(pos+1);
2088 pos += 2;
2089 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2090 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2091 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2092 pos += length;
2093 break;
2094 case HDD_WPS_ELEM_SERIAL_NUM:
2095 pos += 2;
2096 length = *pos<<8 | *(pos+1);
2097 pos += 2;
2098 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2099 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2100 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2101 pos += length;
2102 break;
2103 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2104 pos += 4;
2105 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
2106 hddLog(LOG1, "primary dev category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
2107 pos += 2;
2108
2109 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
2110 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x\n", pos[0], pos[1], pos[2], pos[3]);
2111 pos += 4;
2112 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
2113 hddLog(LOG1, "primary dev sub category: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
2114 pos += 2;
2115 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2116 break;
2117 case HDD_WPS_ELEM_DEVICE_NAME:
2118 pos += 2;
2119 length = *pos<<8 | *(pos+1);
2120 pos += 2;
2121 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2122 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2123 pos += length;
2124 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2125 break;
2126 case HDD_WPS_ELEM_CONFIG_METHODS:
2127 pos += 4;
2128 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
2129 hddLog(LOG1, "Config Methods: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
2130 pos += 2;
2131 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2132 break;
2133
2134 case HDD_WPS_ELEM_RF_BANDS:
2135 pos += 4;
2136 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
2137 hddLog(LOG1, "RF band: %d\n", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
2138 pos += 1;
2139 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2140 break;
2141 } // switch
2142 }
2143 }
2144 else
2145 {
2146 hddLog (LOGE, "%s WPS IE Mismatch %X",__FUNCTION__, wps_genie[0]);
2147 }
2148
2149 } // switch
2150 }
2151 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2152 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2153 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
2154 {
2155 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2156 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
2157 WLANSAP_Update_WpsIe ( pVosContext );
2158 }
2159
2160 vos_mem_free(pSap_WPSIe);
2161 EXIT();
2162 return halStatus;
2163}
2164
2165static int iw_softap_stopbss(struct net_device *dev,
2166 struct iw_request_info *info,
2167 union iwreq_data *wrqu,
2168 char *extra)
2169{
2170 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2171 VOS_STATUS status = VOS_STATUS_SUCCESS;
2172 ENTER();
2173 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
2174 {
2175 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
2176 {
2177 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2178
2179 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2180
2181 if (!VOS_IS_STATUS_SUCCESS(status))
2182 {
2183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2184 ("ERROR: HDD vos wait for single_event failed!!\n"));
2185 VOS_ASSERT(0);
2186 }
2187 }
2188 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2189 }
2190 EXIT();
2191 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
2192}
2193
2194static int iw_softap_version(struct net_device *dev,
2195 struct iw_request_info *info,
2196 union iwreq_data *wrqu,
2197 char *extra)
2198{
2199#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
2200 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2201 VOS_STATUS status;
2202 ENTER();
2203 status = hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
2204 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
2205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n",__func__);
2206 return -EINVAL;
2207 }
2208 EXIT();
2209#endif//TODO need to handle in prima
2210 return 0;
2211}
2212static int iw_set_ap_genie(struct net_device *dev,
2213 struct iw_request_info *info,
2214 union iwreq_data *wrqu,
2215 char *extra)
2216{
2217
2218 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2219 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2220 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2221 u_int8_t *genie = wrqu->data.pointer;
2222
2223 ENTER();
2224
2225 if(!wrqu->data.length)
2226 {
2227 EXIT();
2228 return 0;
2229 }
2230
2231 switch (genie[0])
2232 {
2233 case DOT11F_EID_WPA:
2234 case DOT11F_EID_RSN:
2235 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
2236 {
2237 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
2238 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
2239 }
2240 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
2241 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, wrqu->data.pointer, wrqu->data.length);
2242 break;
2243
2244 default:
2245 hddLog (LOGE, "%s Set UNKNOWN IE %X",__FUNCTION__, genie[0]);
2246 halStatus = 0;
2247 }
2248
2249 EXIT();
2250 return halStatus;
2251}
2252
2253static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
2254{
2255 eHalStatus hstatus;
2256 long lrc;
2257 struct statsContext context;
2258
2259 if (NULL == pAdapter)
2260 {
2261 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Padapter is NULL", __func__);
2262 return VOS_STATUS_E_FAULT;
2263 }
2264
2265 init_completion(&context.completion);
2266 context.pAdapter = pAdapter;
2267 context.magic = STATS_CONTEXT_MAGIC;
2268 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
2269 eCSR_HDD,
2270 SME_GLOBAL_CLASSA_STATS,
2271 hdd_GetClassA_statisticsCB,
2272 0, // not periodic
2273 FALSE, //non-cached results
2274 staid,
2275 &context);
2276 if (eHAL_STATUS_SUCCESS != hstatus)
2277 {
2278 hddLog(VOS_TRACE_LEVEL_ERROR,
2279 "%s: Unable to retrieve statistics for link speed",
2280 __FUNCTION__);
2281 }
2282 else
2283 {
2284 lrc = wait_for_completion_interruptible_timeout(&context.completion,
2285 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2286 context.magic = 0;
2287 if (lrc <= 0)
2288 {
2289 hddLog(VOS_TRACE_LEVEL_ERROR,
2290 "%s: SME %s while retrieving link speed",
2291 __FUNCTION__, (0 == lrc) ? "timeout" : "interrupt");
2292 msleep(50);
2293 }
2294 }
2295 return VOS_STATUS_SUCCESS;
2296}
2297
2298int iw_get_softap_linkspeed(struct net_device *dev,
2299 struct iw_request_info *info,
2300 union iwreq_data *wrqu,
2301 char *extra)
2302
2303{
2304 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2305 char *pLinkSpeed = (char*)extra;
2306 v_U16_t link_speed;
2307 unsigned short staId;
2308 int len = sizeof(v_U16_t)+1;
2309 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
2310 VOS_STATUS status;
2311 int rc;
2312
2313 if ( hdd_string_to_hex ((char *)wrqu->data.pointer, wrqu->data.length, macAddress ) )
2314 {
2315 hddLog(VOS_TRACE_LEVEL_FATAL, "ERROR: Command not found");
2316 return -EINVAL;
2317 }
2318
2319 status = hdd_softap_GetStaId(pHostapdAdapter, (v_MACADDR_t *)macAddress, (void *)(&staId));
2320
2321 if (!VOS_IS_STATUS_SUCCESS(status ))
2322 {
2323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD Failed to find sta id!!\n"));
2324 link_speed = 0;
2325 }
2326 else
2327 {
2328 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
2329 if (!VOS_IS_STATUS_SUCCESS(status ))
2330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve SME statistics", __FUNCTION__);
2332 return -EINVAL;
2333 }
2334 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
2335 }
2336
2337 wrqu->data.length = len;
2338 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
2339 if ((rc < 0) || (rc >= len))
2340 {
2341 // encoding or length error?
2342 hddLog(VOS_TRACE_LEVEL_ERROR,
2343 "%s: Unable to encode link speed, got [%s]",
2344 __FUNCTION__, pLinkSpeed);
2345 return -EIO;
2346 }
2347
2348 return 0;
2349}
2350
2351static const iw_handler hostapd_handler[] =
2352{
2353 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2354 (iw_handler) NULL, /* SIOCGIWNAME */
2355 (iw_handler) NULL, /* SIOCSIWNWID */
2356 (iw_handler) NULL, /* SIOCGIWNWID */
2357 (iw_handler) NULL, /* SIOCSIWFREQ */
2358 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
2359 (iw_handler) NULL, /* SIOCSIWMODE */
2360 (iw_handler) NULL, /* SIOCGIWMODE */
2361 (iw_handler) NULL, /* SIOCSIWSENS */
2362 (iw_handler) NULL, /* SIOCGIWSENS */
2363 (iw_handler) NULL, /* SIOCSIWRANGE */
2364 (iw_handler) NULL, /* SIOCGIWRANGE */
2365 (iw_handler) NULL, /* SIOCSIWPRIV */
2366 (iw_handler) NULL, /* SIOCGIWPRIV */
2367 (iw_handler) NULL, /* SIOCSIWSTATS */
2368 (iw_handler) NULL, /* SIOCGIWSTATS */
2369 (iw_handler) NULL, /* SIOCSIWSPY */
2370 (iw_handler) NULL, /* SIOCGIWSPY */
2371 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2372 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2373 (iw_handler) NULL, /* SIOCSIWAP */
2374 (iw_handler) NULL, /* SIOCGIWAP */
2375 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
2376 (iw_handler) NULL, /* SIOCGIWAPLIST */
2377 (iw_handler) NULL, /* SIOCSIWSCAN */
2378 (iw_handler) NULL, /* SIOCGIWSCAN */
2379 (iw_handler) NULL, /* SIOCSIWESSID */
2380 (iw_handler) NULL, /* SIOCGIWESSID */
2381 (iw_handler) NULL, /* SIOCSIWNICKN */
2382 (iw_handler) NULL, /* SIOCGIWNICKN */
2383 (iw_handler) NULL, /* -- hole -- */
2384 (iw_handler) NULL, /* -- hole -- */
2385 (iw_handler) NULL, /* SIOCSIWRATE */
2386 (iw_handler) NULL, /* SIOCGIWRATE */
2387 (iw_handler) NULL, /* SIOCSIWRTS */
2388 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
2389 (iw_handler) NULL, /* SIOCSIWFRAG */
2390 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
2391 (iw_handler) NULL, /* SIOCSIWTXPOW */
2392 (iw_handler) NULL, /* SIOCGIWTXPOW */
2393 (iw_handler) NULL, /* SIOCSIWRETRY */
2394 (iw_handler) NULL, /* SIOCGIWRETRY */
2395 (iw_handler) NULL, /* SIOCSIWENCODE */
2396 (iw_handler) NULL, /* SIOCGIWENCODE */
2397 (iw_handler) NULL, /* SIOCSIWPOWER */
2398 (iw_handler) NULL, /* SIOCGIWPOWER */
2399 (iw_handler) NULL, /* -- hole -- */
2400 (iw_handler) NULL, /* -- hole -- */
2401 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
2402 (iw_handler) NULL, /* SIOCGIWGENIE */
2403 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
2404 (iw_handler) NULL, /* SIOCGIWAUTH */
2405 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
2406 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
2407 (iw_handler) NULL, /* SIOCSIWPMKSA */
2408};
2409
2410#define IW_PRIV_TYPE_OPTIE IW_PRIV_TYPE_BYTE | QCSAP_MAX_OPT_IE
2411#define IW_PRIV_TYPE_MLME \
2412 IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme)
2413
2414static const struct iw_priv_args hostapd_private_args[] = {
2415 { QCSAP_IOCTL_SETPARAM,
2416 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
2417 { QCSAP_IOCTL_SETPARAM,
2418 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2419 { QCSAP_PARAM_MAX_ASSOC,
2420 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
2421 { QCSAP_PARAM_HIDE_SSID,
2422 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
2423 { QCSAP_IOCTL_GETPARAM,
2424 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2425 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
2426 { QCSAP_IOCTL_GETPARAM, 0,
2427 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2428 { QCSAP_PARAM_MAX_ASSOC, 0,
2429 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
2430 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
2431 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
2432 { QCSAP_PARAM_CLR_ACL, 0,
2433 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
2434 { QCSAP_PARAM_ACL_MODE,
2435 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
2436 { QCSAP_IOCTL_COMMIT,
2437 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
2438 { QCSAP_IOCTL_SETMLME,
2439 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
2440 { QCSAP_IOCTL_GET_STAWPAIE,
2441 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
2442 { QCSAP_IOCTL_SETWPAIE,
2443 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
2444 { QCSAP_IOCTL_STOPBSS,
2445 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
2446 { QCSAP_IOCTL_VERSION, 0,
2447 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
2448 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
2449 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED | 1, 0, "getProbeReqIEs" },
2450 { QCSAP_IOCTL_GET_CHANNEL, 0,
2451 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | sizeof(signed long int), "getchannel" },
2452 { QCSAP_IOCTL_ASSOC_STA_MACADDR, 0,
2453 IW_PRIV_TYPE_BYTE | /*((WLAN_MAX_STA_COUNT*6)+100)*/1 , "get_assoc_stamac" },
2454 { QCSAP_IOCTL_DISASSOC_STA,
2455 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
2456 { QCSAP_IOCTL_AP_STATS,
2457 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
2458 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
2459 IW_PRIV_TYPE_CHAR | 18,
2460 IW_PRIV_TYPE_CHAR | 3, "getLinkSpeed" },
2461
2462 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
2463 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
2464 /* handlers for sub-ioctl */
2465 { WE_SET_WLAN_DBG,
2466 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
2467 0,
2468 "setwlandbg" },
2469
2470 /* handlers for main ioctl */
2471 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
2472 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2473 0,
2474 "" },
2475
2476 /* handlers for sub-ioctl */
2477 { WE_LOG_DUMP_CMD,
2478 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2479 0,
2480 "dump" },
2481#ifdef WLAN_FEATURE_P2P
2482 { WE_P2P_NOA_CMD,
2483 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
2484 0,
2485 "SetP2pPs" },
2486#endif
2487 /* handlers for main ioctl */
2488 { QCSAP_IOCTL_MODIFY_ACL,
2489 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
2490 0,
2491 "modify_acl" },
2492
2493 /* handlers for main ioctl */
2494 { QCSAP_IOCTL_GET_CHANNEL_LIST,
2495 0,
2496 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
2497 "getChannelList" },
2498
2499};
2500static const iw_handler hostapd_private[] = {
2501 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
2502 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
2503 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
2504 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
2505 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
2506 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
2507 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
2508 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
2509 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
2510 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
2511 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
2512 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
2513 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
2514 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
2515 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
2516 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
2517 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
2518 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
2519 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed
2520};
2521const struct iw_handler_def hostapd_handler_def = {
2522 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
2523 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
2524 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
2525 .standard = (iw_handler *)hostapd_handler,
2526 .private = (iw_handler *)hostapd_private,
2527 .private_args = hostapd_private_args,
2528 .get_wireless_stats = NULL,
2529};
2530#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2531struct net_device_ops net_ops_struct = {
2532 .ndo_open = hdd_hostapd_open,
2533 .ndo_stop = hdd_hostapd_stop,
2534 .ndo_uninit = hdd_hostapd_uninit,
2535 .ndo_start_xmit = hdd_softap_hard_start_xmit,
2536 .ndo_tx_timeout = hdd_softap_tx_timeout,
2537 .ndo_get_stats = hdd_softap_stats,
2538 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
2539 .ndo_do_ioctl = hdd_hostapd_ioctl,
2540 .ndo_change_mtu = hdd_hostapd_change_mtu,
2541 .ndo_select_queue = hdd_hostapd_select_queue,
2542 };
2543#endif
2544
2545int hdd_set_hostapd(hdd_adapter_t *pAdapter)
2546{
2547 return VOS_STATUS_SUCCESS;
2548}
2549
2550void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
2551{
2552#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
2553 pWlanHostapdDev->netdev_ops = &net_ops_struct;
2554#else
2555 pWlanHostapdDev->open = hdd_hostapd_open;
2556 pWlanHostapdDev->stop = hdd_hostapd_stop;
2557 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
2558 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
2559 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
2560 pWlanHostapdDev->get_stats = hdd_softap_stats;
2561 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
2562 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
2563#endif
2564}
2565
2566VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
2567{
2568 hdd_hostapd_state_t * phostapdBuf;
2569 struct net_device *dev = pAdapter->dev;
2570 VOS_STATUS status;
2571 ENTER();
2572 // Allocate the Wireless Extensions state structure
2573 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
2574
2575 // Zero the memory. This zeros the profile structure.
2576 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
2577
2578 // Set up the pointer to the Wireless Extensions state structure
2579 // NOP
2580 status = hdd_set_hostapd(pAdapter);
2581 if(!VOS_IS_STATUS_SUCCESS(status)) {
2582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!\n"));
2583 return status;
2584 }
2585
2586 status = vos_event_init(&phostapdBuf->vosEvent);
2587 if (!VOS_IS_STATUS_SUCCESS(status))
2588 {
2589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!\n"));
2590 return status;
2591 }
2592
2593 init_completion(&pAdapter->session_close_comp_var);
2594 init_completion(&pAdapter->session_open_comp_var);
2595
2596 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
2597
2598 // Register as a wireless device
2599 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
2600
2601 //Initialize the data path module
2602 status = hdd_softap_init_tx_rx(pAdapter);
2603 if ( !VOS_IS_STATUS_SUCCESS( status ))
2604 {
2605 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __FUNCTION__);
2606 }
2607
2608#ifdef CONFIG_CFG80211
2609 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
2610#endif
2611#ifdef WLAN_FEATURE_P2P
2612 /* If administrative interface is enabled then one interface being
2613 * created for p2p device address. This will take one HW STA and
2614 * the max number of clients that can connect to softAP will be
2615 * reduced by one. So as soon as SoftAP interface got created remove
2616 * the session for p2p device address.
2617 */
2618 if ( VOS_IS_STATUS_SUCCESS( status ) &&
2619 ( pAdapter->device_mode == WLAN_HDD_SOFTAP ) &&
2620 ( !strncmp( pAdapter->dev->name, "wlan", 4 )) )
2621 {
2622 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2623 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated)
2624 {
2625 INIT_COMPLETION(pAdapter->session_close_comp_var);
2626 if( eHAL_STATUS_SUCCESS == sme_CloseSession( pHddCtx->hHal,
2627 pAdapter->p2pSessionId,
2628 hdd_smeCloseSessionCallback, pAdapter ) )
2629 {
2630 //Block on a completion variable. Can't wait forever though.
2631 wait_for_completion_interruptible_timeout(
2632 &pAdapter->session_close_comp_var,
2633 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
2634 }
2635 }
2636 }
2637#endif
2638 EXIT();
2639 return status;
2640}
2641
2642hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
2643{
2644 struct net_device *pWlanHostapdDev = NULL;
2645 hdd_adapter_t *pHostapdAdapter = NULL;
2646 v_CONTEXT_t pVosContext= NULL;
2647
2648#ifdef CONFIG_CFG80211
2649 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
2650#else
2651 pWlanHostapdDev = alloc_etherdev_mq(sizeof(hdd_adapter_t), NUM_TX_QUEUES);
2652#endif
2653
2654 if (pWlanHostapdDev != NULL)
2655 {
2656 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
2657
2658 //Init the net_device structure
2659 ether_setup(pWlanHostapdDev);
2660
2661 //Initialize the adapter context to zeros.
2662 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
2663 pHostapdAdapter->dev = pWlanHostapdDev;
2664 pHostapdAdapter->pHddCtx = pHddCtx;
2665 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
2666
2667 //Get the Global VOSS context.
2668 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2669 //Save the adapter context in global context for future.
2670 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
2671
2672 //Init the net_device structure
2673 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
2674
2675 hdd_set_ap_ops( pHostapdAdapter->dev );
2676
2677 pWlanHostapdDev->tx_queue_len = NET_DEV_TX_QUEUE_LEN;
2678 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
2679 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
2680
2681 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
2682 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
2683
2684 pWlanHostapdDev->destructor = free_netdev;
2685#ifdef CONFIG_CFG80211
2686 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
2687 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
2688 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
2689 init_completion(&pHostapdAdapter->tx_action_cnf_event);
2690#endif
2691 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
2692 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
2693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2694 init_completion(&pHostapdAdapter->offchannel_tx_event);
2695#endif
2696
2697 init_completion(&pHostapdAdapter->scan_info.scan_req_completion_event);
2698
2699 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
2700 }
2701 return pHostapdAdapter;
2702}
2703
2704VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
2705{
2706 struct net_device *dev = pAdapter->dev;
2707 VOS_STATUS status = VOS_STATUS_SUCCESS;
2708
2709 ENTER();
2710
2711 if( rtnl_lock_held )
2712 {
2713 if (strchr(dev->name, '%')) {
2714 if( dev_alloc_name(dev, dev->name) < 0 )
2715 {
2716 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
2717 return VOS_STATUS_E_FAILURE;
2718 }
2719 }
2720 if (register_netdevice(dev))
2721 {
2722 hddLog(VOS_TRACE_LEVEL_FATAL,
2723 "%s:Failed:register_netdevice", __func__);
2724 return VOS_STATUS_E_FAILURE;
2725 }
2726 }
2727 else
2728 {
2729 if (register_netdev(dev))
2730 {
2731 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
2732 return VOS_STATUS_E_FAILURE;
2733 }
2734 }
2735 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
2736
2737 EXIT();
2738 return status;
2739}
2740
2741VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
2742{
2743 ENTER();
2744
2745 hdd_softap_deinit_tx_rx(pAdapter);
2746
2747 /* if we are being called during driver unload, then the dev has already
2748 been invalidated. if we are being called at other times, then we can
2749 detatch the wireless device handlers */
2750 if (pAdapter->dev)
2751 {
2752 pAdapter->dev->wireless_handlers = NULL;
2753 }
2754 EXIT();
2755 return 0;
2756}