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