blob: 6e4bb7ca15e6e0df85c4e74aa35d91c640892bb5 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
Jeff Johnson295189b2012-06-20 16:38:30 -070027
28/**========================================================================
29
30 \file wlan_hdd_hostapd.c
31 \brief WLAN Host Device Driver implementation
32
33 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
34
35 Qualcomm Confidential and Proprietary.
36
37 ========================================================================*/
38/**=========================================================================
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45 $Header:$ $DateTime: $ $Author: $
46
47
48 when who what, where, why
49 -------- --- --------------------------------------------------------
50 04/5/09 Shailender Created module.
51 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
52 ==========================================================================*/
53/*--------------------------------------------------------------------------
54 Include Files
55 ------------------------------------------------------------------------*/
56
57#include <linux/version.h>
58#include <linux/module.h>
59#include <linux/kernel.h>
60#include <linux/init.h>
61#include <linux/wireless.h>
62#include <linux/semaphore.h>
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -070063#include <linux/compat.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
66#include <linux/etherdevice.h>
67#include <wlan_hdd_includes.h>
68#include <qc_sap_ioctl.h>
69#include <wlan_hdd_hostapd.h>
70#include <sapApi.h>
71#include <sapInternal.h>
72#include <wlan_qct_tl.h>
73#include <wlan_hdd_softap_tx_rx.h>
74#include <wlan_hdd_main.h>
75#include <linux/netdevice.h>
76#include <linux/mmc/sdio_func.h>
77#include "wlan_nlink_common.h"
78#include "wlan_btc_svc.h"
79#include <bap_hdd_main.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070080#include "wlan_hdd_p2p.h"
Leo Chang614d2072013-08-22 14:59:44 -070081#include "cfgApi.h"
82#include "wniCfgAp.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070083
Leo Chang0b0e45a2013-12-15 15:18:55 -080084#ifdef FEATURE_WLAN_CH_AVOID
85#include "wcnss_wlan.h"
86#endif /* FEATURE_WLAN_CH_AVOID */
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Leo Chang0b0e45a2013-12-15 15:18:55 -080090
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define IS_UP(_dev) \
92 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
93#define IS_UP_AUTO(_ic) \
94 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
95#define WE_WLAN_VERSION 1
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -070096#define WE_GET_STA_INFO_SIZE 30
97/* WEXT limition: MAX allowed buf len for any *
98 * IW_PRIV_TYPE_CHAR is 2Kbytes *
99 */
100#define WE_SAP_MAX_STA_INFO 0x7FF
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530102#define SAP_24GHZ_CH_COUNT (14)
Leo Chang614d2072013-08-22 14:59:44 -0700103
Leo Chang0b0e45a2013-12-15 15:18:55 -0800104#ifdef FEATURE_WLAN_CH_AVOID
105/* Channle/Freqency table */
106extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
107safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
108{
109 /*CH , SAFE, default safe */
110 {1 , VOS_TRUE}, //RF_CHAN_1,
111 {2 , VOS_TRUE}, //RF_CHAN_2,
112 {3 , VOS_TRUE}, //RF_CHAN_3,
113 {4 , VOS_TRUE}, //RF_CHAN_4,
114 {5 , VOS_TRUE}, //RF_CHAN_5,
115 {6 , VOS_TRUE}, //RF_CHAN_6,
116 {7 , VOS_TRUE}, //RF_CHAN_7,
117 {8 , VOS_TRUE}, //RF_CHAN_8,
118 {9 , VOS_TRUE}, //RF_CHAN_9,
119 {10 , VOS_TRUE}, //RF_CHAN_10,
120 {11 , VOS_TRUE}, //RF_CHAN_11,
121 {12 , VOS_TRUE}, //RF_CHAN_12,
122 {13 , VOS_TRUE}, //RF_CHAN_13,
123 {14 , VOS_TRUE}, //RF_CHAN_14,
124 {240, VOS_TRUE}, //RF_CHAN_240,
125 {244, VOS_TRUE}, //RF_CHAN_244,
126 {248, VOS_TRUE}, //RF_CHAN_248,
127 {252, VOS_TRUE}, //RF_CHAN_252,
128 {208, VOS_TRUE}, //RF_CHAN_208,
129 {212, VOS_TRUE}, //RF_CHAN_212,
130 {216, VOS_TRUE}, //RF_CHAN_216,
131 {36 , VOS_TRUE}, //RF_CHAN_36,
132 {40 , VOS_TRUE}, //RF_CHAN_40,
133 {44 , VOS_TRUE}, //RF_CHAN_44,
134 {48 , VOS_TRUE}, //RF_CHAN_48,
135 {52 , VOS_TRUE}, //RF_CHAN_52,
136 {56 , VOS_TRUE}, //RF_CHAN_56,
137 {60 , VOS_TRUE}, //RF_CHAN_60,
138 {64 , VOS_TRUE}, //RF_CHAN_64,
139 {100, VOS_TRUE}, //RF_CHAN_100,
140 {104, VOS_TRUE}, //RF_CHAN_104,
141 {108, VOS_TRUE}, //RF_CHAN_108,
142 {112, VOS_TRUE}, //RF_CHAN_112,
143 {116, VOS_TRUE}, //RF_CHAN_116,
144 {120, VOS_TRUE}, //RF_CHAN_120,
145 {124, VOS_TRUE}, //RF_CHAN_124,
146 {128, VOS_TRUE}, //RF_CHAN_128,
147 {132, VOS_TRUE}, //RF_CHAN_132,
148 {136, VOS_TRUE}, //RF_CHAN_136,
149 {140, VOS_TRUE}, //RF_CHAN_140,
150 {149, VOS_TRUE}, //RF_CHAN_149,
151 {153, VOS_TRUE}, //RF_CHAN_153,
152 {157, VOS_TRUE}, //RF_CHAN_157,
153 {161, VOS_TRUE}, //RF_CHAN_161,
154 {165, VOS_TRUE}, //RF_CHAN_165,
155};
156#endif /* FEATURE_WLAN_CH_AVOID */
157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530158/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 * Function definitions
160 *-------------------------------------------------------------------------*/
161/**---------------------------------------------------------------------------
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530162
Jeff Johnson295189b2012-06-20 16:38:30 -0700163 \brief hdd_hostapd_open() - HDD Open function for hostapd interface
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530164
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 This is called in response to ifconfig up
166
167 \param - dev Pointer to net_device structure
168
169 \return - 0 for success non-zero for failure
170
171 --------------------------------------------------------------------------*/
172int hdd_hostapd_open (struct net_device *dev)
173{
174 ENTER();
175
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530176 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
177 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 //Turn ON carrier state
179 netif_carrier_on(dev);
180 //Enable all Tx queues
181 netif_tx_start_all_queues(dev);
182
183 EXIT();
184 return 0;
185}
186/**---------------------------------------------------------------------------
187
188 \brief hdd_hostapd_stop() - HDD stop function for hostapd interface
189
190 This is called in response to ifconfig down
191
192 \param - dev Pointer to net_device structure
193
194 \return - 0 for success non-zero for failure
195
196 --------------------------------------------------------------------------*/
197int hdd_hostapd_stop (struct net_device *dev)
198{
199 ENTER();
200
201 //Stop all tx queues
202 netif_tx_disable(dev);
203
204 //Turn OFF carrier state
205 netif_carrier_off(dev);
206
207 EXIT();
208 return 0;
209}
210/**---------------------------------------------------------------------------
211
212 \brief hdd_hostapd_uninit() - HDD uninit function
213
214 This is called during the netdev unregister to uninitialize all data
215associated with the device
216
217 \param - dev Pointer to net_device structure
218
219 \return - void
220
221 --------------------------------------------------------------------------*/
222static void hdd_hostapd_uninit (struct net_device *dev)
223{
224 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
225
226 ENTER();
227
228 if (pHostapdAdapter && pHostapdAdapter->pHddCtx)
229 {
230 hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter);
231
232 /* after uninit our adapter structure will no longer be valid */
233 pHostapdAdapter->dev = NULL;
234 }
235
236 EXIT();
237}
238
239
240/**============================================================================
241 @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for
242 transmitting packets. There are 2 versions of this function. One that uses
243 locked queue and other that uses lockless queues. Both have been retained to
244 do some performance testing
245 @param skb : [in] pointer to OS packet (sk_buff)
246 @param dev : [in] pointer to Libra network device
247
248 @return : NET_XMIT_DROP if packets are dropped
249 : NET_XMIT_SUCCESS if packet is enqueued succesfully
250 ===========================================================================*/
251int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
252{
253 return 0;
254}
255int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
256{
257 return 0;
258}
259
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700260static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
261 hdd_priv_data_t *priv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -0700262{
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700263 tANI_U8 *command = NULL;
264 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700265
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700266 /*
267 * Note that valid pointers are provided by caller
268 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700269
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700270 if (priv_data->total_len <= 0 ||
271 priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
272 {
273 /* below we allocate one more byte for command buffer.
274 * To avoid addition overflow total_len should be
275 * smaller than INT_MAX. */
276 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
277 __func__, priv_data->total_len);
278 ret = -EFAULT;
279 goto exit;
280 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700282 /* Allocate +1 for '\0' */
283 command = kmalloc((priv_data->total_len + 1), GFP_KERNEL);
284 if (!command)
285 {
286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__);
287 ret = -ENOMEM;
288 goto exit;
289 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700290
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700291 if (copy_from_user(command, priv_data->buf, priv_data->total_len))
292 {
293 ret = -EFAULT;
294 goto exit;
295 }
Mingcheng Zhuc7608ae2013-11-04 15:11:01 -0800296
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700297 /* Make sure the command is NUL-terminated */
298 command[priv_data->total_len] = '\0';
Jeff Johnson295189b2012-06-20 16:38:30 -0700299
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700300 hddLog(VOS_TRACE_LEVEL_INFO,
301 "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700303 if (strncmp(command, "P2P_SET_NOA", 11) == 0)
304 {
305 hdd_setP2pNoa(pAdapter->dev, command);
306 }
307 else if (strncmp(command, "P2P_SET_PS", 10) == 0)
308 {
309 hdd_setP2pOpps(pAdapter->dev, command);
310 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800311#ifdef FEATURE_WLAN_BATCH_SCAN
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700312 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
313 {
314 ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command);
315 }
Rajeev Kumar8b373292014-01-08 20:36:55 -0800316#endif
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700317 else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
318 {
319 /*
320 * command should be a string having format
321 * SET_SAP_CHANNEL_LIST <num channels> <channels seperated by spaces>
322 */
323 hddLog(VOS_TRACE_LEVEL_INFO,
324 "%s: Received Command to Set Preferred Channels for SAP",
325 __func__);
Rajeev Kumar8b373292014-01-08 20:36:55 -0800326
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700327 ret = sapSetPreferredChannel(command);
328 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700329
Jeff Johnson295189b2012-06-20 16:38:30 -0700330exit:
331 if (command)
332 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700333 kfree(command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 }
335 return ret;
336}
337
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -0700338#ifdef CONFIG_COMPAT
339static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
340 struct ifreq *ifr)
341{
342 struct {
343 compat_uptr_t buf;
344 int used_len;
345 int total_len;
346 } compat_priv_data;
347 hdd_priv_data_t priv_data;
348 int ret = 0;
349
350 /*
351 * Note that pAdapter and ifr have already been verified by caller,
352 * and HDD context has also been validated
353 */
354 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
355 sizeof(compat_priv_data))) {
356 ret = -EFAULT;
357 goto exit;
358 }
359 priv_data.buf = compat_ptr(compat_priv_data.buf);
360 priv_data.used_len = compat_priv_data.used_len;
361 priv_data.total_len = compat_priv_data.total_len;
362 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
363 exit:
364 return ret;
365}
366#else /* CONFIG_COMPAT */
367static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
368 struct ifreq *ifr)
369{
370 /* will never be invoked */
371 return 0;
372}
373#endif /* CONFIG_COMPAT */
374
375static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
376{
377 hdd_priv_data_t priv_data;
378 int ret = 0;
379
380 /*
381 * Note that pAdapter and ifr have already been verified by caller,
382 * and HDD context has also been validated
383 */
384 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
385 ret = -EFAULT;
386 } else {
387 ret = hdd_hostapd_driver_command(pAdapter, &priv_data);
388 }
389 return ret;
390}
391
392static int hdd_hostapd_ioctl(struct net_device *dev,
393 struct ifreq *ifr, int cmd)
394{
395 hdd_adapter_t *pAdapter;
396 hdd_context_t *pHddCtx;
397 int ret;
398
399 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
400 if (NULL == pAdapter) {
401 hddLog(VOS_TRACE_LEVEL_ERROR,
402 "%s: HDD adapter context is Null", __func__);
403 ret = -ENODEV;
404 goto exit;
405 }
406 if (dev != pAdapter->dev) {
407 hddLog(VOS_TRACE_LEVEL_ERROR,
408 "%s: HDD adapter/dev inconsistency", __func__);
409 ret = -ENODEV;
410 goto exit;
411 }
412
413 if ((!ifr) || (!ifr->ifr_data)) {
414 ret = -EINVAL;
415 goto exit;
416 }
417
418 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
419 ret = wlan_hdd_validate_context(pHddCtx);
420 if (ret) {
421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__);
422 ret = -EBUSY;
423 goto exit;
424 }
425
426 switch (cmd) {
427 case (SIOCDEVPRIVATE + 1):
428 if (is_compat_task())
429 ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
430 else
431 ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
432 break;
433 default:
434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
435 __func__, cmd);
436 ret = -EINVAL;
437 break;
438 }
439 exit:
440 return ret;
441}
442
Jeff Johnson295189b2012-06-20 16:38:30 -0700443/**---------------------------------------------------------------------------
444
445 \brief hdd_hostapd_set_mac_address() -
446 This function sets the user specified mac address using
447 the command ifconfig wlanX hw ether <mac adress>.
448
449 \param - dev - Pointer to the net device.
450 - addr - Pointer to the sockaddr.
451 \return - 0 for success, non zero for failure
452
453 --------------------------------------------------------------------------*/
454
455static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
456{
457 struct sockaddr *psta_mac_addr = addr;
458 ENTER();
459 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
460 EXIT();
461 return 0;
462}
463void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
464{
465 struct net_device *dev = (struct net_device *)usrDataForCallback;
466 v_BYTE_t we_custom_event[64];
467 union iwreq_data wrqu;
468#ifdef DISABLE_CONCURRENCY_AUTOSAVE
469 VOS_STATUS vos_status;
470 hdd_adapter_t *pHostapdAdapter;
471 hdd_ap_ctx_t *pHddApCtx;
472#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
473
474 /* event_name space-delimiter driver_module_name */
475 /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
476 char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
477 int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */
478
479 ENTER();
480
481#ifdef DISABLE_CONCURRENCY_AUTOSAVE
482 if (vos_concurrent_sessions_running())
483 {
484 /*
485 This timer routine is going to be called only when AP
486 persona is up.
487 If there are concurrent sessions running we do not want
488 to shut down the Bss.Instead we run the timer again so
489 that if Autosave is enabled next time and other session
490 was down only then we bring down AP
491 */
492 pHostapdAdapter = netdev_priv(dev);
493 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
494 vos_status = vos_timer_start(
495 &pHddApCtx->hdd_ap_inactivity_timer,
496 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
497 * 1000);
498 if (!VOS_IS_STATUS_SUCCESS(vos_status))
499 {
500 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
501 }
502 EXIT();
503 return;
504 }
505#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
506 memset(&we_custom_event, '\0', sizeof(we_custom_event));
507 memcpy(&we_custom_event, autoShutEvent, event_len);
508
509 memset(&wrqu, 0, sizeof(wrqu));
510 wrqu.data.length = event_len;
511
512 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
513 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
514
515 EXIT();
516}
517
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800518VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
519{
520 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
521 ptSapContext pSapCtx = NULL;
522 eHalStatus halStatus = eHAL_STATUS_FAILURE;
523 v_PVOID_t hHal = NULL;
524
525 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
526 "%s: UPDATE Beacon Params", __func__);
527
528 if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
529 pSapCtx = VOS_GET_SAP_CB(pVosContext);
530 if ( NULL == pSapCtx )
531 {
532 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
533 "%s: Invalid SAP pointer from pvosGCtx", __func__);
534 return VOS_STATUS_E_FAULT;
535 }
536
537 hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
538 if ( NULL == hHal ){
539 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
540 "%s: Invalid HAL pointer from pvosGCtx", __func__);
541 return VOS_STATUS_E_FAULT;
542 }
543 halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
544 if(halStatus == eHAL_STATUS_FAILURE ){
545 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
546 "%s: Failed to update Beacon Params", __func__);
547 return VOS_STATUS_E_FAILURE;
548 }
549 }
550 return VOS_STATUS_SUCCESS;
551}
552
553void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
554{
555 v_U8_t staId = 0;
556 struct net_device *dev;
557 dev = (struct net_device *)usrDataForCallback;
558
Arif Hussain6d2a3322013-11-17 19:50:10 -0800559 hddLog(LOGE, FL("Clearing all the STA entry...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800560 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
561 {
562 if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
563 ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
564 {
565 //Disconnect all the stations
566 hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
567 }
568 }
569}
570
571static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
572{
573 struct net_device *dev;
574 VOS_STATUS status = VOS_STATUS_SUCCESS;
575 dev = (struct net_device *)usrDataForCallback;
576 ENTER();
577 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
578 {
579 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
580 {
581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
582 }
583 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
584 }
585 EXIT();
586 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
587}
Jeff Johnson295189b2012-06-20 16:38:30 -0700588
589VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
590{
591 hdd_adapter_t *pHostapdAdapter;
592 hdd_ap_ctx_t *pHddApCtx;
593 hdd_hostapd_state_t *pHostapdState;
594 struct net_device *dev;
595 eSapHddEvent sapEvent;
596 union iwreq_data wrqu;
597 v_BYTE_t *we_custom_event_generic = NULL;
598 int we_event = 0;
599 int i = 0;
600 v_U8_t staId;
601 VOS_STATUS vos_status;
602 v_BOOL_t bWPSState;
603 v_BOOL_t bApActive = FALSE;
604 v_BOOL_t bAuthRequired = TRUE;
605 tpSap_AssocMacAddr pAssocStasArray = NULL;
606 char unknownSTAEvent[IW_CUSTOM_MAX+1];
607 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
608 v_BYTE_t we_custom_start_event[64];
609 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800610 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800611 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700612 struct iw_michaelmicfailure msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700613
614 dev = (struct net_device *)usrDataForCallback;
615 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530616
617 if ((NULL == pHostapdAdapter) ||
618 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
619 {
620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
621 "invalid adapter or adapter has invalid magic");
622 return eHAL_STATUS_FAILURE;
623 }
624
Jeff Johnson295189b2012-06-20 16:38:30 -0700625 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
626 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
627 sapEvent = pSapEvent->sapHddEventCode;
628 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800629 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700630
631 switch(sapEvent)
632 {
633 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800634 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700635 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
636 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
637 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
638
639 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
640 vos_status = vos_event_set(&pHostapdState->vosEvent);
641
642 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
643 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700645 goto stopbss;
646 }
647 else
648 {
649 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
650 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530651 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
652 if (!VOS_IS_STATUS_SUCCESS(vos_status))
653 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 }
655
656 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
657 {
658 // AP Inactivity timer init and start
659 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
660 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
661 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800662 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700663
664 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
665 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800666 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700667
668 }
669 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
670 pHostapdState->bssState = BSS_START;
671
672 // Send current operating channel of SoftAP to BTC-ES
673 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
674
Jeff Johnson295189b2012-06-20 16:38:30 -0700675 //Check if there is any group key pending to set.
676 if( pHddApCtx->groupKey.keyLength )
677 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700678 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700679 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
680 &pHddApCtx->groupKey ) )
681 {
682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
683 "%s: WLANSAP_SetKeySta failed", __func__);
684 }
685 pHddApCtx->groupKey.keyLength = 0;
686 }
687 else if ( pHddApCtx->wepKey[0].keyLength )
688 {
689 int i=0;
690 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
691 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700692 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
694 &pHddApCtx->wepKey[i] ) )
695 {
696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
697 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
698 }
699 pHddApCtx->wepKey[i].keyLength = 0;
700 }
701 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
703 startBssEvent = "SOFTAP.enabled";
704 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
705 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
706 memset(&wrqu, 0, sizeof(wrqu));
707 wrqu.data.length = strlen(startBssEvent);
708 we_event = IWEVCUSTOM;
709 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700710 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 break; //Event will be sent after Switch-Case stmt
712
713 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800714 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700715 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
716
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700717 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700718 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700719
Jeff Johnson295189b2012-06-20 16:38:30 -0700720 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700721 goto stopbss;
722 case eSAP_STA_SET_KEY_EVENT:
723 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800724 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
726 return VOS_STATUS_SUCCESS;
727 case eSAP_STA_DEL_KEY_EVENT:
728 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800729 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 return VOS_STATUS_SUCCESS;
731 case eSAP_STA_MIC_FAILURE_EVENT:
732 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 memset(&msg, '\0', sizeof(msg));
734 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800735 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800736 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700737 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 msg.flags = IW_MICFAILURE_GROUP;
739 else
740 msg.flags = IW_MICFAILURE_PAIRWISE;
741 memset(&wrqu, 0, sizeof(wrqu));
742 wrqu.data.length = sizeof(msg);
743 we_event = IWEVMICHAELMICFAILURE;
744 we_custom_event_generic = (v_BYTE_t *)&msg;
745 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 /* inform mic failure to nl80211 */
747 cfg80211_michael_mic_failure(dev,
748 pSapEvent->sapevt.
749 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700750 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700751 NL80211_KEYTYPE_GROUP :
752 NL80211_KEYTYPE_PAIRWISE),
753 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
754 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
755 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700756 break;
757
758 case eSAP_STA_ASSOC_EVENT:
759 case eSAP_STA_REASSOC_EVENT:
760 wrqu.addr.sa_family = ARPHRD_ETHER;
761 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800762 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800763 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 we_event = IWEVREGISTERED;
765
766 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
767
768 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
769 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
770 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
771 {
772 bAuthRequired = FALSE;
773 }
774
775 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
776 {
c_hpothuffdb5272013-10-02 16:42:35 +0530777 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 TRUE,
779 pHddApCtx->uPrivacy,
780 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
781 0,
782 0,
783 (v_MACADDR_t *)wrqu.addr.sa_data,
784 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530785
786 if (!VOS_IS_STATUS_SUCCESS(vos_status))
787 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
788 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700789 }
790 else
791 {
c_hpothuffdb5272013-10-02 16:42:35 +0530792 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 FALSE,
794 pHddApCtx->uPrivacy,
795 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
796 0,
797 0,
798 (v_MACADDR_t *)wrqu.addr.sa_data,
799 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530800 if (!VOS_IS_STATUS_SUCCESS(vos_status))
801 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
802 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Amar Singhal6144c002013-05-03 16:11:42 -0700803 }
804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 // Stop AP inactivity timer
806 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
807 {
808 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
809 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800810 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700811 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800812#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800813 if (wake_lock_active(&pHddCtx->sap_wake_lock))
814 {
815 wake_unlock(&pHddCtx->sap_wake_lock);
816 }
Amar Singhal6144c002013-05-03 16:11:42 -0700817 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
820 {
821 struct station_info staInfo;
822 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
823
824 memset(&staInfo, 0, sizeof(staInfo));
825 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
826 {
827 staInfo.assoc_req_ies =
828 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
829 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700831 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
832#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 cfg80211_new_sta(dev,
834 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
835 &staInfo, GFP_KERNEL);
836 }
837 else
838 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800839 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 }
841 }
842#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800843 pScanInfo = &pHddCtx->scan_info;
844 // Lets do abort scan to ensure smooth authentication for client
845 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
846 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530847 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
848 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800849 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700850
851 break;
852 case eSAP_STA_DISASSOC_EVENT:
853 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800854 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800855 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700856 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
857 hddLog(LOG1," User initiated disassociation");
858 else
859 hddLog(LOG1," MAC initiated disassociation");
860 we_event = IWEVEXPIRED;
861 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
862 if (!VOS_IS_STATUS_SUCCESS(vos_status))
863 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700864 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 -0700865 return VOS_STATUS_E_FAILURE;
866 }
867 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
868
869 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
870 {
871 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
872 // Start AP inactivity timer if no stations associated with it
873 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
874 {
875 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
876 {
877 bApActive = TRUE;
878 break;
879 }
880 }
881 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
882
883 if (bApActive == FALSE)
884 {
885 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
886 {
887 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
888 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800889 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 }
891 else
892 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
893 }
894 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
896 cfg80211_del_sta(dev,
897 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
898 GFP_KERNEL);
899#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800900 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +0530901 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
902 if (VOS_STATUS_SUCCESS != vos_status)
903 {
904 hddLog(LOGE, "%s: failed to update Beacon interval %d",
905 __func__, vos_status);
906 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 break;
908 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
909 {
910 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
911 union iwreq_data wreq;
912
913 down(&pHddApCtx->semWpsPBCOverlapInd);
914 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
915
916 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
917 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
918
919 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800920 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700921 memset(&wreq, 0, sizeof(wreq));
922 wreq.data.length = strlen(message); // This is length of message
923 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
924
925 return VOS_STATUS_SUCCESS;
926 }
927 case eSAP_ASSOC_STA_CALLBACK_EVENT:
928 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
929 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
930 { // List of associated stations
931 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
932 {
933 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
934 i+1,
935 pAssocStasArray->assocId,
936 pAssocStasArray->staId,
937 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
938 pAssocStasArray++;
939 }
940 }
941 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800942 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700943 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 case eSAP_INDICATE_MGMT_FRAME:
945 hdd_indicateMgmtFrame( pHostapdAdapter,
946 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
947 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
948 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530949 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 return VOS_STATUS_SUCCESS;
951 case eSAP_REMAIN_CHAN_READY:
952 hdd_remainChanReadyHandler( pHostapdAdapter );
953 return VOS_STATUS_SUCCESS;
954 case eSAP_SEND_ACTION_CNF:
955 hdd_sendActionCnf( pHostapdAdapter,
956 ( eSAP_STATUS_SUCCESS ==
957 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
958 TRUE : FALSE );
959 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 case eSAP_UNKNOWN_STA_JOIN:
961 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
962 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
963 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
964 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
965 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
966 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
967 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
968 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
969 wrqu.data.pointer = unknownSTAEvent;
970 wrqu.data.length = strlen(unknownSTAEvent);
971 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +0530972 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 break;
974
975 case eSAP_MAX_ASSOC_EXCEEDED:
976 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
977 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
978 " one or more devices to enable the new device connection",
979 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
980 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
981 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
982 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
983 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
984 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
985 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
986 wrqu.data.pointer = maxAssocExceededEvent;
987 wrqu.data.length = strlen(maxAssocExceededEvent);
988 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -0800989 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 break;
991 case eSAP_STA_ASSOC_IND:
992 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800993
994 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800995 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800996 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
997 return VOS_STATUS_SUCCESS;
998
999 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
c_hpothuffdb5272013-10-02 16:42:35 +05301000 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1001 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1002 {
1003 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1004 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001005 return VOS_STATUS_SUCCESS;
1006
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001008 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 goto stopbss;
1010 return VOS_STATUS_SUCCESS;
1011 }
1012 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1013 return VOS_STATUS_SUCCESS;
1014
1015stopbss :
1016 {
1017 v_BYTE_t we_custom_event[64];
1018 char *stopBssEvent = "STOP-BSS.response";//17
1019 int event_len = strlen(stopBssEvent);
1020
1021 hddLog(LOG1, FL("BSS stop status = %s"),
1022 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1023 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1024
1025 /* Change the BSS state now since, as we are shutting things down,
1026 * we don't want interfaces to become re-enabled */
1027 pHostapdState->bssState = BSS_STOP;
1028
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301029 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1030 {
1031 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1032 {
1033 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1034 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1035 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1036 }
1037
1038 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1039 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1040 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1041 }
1042
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 /* Stop the pkts from n/w stack as we are going to free all of
1044 * the TX WMM queues for all STAID's */
1045 hdd_hostapd_stop(dev);
1046
1047 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301048 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1049 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1050 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001051
Amar Singhal37e6f052013-03-05 16:16:54 -08001052 /* once the event is set, structure dev/pHostapdAdapter should
1053 * not be touched since they are now subject to being deleted
1054 * by another thread */
1055 if (eSAP_STOP_BSS_EVENT == sapEvent)
1056 vos_event_set(&pHostapdState->vosEvent);
1057
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 /* notify userspace that the BSS has stopped */
1059 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1060 memcpy(&we_custom_event, stopBssEvent, event_len);
1061 memset(&wrqu, 0, sizeof(wrqu));
1062 wrqu.data.length = event_len;
1063 we_event = IWEVCUSTOM;
1064 we_custom_event_generic = we_custom_event;
1065 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001066 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 }
1068 return VOS_STATUS_SUCCESS;
1069}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001070
1071int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001073 eCsrEncryptionType *pEncryptType,
1074 eCsrEncryptionType *mcEncryptType,
1075 eCsrAuthType *pAuthType,
1076 v_BOOL_t *pMFPCapable,
1077 v_BOOL_t *pMFPRequired,
1078 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 u_int8_t *gen_ie )
1080{
1081 tDot11fIERSN dot11RSNIE;
1082 tDot11fIEWPA dot11WPAIE;
1083
1084 tANI_U8 *pRsnIe;
1085 tANI_U16 RSNIeLen;
1086
1087 if (NULL == halHandle)
1088 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001089 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 return -EINVAL;
1091 }
1092
1093 // Validity checks
1094 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1095 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1096 return -EINVAL;
1097 // Type check
1098 if ( gen_ie[0] == DOT11F_EID_RSN)
1099 {
1100 // Validity checks
1101 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1102 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1103 {
1104 return VOS_STATUS_E_FAILURE;
1105 }
1106 // Skip past the EID byte and length byte
1107 pRsnIe = gen_ie + 2;
1108 RSNIeLen = gen_ie_len - 2;
1109 // Unpack the RSN IE
1110 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1111 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1112 pRsnIe,
1113 RSNIeLen,
1114 &dot11RSNIE);
1115 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001116 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001117 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001118 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001119 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 /*Here we have followed the apple base code,
1121 but probably I suspect we can do something different*/
1122 //dot11RSNIE.akm_suite_count
1123 // Just translate the FIRST one
1124 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1125 //dot11RSNIE.pwise_cipher_suite_count
1126 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1127 //dot11RSNIE.gp_cipher_suite_count
1128 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1129 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001130 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1131 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001132
1133 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1134 } else
1135 if (gen_ie[0] == DOT11F_EID_WPA)
1136 {
1137 // Validity checks
1138 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1139 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1140 {
1141 return VOS_STATUS_E_FAILURE;
1142 }
1143 // Skip past the EID byte and length byte - and four byte WiFi OUI
1144 pRsnIe = gen_ie + 2 + 4;
1145 RSNIeLen = gen_ie_len - (2 + 4);
1146 // Unpack the WPA IE
1147 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1148 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1149 pRsnIe,
1150 RSNIeLen,
1151 &dot11WPAIE);
1152 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001153 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001154 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001155 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001156 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 //dot11WPAIE.auth_suite_count
1158 // Just translate the FIRST one
1159 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1160 //dot11WPAIE.unicast_cipher_count
1161 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1162 //dot11WPAIE.unicast_cipher_count
1163 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001164 *pMFPCapable = VOS_FALSE;
1165 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 }
1167 else
1168 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001169 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 return VOS_STATUS_E_FAILURE;
1171 }
1172 return VOS_STATUS_SUCCESS;
1173}
Leo Chang614d2072013-08-22 14:59:44 -07001174
Leo Chang0b0e45a2013-12-15 15:18:55 -08001175#ifdef FEATURE_WLAN_CH_AVOID
1176/**---------------------------------------------------------------------------
1177
1178 \brief hdd_hostapd_freq_to_chn() -
1179
1180 Input frequency translated into channel number
1181
1182 \param - freq input frequency with order of kHz
1183
1184 \return - corresponding channel number.
1185 incannot find correct channel number, return 0
1186
1187 --------------------------------------------------------------------------*/
1188v_U16_t hdd_hostapd_freq_to_chn
1189(
1190 v_U16_t freq
1191)
1192{
1193 int loop;
1194
1195 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1196 {
1197 if (rfChannels[loop].targetFreq == freq)
1198 {
1199 return rfChannels[loop].channelNum;
1200 }
1201 }
1202
1203 return (0);
1204}
1205
1206/*==========================================================================
1207 FUNCTION sapUpdateUnsafeChannelList
1208
1209 DESCRIPTION
1210 Function Undate unsafe channel list table
1211
1212 DEPENDENCIES
1213 NA.
1214
1215 PARAMETERS
1216
1217 IN
1218 pSapCtx : SAP context pointer, include unsafe channel list
1219
1220 RETURN VALUE
1221 NONE
1222============================================================================*/
1223void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1224 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1225{
1226 v_U16_t i, j;
1227
1228 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1229 sizeof(pHddCtx->unsafeChannelList));
1230 if (0 == unsafeChannelCount)
1231 {
1232 pHddCtx->unsafeChannelCount = 0;
1233 }
1234 else
1235 {
1236 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1237 unsafeChannelList,
1238 unsafeChannelCount * sizeof(tANI_U16));
1239 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1240 }
1241
1242 /* Flush, default set all channel safe */
1243 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1244 {
1245 safeChannels[i].isSafe = VOS_TRUE;
1246 }
1247
1248 /* Try to find unsafe channel */
1249 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1250 {
1251 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1252 {
1253 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1254 {
1255 /* Found unsafe channel, update it */
1256 safeChannels[j].isSafe = VOS_FALSE;
1257 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1258 "%s : CH %d is not safe",
1259 __func__, pHddCtx->unsafeChannelList[i]);
1260 break;
1261 }
1262 }
1263 }
1264
1265 return;
1266}
1267
1268/**---------------------------------------------------------------------------
1269
1270 \brief hdd_hostapd_ch_avoid_cb() -
1271
1272 Avoid channel notification from FW handler.
1273 FW will send un-safe channle list to avoid overwrapping.
1274 hostapd should not use notified channel
1275
1276 \param - pAdapter HDD adapter pointer
1277 indParam channel avoid notification parameter
1278
1279 \return - None
1280
1281 --------------------------------------------------------------------------*/
1282void hdd_hostapd_ch_avoid_cb
1283(
1284 void *pAdapter,
1285 void *indParam
1286)
1287{
1288 hdd_adapter_t *pHostapdAdapter = NULL;
1289 hdd_context_t *hddCtxt;
1290 tSirChAvoidIndType *chAvoidInd;
1291 v_U8_t rangeLoop;
1292 v_U16_t channelLoop;
1293 v_U16_t dupCheck;
1294 v_U16_t startChannel;
1295 v_U16_t endChannel;
1296 v_U16_t unsafeChannelCount = 0;
1297 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1298 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001299 tHddAvoidFreqList hddAvoidFreqList;
1300 tANI_U32 i;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001301
1302 /* Basic sanity */
1303 if ((NULL == pAdapter) || (NULL == indParam))
1304 {
1305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1306 "%s : Invalid arguments", __func__);
1307 return;
1308 }
1309
1310 hddCtxt = (hdd_context_t *)pAdapter;
1311 chAvoidInd = (tSirChAvoidIndType *)indParam;
1312 pVosContext = hddCtxt->pvosContext;
1313
1314 /* Make unsafe channel list */
1315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1316 "%s : band count %d",
1317 __func__, chAvoidInd->avoidRangeCount);
1318 vos_mem_zero((void *)unsafeChannelList,
1319 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1320 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1321 {
1322 startChannel = hdd_hostapd_freq_to_chn(
1323 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1324 endChannel = hdd_hostapd_freq_to_chn(
1325 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1327 "%s : start %d : %d, end %d : %d",
1328 __func__,
1329 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1330 startChannel,
1331 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1332 endChannel);
1333 for (channelLoop = startChannel;
1334 channelLoop < (endChannel + 1);
1335 channelLoop++)
1336 {
1337 /* Channel duplicate check routine */
1338 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1339 {
1340 if (unsafeChannelList[dupCheck] == channelLoop)
1341 {
1342 /* This channel is duplicated */
1343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1344 "%s : found duplicated channel %d",
1345 __func__, channelLoop);
1346 break;
1347 }
1348 }
1349 if (dupCheck == unsafeChannelCount)
1350 {
1351 unsafeChannelList[unsafeChannelCount] = channelLoop;
1352 unsafeChannelCount++;
1353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1354 "%s : unsafe channel %d, count %d",
1355 __func__,
1356 channelLoop, unsafeChannelCount);
1357 }
1358 else
1359 {
1360 /* DUP, do nothing */
1361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1362 "%s : duplicated channel %d",
1363 __func__, channelLoop);
1364 }
1365 }
1366 }
1367 /* Update unsafe channel cache
1368 * WCN Platform Driver cache */
1369 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1370 unsafeChannelCount);
1371
1372 /* Store into local cache
1373 * Start with STA and later start SAP
1374 * in this scenario, local cache will be used */
1375 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1376 unsafeChannelList,
1377 unsafeChannelCount);
1378
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001379 /* generate vendor specific event */
1380 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1381 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1382 {
1383 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1384 chAvoidInd->avoidFreqRange[i].startFreq;
1385 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1386 chAvoidInd->avoidFreqRange[i].endFreq;
1387 }
1388 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1389
1390 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1391
Leo Chang0b0e45a2013-12-15 15:18:55 -08001392 /* Get SAP context first
1393 * SAP and P2PGO would not concurrent */
1394 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
1395 if ((pHostapdAdapter) && (unsafeChannelCount))
1396 {
1397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1398 "%s : Current operation channel %d",
1399 __func__,
1400 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1401 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1402 {
1403 if (((unsafeChannelList[channelLoop] ==
1404 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1405 (AUTO_CHANNEL_SELECT ==
1406 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1407 {
1408 /* current operating channel is un-safe channel
1409 * restart driver */
1410 hdd_hostapd_stop(pHostapdAdapter->dev);
1411 break;
1412 }
1413 }
1414 }
1415
1416 return;
1417}
1418
1419#endif /* FEATURE_WLAN_CH_AVOID */
1420
Jeff Johnson295189b2012-06-20 16:38:30 -07001421int
1422static iw_softap_setparam(struct net_device *dev,
1423 struct iw_request_info *info,
1424 union iwreq_data *wrqu, char *extra)
1425{
1426 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001427 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 int *value = (int *)extra;
1429 int sub_cmd = value[0];
1430 int set_value = value[1];
1431 eHalStatus status;
1432 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001433 v_CONTEXT_t pVosContext;
1434
1435 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1436 {
1437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1438 "%s: either hostapd Adapter is null or HDD ctx is null",
1439 __func__);
1440 return -1;
1441 }
1442
1443 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1444 if (!hHal)
1445 {
1446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1447 "%s: Hal ctx is null", __func__);
1448 return -1;
1449 }
1450
1451 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1452 if (!pVosContext)
1453 {
1454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1455 "%s: Vos ctx is null", __func__);
1456 return -1;
1457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001458
1459 switch(sub_cmd)
1460 {
1461
1462 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001463 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001464 {
1465 ret = -EIO;
1466 }
1467 break;
1468
1469 case QCSAP_PARAM_ACL_MODE:
1470 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1471 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1472 {
1473 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1474 ret = -EINVAL;
1475 }
1476 else
1477 {
1478 WLANSAP_SetMode(pVosContext, set_value);
1479 }
1480 break;
1481 case QCSAP_PARAM_MAX_ASSOC:
1482 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1483 {
1484 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1485 ret = -EINVAL;
1486 }
1487 else
1488 {
1489 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1490 {
1491 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1492 "Setting it to max allowed and continuing"),
1493 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1494 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1495 }
1496 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1497 set_value, NULL, eANI_BOOLEAN_FALSE);
1498 if ( status != eHAL_STATUS_SUCCESS )
1499 {
1500 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1501 status);
1502 ret = -EIO;
1503 }
1504 }
1505 break;
1506
1507 case QCSAP_PARAM_HIDE_SSID:
1508 {
1509 eHalStatus status = eHAL_STATUS_SUCCESS;
1510 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1511 if(eHAL_STATUS_SUCCESS != status)
1512 {
1513 hddLog(VOS_TRACE_LEVEL_ERROR,
1514 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001515 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001516 return status;
1517 }
1518 break;
1519 }
1520
Leo Chang614d2072013-08-22 14:59:44 -07001521 case QCSAP_PARAM_SET_MC_RATE:
1522 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001523 tSirRateUpdateInd *rateUpdate;
1524
1525 rateUpdate = (tSirRateUpdateInd *)
1526 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1527 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001528 {
1529 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001530 "%s: SET_MC_RATE indication alloc fail", __func__);
1531 ret = -1;
1532 break;
1533 }
1534 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1535
1536 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1537 /* Ignore unicast */
1538 rateUpdate->ucastDataRate = -1;
1539 rateUpdate->mcastDataRate24GHz = set_value;
1540 rateUpdate->mcastDataRate5GHz = set_value;
1541 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1542 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1543 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1544 if (eHAL_STATUS_SUCCESS != status)
1545 {
1546 hddLog(VOS_TRACE_LEVEL_ERROR,
1547 "%s: SET_MC_RATE failed", __func__);
1548 vos_mem_free(rateUpdate);
1549 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001550 }
1551 break;
1552 }
1553
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 default:
1555 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1556 sub_cmd, set_value);
1557 ret = -EINVAL;
1558 break;
1559 }
1560
1561 return ret;
1562}
1563
1564
1565int
1566static iw_softap_getparam(struct net_device *dev,
1567 struct iw_request_info *info,
1568 union iwreq_data *wrqu, char *extra)
1569{
1570 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1571 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1572 int *value = (int *)extra;
1573 int sub_cmd = value[0];
1574 eHalStatus status;
1575 int ret = 0; /* success */
1576 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1577
1578 switch (sub_cmd)
1579 {
1580 case QCSAP_PARAM_MAX_ASSOC:
1581 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1582 if (eHAL_STATUS_SUCCESS != status)
1583 {
c_hpothuffdb5272013-10-02 16:42:35 +05301584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1585 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001586 ret = -EIO;
1587 }
1588 break;
1589
1590 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001591 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001592 {
c_hpothuffdb5272013-10-02 16:42:35 +05301593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1594 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001595 ret = -EIO;
1596 }
1597 *value = 0;
1598 break;
1599
1600 case QCSAP_PARAM_MODULE_DOWN_IND:
1601 {
1602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001603 "%s: sending WLAN_MODULE_DOWN_IND", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001604 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1605#ifdef WLAN_BTAMP_FEATURE
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001607 "%s: Take down AMP PAL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
1609#endif
1610 *value = 0;
1611 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001612 }
1613
1614 case QCSAP_PARAM_GET_WLAN_DBG:
1615 {
1616 vos_trace_display();
1617 *value = 0;
1618 break;
1619 }
1620
1621 case QCSAP_PARAM_AUTO_CHANNEL:
1622 {
1623 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1624 break;
1625 }
1626
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 default:
1628 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1629 ret = -EINVAL;
1630 break;
1631
1632 }
1633
1634 return ret;
1635}
1636
1637/* Usage:
1638 BLACK_LIST = 0
1639 WHITE_LIST = 1
1640 ADD MAC = 0
1641 REMOVE MAC = 1
1642
1643 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1644 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1645 while using this ioctl
1646
1647 Syntax:
1648 iwpriv softap.0 modify_acl
1649 <6 octet mac addr> <list type> <cmd type>
1650
1651 Examples:
1652 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1653 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1654 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1655 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1656*/
1657int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1658 union iwreq_data *wrqu, char *extra)
1659{
1660 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1661 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1662 v_BYTE_t *value = (v_BYTE_t*)extra;
1663 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1664 int listType, cmd, i;
1665 int ret = 0; /* success */
1666
1667 ENTER();
1668 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1669 {
1670 pPeerStaMac[i] = *(value+i);
1671 }
1672 listType = (int)(*(value+i));
1673 i++;
1674 cmd = (int)(*(value+i));
1675
Arif Hussain24bafea2013-11-15 15:10:03 -08001676 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1677 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001678
1679 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1680 != VOS_STATUS_SUCCESS)
1681 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001682 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001683 ret = -EIO;
1684 }
1685 EXIT();
1686 return ret;
1687}
1688
1689int
1690static iw_softap_getchannel(struct net_device *dev,
1691 struct iw_request_info *info,
1692 union iwreq_data *wrqu, char *extra)
1693{
1694 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1695
Jeff Johnson43971f52012-07-17 12:26:56 -07001696 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001697
Jeff Johnson43971f52012-07-17 12:26:56 -07001698 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001699 return 0;
1700}
1701
Jeff Johnsone7245742012-09-05 17:12:55 -07001702int
schang86c22c42013-03-13 18:41:24 -07001703static iw_softap_set_max_tx_power(struct net_device *dev,
Jeff Johnsone7245742012-09-05 17:12:55 -07001704 struct iw_request_info *info,
1705 union iwreq_data *wrqu, char *extra)
1706{
1707 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1708 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001709 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001710 int set_value;
1711 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1712 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1713
schang86c22c42013-03-13 18:41:24 -07001714 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001715 return -ENOMEM;
1716
Leo Changd37675a2013-08-01 13:19:45 -07001717 /* Assign correct slef MAC address */
1718 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1719 VOS_MAC_ADDR_SIZE);
1720 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1721 VOS_MAC_ADDR_SIZE);
1722
schang86c22c42013-03-13 18:41:24 -07001723 set_value = value[0];
1724 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1725 {
1726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001727 __func__);
schang86c22c42013-03-13 18:41:24 -07001728 return -EIO;
1729 }
1730
1731 return 0;
1732}
1733
1734int
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301735static iw_display_data_path_snapshot(struct net_device *dev,
1736 struct iw_request_info *info,
1737 union iwreq_data *wrqu, char *extra)
1738{
1739
1740 /* Function intitiating dumping states of
1741 * HDD(WMM Tx Queues)
1742 * TL State (with Per Client infor)
1743 * DXE Snapshot (Called at the end of TL Snapshot)
1744 */
1745 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1746 hddLog(LOGE, "%s: called for SAP",__func__);
1747 hdd_wmm_tx_snapshot(pHostapdAdapter);
1748 WLANTL_TLDebugMessage(VOS_TRUE);
1749 return 0;
1750}
1751
1752int
schang86c22c42013-03-13 18:41:24 -07001753static iw_softap_set_tx_power(struct net_device *dev,
1754 struct iw_request_info *info,
1755 union iwreq_data *wrqu, char *extra)
1756{
1757 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1758 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1759 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1760 int *value = (int *)extra;
1761 int set_value;
1762 ptSapContext pSapCtx = NULL;
1763
1764 if (NULL == value)
1765 return -ENOMEM;
1766
1767 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1768 if (NULL == pSapCtx)
1769 {
1770 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1771 "%s: Invalid SAP pointer from pvosGCtx", __func__);
1772 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07001773 }
1774
1775 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07001776 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07001777 {
schang86c22c42013-03-13 18:41:24 -07001778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07001779 __func__);
1780 return -EIO;
1781 }
1782
1783 return 0;
1784}
1785
Kiet Lambcf38522013-10-26 18:28:27 +05301786/**---------------------------------------------------------------------------
1787
1788 \brief iw_softap_set_trafficmonitor() -
1789 This function dynamically enable/disable traffic monitor functonality
1790 the command iwpriv wlanX setTrafficMon <value>.
1791
1792 \param - dev - Pointer to the net device.
1793 - addr - Pointer to the sockaddr.
1794 \return - 0 for success, non zero for failure
1795
1796 --------------------------------------------------------------------------*/
1797
1798static int iw_softap_set_trafficmonitor(struct net_device *dev,
1799 struct iw_request_info *info,
1800 union iwreq_data *wrqu, char *extra)
1801{
1802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1803 int *isSetTrafficMon = (int *)wrqu->data.pointer;
1804 hdd_context_t *pHddCtx;
1805 int status;
1806
1807 if (NULL == pAdapter)
1808 {
1809 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1810 "%s: HDD adapter is Null", __func__);
1811 return -ENODEV;
1812 }
1813
1814 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1815
1816 status = wlan_hdd_validate_context(pHddCtx);
1817
1818 if (0 != status)
1819 {
1820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1821 "%s: HDD context is not valid", __func__);
1822 return status;
1823 }
1824
1825 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
1826
1827 if (NULL == isSetTrafficMon)
1828 {
1829 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1830 "%s: Invalid SAP pointer from extra", __func__);
1831 return -ENOMEM;
1832 }
1833
1834 if (TRUE == *isSetTrafficMon)
1835 {
1836 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
1837 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
1838 {
1839 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1840 "%s: failed to Start Traffic Monitor timer ", __func__ );
1841 return -EIO;
1842 }
1843 }
1844 else if (FALSE == *isSetTrafficMon)
1845 {
1846 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
1847 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
1848 {
1849 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1850 "%s: failed to Stop Traffic Monitor timer ", __func__ );
1851 return -EIO;
1852 }
1853
1854 }
1855 return 0;
1856}
1857
Jeff Johnson295189b2012-06-20 16:38:30 -07001858#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1859
1860int
1861static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1862 struct iw_request_info *info,
1863 union iwreq_data *wrqu, char *extra)
1864{
1865 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson295189b2012-06-20 16:38:30 -07001866 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07001867 char *buf;
1868 int cnt = 0;
1869 int left;
1870 int ret = 0;
1871 /* maclist_index must be u32 to match userspace */
1872 u32 maclist_index;
Jeff Johnson295189b2012-06-20 16:38:30 -07001873
Jeff Johnson224f3702014-03-26 11:09:47 -07001874 /*
1875 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
1876 * number, and even numbered iocts are supposed to have "set"
1877 * semantics. Hence the wireless extensions support in the kernel
1878 * won't correctly copy the result to userspace, so the ioctl
1879 * handler itself must copy the data. Output format is 32-bit
1880 * record length, followed by 0 or more 6-byte STA MAC addresses.
1881 *
1882 * Further note that due to the incorrect semantics, the "iwpriv"
1883 * userspace application is unable to correctly invoke this API,
1884 * hence it is not registered in the hostapd_private_args. This
1885 * API can only be invoked by directly invoking the ioctl() system
1886 * call.
1887 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001888
Jeff Johnson224f3702014-03-26 11:09:47 -07001889 /* make sure userspace allocated a reasonable buffer size */
1890 if (wrqu->data.length < sizeof(maclist_index)) {
1891 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
1892 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07001893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001894
Jeff Johnson224f3702014-03-26 11:09:47 -07001895 /* allocate local buffer to build the response */
1896 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
1897 if (!buf) {
1898 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
1899 return -ENOMEM;
1900 }
1901
1902 /* start indexing beyond where the record count will be written */
1903 maclist_index = sizeof(maclist_index);
1904 left = wrqu->data.length - maclist_index;
1905
1906 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1907 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
1908 if ((pStaInfo[cnt].isUsed) &&
1909 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
1910 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
1911 VOS_MAC_ADDR_SIZE);
1912 maclist_index += VOS_MAC_ADDR_SIZE;
1913 left -= VOS_MAC_ADDR_SIZE;
1914 }
1915 cnt++;
1916 }
1917 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1918
1919 *((u32 *)buf) = maclist_index;
1920 wrqu->data.length = maclist_index;
1921 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
1922 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
1923 ret = -EFAULT;
1924 }
1925 kfree(buf);
1926 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001927}
1928
1929/* Usage:
1930 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1931 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1932 while using this ioctl
1933
1934 Syntax:
1935 iwpriv softap.0 disassoc_sta <6 octet mac address>
1936
1937 e.g.
1938 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1939 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1940*/
1941
1942int
1943static iw_softap_disassoc_sta(struct net_device *dev,
1944 struct iw_request_info *info,
1945 union iwreq_data *wrqu, char *extra)
1946{
1947 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1948 v_U8_t *peerMacAddr;
1949
1950 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301951 /* iwpriv tool or framework calls this ioctl with
1952 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301954 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07001955
Arif Hussain24bafea2013-11-15 15:10:03 -08001956 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
1957 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1959 EXIT();
1960 return 0;
1961}
1962
1963int
1964static iw_softap_ap_stats(struct net_device *dev,
1965 struct iw_request_info *info,
1966 union iwreq_data *wrqu, char *extra)
1967{
1968 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1969 WLANTL_TRANSFER_STA_TYPE statBuffer;
1970 char *pstatbuf;
1971 int len = wrqu->data.length;
1972 pstatbuf = wrqu->data.pointer;
1973
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001974 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07001975 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
1976 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07001977
Arif Hussained667642013-10-27 23:01:14 -07001978 pstatbuf = kmalloc(wrqu->data.length, GFP_KERNEL);
1979 if(NULL == pstatbuf) {
1980 hddLog(LOG1, "unable to allocate memory");
1981 return -ENOMEM;
1982 }
1983 len = scnprintf(pstatbuf, wrqu->data.length,
1984 "RUF=%d RMF=%d RBF=%d "
1985 "RUB=%d RMB=%d RBB=%d "
1986 "TUF=%d TMF=%d TBF=%d "
1987 "TUB=%d TMB=%d TBB=%d",
1988 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
1989 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
1990 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
1991 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
1992 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
1993 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07001994
Arif Hussained667642013-10-27 23:01:14 -07001995 if (len > wrqu->data.length ||
1996 copy_to_user((void *)wrqu->data.pointer, (void *)pstatbuf, len))
1997 {
1998 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
1999 kfree(pstatbuf);
2000 return -EFAULT;
2001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 wrqu->data.length -= len;
Arif Hussained667642013-10-27 23:01:14 -07002003 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 return 0;
2005}
2006
2007int
2008static iw_softap_commit(struct net_device *dev,
2009 struct iw_request_info *info,
2010 union iwreq_data *wrqu, char *extra)
2011{
2012 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
2013 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2014 hdd_hostapd_state_t *pHostapdState;
2015 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2016 tpWLAN_SAPEventCB pSapEventCallback;
2017 tsap_Config_t *pConfig;
2018 s_CommitConfig_t *pCommitConfig;
2019 struct qc_mac_acl_entry *acl_entry = NULL;
2020 v_SINT_t i = 0, num_mac = 0;
2021 v_U32_t status = 0;
2022 eCsrAuthType RSNAuthType;
2023 eCsrEncryptionType RSNEncryptType;
2024 eCsrEncryptionType mcRSNEncryptType;
Chet Lanctot8cecea22014-02-11 19:09:36 -08002025 v_BOOL_t MFPCapable;
2026 v_BOOL_t MFPRequired;
Jeff Johnson295189b2012-06-20 16:38:30 -07002027
2028 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2029 pCommitConfig = (s_CommitConfig_t *)extra;
2030
c_hpothuffdb5272013-10-02 16:42:35 +05302031 pConfig = (tsap_Config_t *)vos_mem_malloc(sizeof(tsap_Config_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07002032 if(NULL == pConfig) {
c_hpothuffdb5272013-10-02 16:42:35 +05302033 hddLog(LOGE, FL("VOS unable to allocate memory"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 return -ENOMEM;
2035 }
2036 pConfig->beacon_int = pCommitConfig->beacon_int;
2037 pConfig->channel = pCommitConfig->channel;
2038
2039 /*Protection parameter to enable or disable*/
2040 pConfig->protEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
2041 pConfig->dtim_period = pCommitConfig->dtim_period;
2042 switch(pCommitConfig->hw_mode )
2043 {
2044 case eQC_DOT11_MODE_11A:
2045 pConfig->SapHw_mode = eSAP_DOT11_MODE_11a;
2046 break;
2047 case eQC_DOT11_MODE_11B:
2048 pConfig->SapHw_mode = eSAP_DOT11_MODE_11b;
2049 break;
2050 case eQC_DOT11_MODE_11G:
2051 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g;
2052 break;
2053
2054 case eQC_DOT11_MODE_11N:
2055 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2056 break;
2057 case eQC_DOT11_MODE_11G_ONLY:
2058 pConfig->SapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
2059 break;
2060 case eQC_DOT11_MODE_11N_ONLY:
2061 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n_ONLY;
2062 break;
2063 default:
2064 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2065 break;
2066
2067 }
2068
2069 pConfig->ieee80211d = pCommitConfig->qcsap80211d;
2070 vos_mem_copy(pConfig->countryCode, pCommitConfig->countryCode, 3);
2071 if(pCommitConfig->authType == eQC_AUTH_TYPE_SHARED_KEY)
2072 pConfig->authType = eSAP_SHARED_KEY;
2073 else if(pCommitConfig->authType == eQC_AUTH_TYPE_OPEN_SYSTEM)
2074 pConfig->authType = eSAP_OPEN_SYSTEM;
2075 else
2076 pConfig->authType = eSAP_AUTO_SWITCH;
2077
2078 pConfig->privacy = pCommitConfig->privacy;
2079 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pCommitConfig->privacy;
2080 pConfig->wps_state = pCommitConfig->wps_state;
2081 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
2082 pConfig->RSNWPAReqIELength = pCommitConfig->RSNWPAReqIELength;
2083 if(pConfig->RSNWPAReqIELength){
2084 pConfig->pRSNWPAReqIE = &pCommitConfig->RSNWPAReqIE[0];
2085 if ((pConfig->pRSNWPAReqIE[0] == DOT11F_EID_RSN) || (pConfig->pRSNWPAReqIE[0] == DOT11F_EID_WPA)){
2086 // The actual processing may eventually be more extensive than this.
2087 // Right now, just consume any PMKIDs that are sent in by the app.
2088 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002089 vos_get_context( VOS_MODULE_ID_PE, pVosContext),
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 &RSNEncryptType,
2091 &mcRSNEncryptType,
2092 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002093 &MFPCapable,
2094 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 pConfig->pRSNWPAReqIE[1]+2,
2096 pConfig->pRSNWPAReqIE );
2097
2098 if( VOS_STATUS_SUCCESS == status )
2099 {
2100 // Now copy over all the security attributes you have parsed out
2101 //TODO: Need to handle mixed mode
2102 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2103 pConfig->mcRSNEncryptType = mcRSNEncryptType;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002104 hddLog( LOG1, FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002105 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2106 }
2107 }
2108 }
2109 else
2110 {
2111 /* If no RSNIE, set encrypt type to NONE*/
2112 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
2113 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002114 hddLog( LOG1, FL("EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 pConfig->RSNEncryptType, pConfig->mcRSNEncryptType);
2116 }
2117
Chilam Ngc4244af2013-04-01 15:37:32 -07002118 if (pConfig->RSNWPAReqIELength > QCSAP_MAX_OPT_IE) {
2119 hddLog(LOGE, FL("RSNWPAReqIELength: %d too large"), pConfig->RSNWPAReqIELength);
2120 kfree(pConfig);
2121 return -EIO;
2122 }
2123
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 pConfig->SSIDinfo.ssidHidden = pCommitConfig->SSIDinfo.ssidHidden;
2125 pConfig->SSIDinfo.ssid.length = pCommitConfig->SSIDinfo.ssid.length;
2126 vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, pCommitConfig->SSIDinfo.ssid.ssId, pConfig->SSIDinfo.ssid.length);
2127 vos_mem_copy(pConfig->self_macaddr.bytes, pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2128
2129 pConfig->SapMacaddr_acl = pCommitConfig->qc_macaddr_acl;
2130
2131 // ht_capab is not what the name conveys,this is used for protection bitmap
2132 pConfig->ht_capab = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2133
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302134 if (pCommitConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2135 num_mac = pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 else
2137 num_mac = pConfig->num_accept_mac = pCommitConfig->num_accept_mac;
2138 acl_entry = pCommitConfig->accept_mac;
2139 for (i = 0; i < num_mac; i++)
2140 {
2141 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
2142 acl_entry++;
2143 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302144 if (pCommitConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2145 num_mac = pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002146 else
2147 num_mac = pConfig->num_deny_mac = pCommitConfig->num_deny_mac;
2148 acl_entry = pCommitConfig->deny_mac;
2149 for (i = 0; i < num_mac; i++)
2150 {
2151 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(v_MACADDR_t));
2152 acl_entry++;
2153 }
2154 //Uapsd Enabled Bit
2155 pConfig->UapsdEnable = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2156 //Enable OBSS protection
2157 pConfig->obssProtEnabled = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
2158 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apDisableIntraBssFwd;
2159
Arif Hussain6d2a3322013-11-17 19:50:10 -08002160 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
2161 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2162 pConfig->SSIDinfo.ssid.ssId,
2163 (int)pConfig->beacon_int, (int)pConfig->channel);
2164 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2165 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
2166 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2167 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2168 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d, DisableIntraBssFwd = %d"),
2169 pConfig->protEnabled, pConfig->obssProtEnabled,
2170 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->apDisableIntraBssFwd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002171
2172 pSapEventCallback = hdd_hostapd_SAPEventCB;
2173 pConfig->persona = pHostapdAdapter->device_mode;
2174 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,(v_PVOID_t)dev) != VOS_STATUS_SUCCESS)
2175 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002176 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002177 }
2178
2179 kfree(pConfig);
2180
2181 hddLog(LOG1, FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2182 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2183
2184 if (!VOS_IS_STATUS_SUCCESS(vos_status))
2185 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 VOS_ASSERT(0);
2188 }
2189
2190 pHostapdState->bCommit = TRUE;
2191 if(pHostapdState->vosStatus)
2192 {
c_hpothuffdb5272013-10-02 16:42:35 +05302193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2194 FL("pHostapdState->vosStatus: %d"), pHostapdState->vosStatus);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002195 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002196 }
2197 else
2198 {
2199 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2200 WLANSAP_Update_WpsIe ( pVosContext );
2201 return 0;
2202 }
2203}
2204static
2205int iw_softap_setmlme(struct net_device *dev,
2206 struct iw_request_info *info,
2207 union iwreq_data *wrqu, char *extra)
2208{
2209 struct sQcSapreq_mlme *pmlme;
2210 hdd_adapter_t *pHostapdAdapter = (hdd_adapter_t*)(netdev_priv(dev));
2211 v_MACADDR_t destAddress;
2212 pmlme = (struct sQcSapreq_mlme *)(wrqu->name);
2213 /* NOTE: this address is not valid incase of TKIP failure, since not filled */
2214 vos_mem_copy(&destAddress.bytes, pmlme->im_macaddr, sizeof(v_MACADDR_t));
2215 switch(pmlme->im_op)
2216 {
2217 case QCSAP_MLME_AUTHORIZE:
2218 hdd_softap_change_STA_state( pHostapdAdapter, &destAddress, WLANTL_STA_AUTHENTICATED);
2219 break;
2220 case QCSAP_MLME_ASSOC:
2221 //TODO:inform to TL after associating (not needed as we do in sapCallback)
2222 break;
2223 case QCSAP_MLME_UNAUTHORIZE:
2224 //TODO: send the disassoc to station
2225 //hdd_softap_change_STA_state( pHostapdAdapter, pmlme->im_macaddr, WLANTL_STA_AUTHENTICATED);
2226 break;
2227 case QCSAP_MLME_DISASSOC:
2228 hdd_softap_sta_disassoc(pHostapdAdapter,pmlme->im_macaddr);
2229 break;
2230 case QCSAP_MLME_DEAUTH:
2231 hdd_softap_sta_deauth(pHostapdAdapter,pmlme->im_macaddr);
2232 break;
2233 case QCSAP_MLME_MICFAILURE:
2234 hdd_softap_tkip_mic_fail_counter_measure(pHostapdAdapter,pmlme->im_reason);
2235 break;
2236 default:
2237 break;
2238 }
2239 return 0;
2240}
2241
2242static int iw_softap_set_channel_range(struct net_device *dev,
2243 struct iw_request_info *info,
2244 union iwreq_data *wrqu, char *extra)
2245{
2246 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2247 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002248 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002249
2250 int *value = (int *)extra;
2251 int startChannel = value[0];
2252 int endChannel = value[1];
2253 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002254 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 int ret = 0; /* success */
2256
2257 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2258 if(status != VOS_STATUS_SUCCESS)
2259 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002260 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 startChannel,endChannel, band);
2262 ret = -EINVAL;
2263 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002264
2265 pHddCtx->is_dynamic_channel_range_set = 1;
2266
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 return ret;
2268}
2269
2270int iw_softap_get_channel_list(struct net_device *dev,
2271 struct iw_request_info *info,
2272 union iwreq_data *wrqu, char *extra)
2273{
2274 v_U32_t num_channels = 0;
2275 v_U8_t i = 0;
2276 v_U8_t bandStartChannel = RF_CHAN_1;
2277 v_U8_t bandEndChannel = RF_CHAN_165;
2278 v_U32_t temp_num_channels = 0;
2279 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2280 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2281 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002283 eCsrBand curBand = eCSR_BAND_ALL;
2284
2285 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2286 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002287 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002288 return -EIO;
2289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002290 wrqu->data.length = sizeof(tChannelListInfo);
2291 ENTER();
2292
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002293 if (eCSR_BAND_24 == curBand)
2294 {
2295 bandStartChannel = RF_CHAN_1;
2296 bandEndChannel = RF_CHAN_14;
2297 }
2298 else if (eCSR_BAND_5G == curBand)
2299 {
2300 bandStartChannel = RF_CHAN_36;
2301 bandEndChannel = RF_CHAN_165;
2302 }
2303
Arif Hussain6d2a3322013-11-17 19:50:10 -08002304 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302305 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002306 bandStartChannel, bandEndChannel );
2307
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2309 {
2310 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2311 {
2312 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2313 num_channels++;
2314 }
2315 }
2316
2317 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2318
2319 temp_num_channels = num_channels;
2320
2321 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2322 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302323 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002324 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002325 }
2326
2327 if(REGDOMAIN_FCC == domainIdCurrentSoftap)
2328 {
2329 for(i = 0; i < temp_num_channels; i++)
2330 {
2331
2332 if((channel_list->channels[i] > 35) &&
2333 (channel_list->channels[i] < 49))
2334 {
2335 vos_mem_move(&channel_list->channels[i],
2336 &channel_list->channels[i+1],
2337 temp_num_channels - (i-1));
2338 num_channels--;
2339 temp_num_channels--;
2340 i--;
2341 }
2342 }
2343 }
2344
Arif Hussain6d2a3322013-11-17 19:50:10 -08002345 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002346
2347 if (num_channels > IW_MAX_FREQUENCIES)
2348 {
2349 num_channels = IW_MAX_FREQUENCIES;
2350 }
2351
2352 channel_list->num_channels = num_channels;
2353 EXIT();
2354
2355 return 0;
2356}
2357
2358static
2359int iw_get_genie(struct net_device *dev,
2360 struct iw_request_info *info,
2361 union iwreq_data *wrqu, char *extra)
2362{
2363 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2364 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2365 eHalStatus status;
2366 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2367 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2368 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002369 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002370 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2371 status = WLANSap_getstationIE_information(pVosContext,
2372 &length,
2373 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002374 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2375 if (wrqu->data.length < length ||
2376 copy_to_user(wrqu->data.pointer,
2377 (v_VOID_t*)genIeBytes, length))
2378 {
2379 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2380 return -EFAULT;
2381 }
2382 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002383
Arif Hussain6d2a3322013-11-17 19:50:10 -08002384 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002385
2386
2387 EXIT();
2388 return 0;
2389}
2390static
2391int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2392 struct iw_request_info *info,
2393 union iwreq_data *wrqu, char *extra)
2394{
2395 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002396 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002397 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2398 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002399
Arif Hussain6d2a3322013-11-17 19:50:10 -08002400 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002401 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2402
2403 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2404 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2405 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2406 WPSPBCProbeReqIEs.probeReqIELen);
2407 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2408 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2409 sizeof(v_MACADDR_t));
2410 if (copy_to_user(wrqu->data.pointer,
2411 (void *)&WPSPBCProbeReqIEs,
2412 sizeof(WPSPBCProbeReqIEs)))
2413 {
2414 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2415 return -EFAULT;
2416 }
2417 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002418 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002419 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 up(&pHddApCtx->semWpsPBCOverlapInd);
2421 EXIT();
2422 return 0;
2423}
2424
2425/**---------------------------------------------------------------------------
2426
2427 \brief iw_set_auth_hostap() -
2428 This function sets the auth type received from the wpa_supplicant.
2429
2430 \param - dev - Pointer to the net device.
2431 - info - Pointer to the iw_request_info.
2432 - wrqu - Pointer to the iwreq_data.
2433 - extra - Pointer to the data.
2434 \return - 0 for success, non zero for failure
2435
2436 --------------------------------------------------------------------------*/
2437int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info,
2438 union iwreq_data *wrqu,char *extra)
2439{
2440 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2441 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2442
2443 ENTER();
2444 switch(wrqu->param.flags & IW_AUTH_INDEX)
2445 {
2446 case IW_AUTH_TKIP_COUNTERMEASURES:
2447 {
2448 if(wrqu->param.value) {
2449 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2450 "Counter Measure started %d", wrqu->param.value);
2451 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2452 }
2453 else {
2454 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2455 "Counter Measure stopped=%d", wrqu->param.value);
2456 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2457 }
2458
2459 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2460 wrqu->param.value);
2461 }
2462 break;
2463
2464 default:
2465
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002466 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002467 wrqu->param.flags & IW_AUTH_INDEX);
2468 break;
2469 }
2470
2471 EXIT();
2472 return 0;
2473}
2474
2475static int iw_set_ap_encodeext(struct net_device *dev,
2476 struct iw_request_info *info,
2477 union iwreq_data *wrqu, char *extra)
2478{
2479 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2480 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2481 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002482 int retval = 0;
2483 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002484 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2485 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2486 int key_index;
2487 struct iw_point *encoding = &wrqu->encoding;
2488 tCsrRoamSetKey setKey;
2489// tCsrRoamRemoveKey RemoveKey;
2490 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002491
Jeff Johnson295189b2012-06-20 16:38:30 -07002492 ENTER();
2493
2494 key_index = encoding->flags & IW_ENCODE_INDEX;
2495
2496 if(key_index > 0) {
2497
2498 /*Convert from 1-based to 0-based keying*/
2499 key_index--;
2500 }
2501 if(!ext->key_len) {
2502#if 0
2503 /*Set the encrytion type to NONE*/
2504#if 0
2505 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2506#endif
2507
2508 RemoveKey.keyId = key_index;
2509 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2510 /*Key direction for group is RX only*/
2511 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2512 }
2513 else {
2514 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2515 }
2516 switch(ext->alg)
2517 {
2518 case IW_ENCODE_ALG_NONE:
2519 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2520 break;
2521 case IW_ENCODE_ALG_WEP:
2522 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2523 break;
2524 case IW_ENCODE_ALG_TKIP:
2525 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002526 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 case IW_ENCODE_ALG_CCMP:
2528 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2529 break;
2530 default:
2531 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2532 break;
2533 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002535 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002537 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002538 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002539 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2540 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 {
2542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002543 __LINE__, vstatus );
2544 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002546#endif
2547 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002548
Jeff Johnson43971f52012-07-17 12:26:56 -07002549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002550
2551 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2552
2553 setKey.keyId = key_index;
2554 setKey.keyLength = ext->key_len;
2555
2556 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2557 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2558 }
2559
2560 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2561 /*Key direction for group is RX only*/
2562 setKey.keyDirection = eSIR_RX_ONLY;
2563 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2564 }
2565 else {
2566
2567 setKey.keyDirection = eSIR_TX_RX;
2568 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2569 }
2570 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2571 {
2572 setKey.keyDirection = eSIR_TX_DEFAULT;
2573 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2574 }
2575
2576 /*For supplicant pae role is zero*/
2577 setKey.paeRole = 0;
2578
2579 switch(ext->alg)
2580 {
2581 case IW_ENCODE_ALG_NONE:
2582 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2583 break;
2584
2585 case IW_ENCODE_ALG_WEP:
2586 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2587 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002588 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002589 break;
2590
2591 case IW_ENCODE_ALG_TKIP:
2592 {
2593 v_U8_t *pKey = &setKey.Key[0];
2594
2595 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2596
2597 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2598
2599 /*Supplicant sends the 32bytes key in this order
2600
2601 |--------------|----------|----------|
2602 | Tk1 |TX-MIC | RX Mic |
2603 |--------------|----------|----------|
2604 <---16bytes---><--8bytes--><--8bytes-->
2605
2606 */
2607 /*Sme expects the 32 bytes key to be in the below order
2608
2609 |--------------|----------|----------|
2610 | Tk1 |RX-MIC | TX Mic |
2611 |--------------|----------|----------|
2612 <---16bytes---><--8bytes--><--8bytes-->
2613 */
2614 /* Copy the Temporal Key 1 (TK1) */
2615 vos_mem_copy(pKey,ext->key,16);
2616
2617 /*Copy the rx mic first*/
2618 vos_mem_copy(&pKey[16],&ext->key[24],8);
2619
2620 /*Copy the tx mic */
2621 vos_mem_copy(&pKey[24],&ext->key[16],8);
2622
2623 }
2624 break;
2625
2626 case IW_ENCODE_ALG_CCMP:
2627 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2628 break;
2629
2630 default:
2631 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2632 break;
2633 }
2634
2635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302636 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 setKey.keyId);
2638 for(i=0; i< ext->key_len; i++)
2639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2640 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002641
2642 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2643 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002644 {
2645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002646 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2647 retval = -EINVAL;
2648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002649
Jeff Johnson43971f52012-07-17 12:26:56 -07002650 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002651}
Jeff Johnson43971f52012-07-17 12:26:56 -07002652
2653
Jeff Johnson295189b2012-06-20 16:38:30 -07002654static int iw_set_ap_mlme(struct net_device *dev,
2655 struct iw_request_info *info,
2656 union iwreq_data *wrqu,
2657 char *extra)
2658{
2659#if 0
2660 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2661 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2662
2663 ENTER();
2664
2665 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2666 switch (mlme->cmd) {
2667 case IW_MLME_DISASSOC:
2668 case IW_MLME_DEAUTH:
2669 hddLog(LOG1, "Station disassociate");
2670 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2671 {
2672 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2673
2674 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2675 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2676
2677 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2678
2679 //clear all the reason codes
2680 if (status != 0)
2681 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002682 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 }
2684
2685 netif_stop_queue(dev);
2686 netif_carrier_off(dev);
2687 }
2688 else
2689 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002690 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002691 }
2692 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002693 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002694 return -EINVAL;
2695 }//end of switch
2696 EXIT();
2697#endif
2698 return 0;
2699// return status;
2700}
2701
2702static int iw_get_ap_rts_threshold(struct net_device *dev,
2703 struct iw_request_info *info,
2704 union iwreq_data *wrqu, char *extra)
2705{
2706 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2707 v_U32_t status = 0;
2708
2709 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2710
2711 return status;
2712}
2713
2714static int iw_get_ap_frag_threshold(struct net_device *dev,
2715 struct iw_request_info *info,
2716 union iwreq_data *wrqu, char *extra)
2717{
2718 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2719 v_U32_t status = 0;
2720
2721 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2722
2723 return status;
2724}
2725
2726static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info,
2727 struct iw_freq *fwrq, char *extra)
2728{
Jeff Johnsone7245742012-09-05 17:12:55 -07002729 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002730 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2731 tHalHandle hHal;
2732 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002733 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002734
2735 ENTER();
2736
2737 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2739 "%s:LOGP in Progress. Ignore!!!",__func__);
2740 return status;
2741 }
2742
2743 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2744 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2745
2746 if(pHostapdState->bssState == BSS_STOP )
2747 {
2748 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2749 != eHAL_STATUS_SUCCESS)
2750 {
c_hpothuffdb5272013-10-02 16:42:35 +05302751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2752 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 return -EIO;
2754 }
2755 else
2756 {
2757 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002758 if( TRUE == status)
2759 {
2760 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2761 * iwlist & iwconfig command shows frequency into proper
2762 * format (2.412 GHz instead of 246.2 MHz)*/
2763 fwrq->m = freq;
2764 fwrq->e = MHZ;
2765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002766 }
2767 }
2768 else
2769 {
2770 channel = pHddApCtx->operatingChannel;
2771 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002772 if( TRUE == status)
2773 {
2774 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2775 * iwlist & iwconfig command shows frequency into proper
2776 * format (2.412 GHz instead of 246.2 MHz)*/
2777 fwrq->m = freq;
2778 fwrq->e = MHZ;
2779 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002780 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002781 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002782}
2783
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302784static int iw_get_mode(struct net_device *dev,
2785 struct iw_request_info *info,
2786 union iwreq_data *wrqu,
2787 char *extra)
2788{
2789 int status = 0;
2790
2791 wrqu->mode = IW_MODE_MASTER;
2792
2793 return status;
2794}
2795
Jeff Johnson295189b2012-06-20 16:38:30 -07002796static int iw_softap_setwpsie(struct net_device *dev,
2797 struct iw_request_info *info,
2798 union iwreq_data *wrqu,
2799 char *extra)
2800{
2801 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2802 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2803 hdd_hostapd_state_t *pHostapdState;
2804 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002805 u_int8_t *wps_genie;
2806 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07002807 u_int8_t *pos;
2808 tpSap_WPSIE pSap_WPSIe;
2809 u_int8_t WPSIeType;
2810 u_int16_t length;
2811 ENTER();
2812
Arif Hussained667642013-10-27 23:01:14 -07002813 if(!wrqu->data.length || wrqu->data.length <= QCSAP_MAX_WSC_IE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002814 return 0;
2815
Arif Hussained667642013-10-27 23:01:14 -07002816 wps_genie = kmalloc(wrqu->data.length, GFP_KERNEL);
2817
2818 if(NULL == wps_genie) {
2819 hddLog(LOG1, "unable to allocate memory");
2820 return -ENOMEM;
2821 }
2822 fwps_genie = wps_genie;
2823 if (copy_from_user((void *)wps_genie,
2824 wrqu->data.pointer, wrqu->data.length))
2825 {
2826 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2827 kfree(fwps_genie);
2828 return -EFAULT;
2829 }
2830
Jeff Johnson295189b2012-06-20 16:38:30 -07002831 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2832 if (NULL == pSap_WPSIe)
2833 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002834 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07002835 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 return -ENOMEM;
2837 }
2838 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2839
Arif Hussain6d2a3322013-11-17 19:50:10 -08002840 hddLog(LOG1,"%s WPS IE type[0x%X] IE[0x%X], LEN[%d]", __func__, wps_genie[0], wps_genie[1], wps_genie[2]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002841 WPSIeType = wps_genie[0];
2842 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2843 {
2844 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2845 wps_genie = wps_genie + 1;
2846 switch ( wps_genie[0] )
2847 {
2848 case DOT11F_EID_WPA:
2849 if (wps_genie[1] < 2 + 4)
2850 {
2851 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002852 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002853 return -EINVAL;
2854 }
2855 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2856 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002857 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002858 pos = &wps_genie[6];
2859 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2860 {
2861 switch((u_int16_t)(*pos<<8) | *(pos+1))
2862 {
2863 case HDD_WPS_ELEM_VERSION:
2864 pos += 4;
2865 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002866 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002867 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2868 pos += 1;
2869 break;
2870
2871 case HDD_WPS_ELEM_WPS_STATE:
2872 pos +=4;
2873 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002874 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002875 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2876 pos += 1;
2877 break;
2878 case HDD_WPS_ELEM_APSETUPLOCK:
2879 pos += 4;
2880 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002881 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002882 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2883 pos += 1;
2884 break;
2885 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2886 pos += 4;
2887 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002888 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002889 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2890 pos += 1;
2891 break;
2892 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2893 pos += 4;
2894 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002895 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002896 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2897 pos += 2;
2898 break;
2899 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2900 pos += 4;
2901 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002902 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002903 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2904 pos += 2;
2905 break;
2906
2907 case HDD_WPS_ELEM_UUID_E:
2908 pos += 2;
2909 length = *pos<<8 | *(pos+1);
2910 pos += 2;
2911 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2912 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2913 pos += length;
2914 break;
2915 case HDD_WPS_ELEM_RF_BANDS:
2916 pos += 4;
2917 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002918 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002919 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2920 pos += 1;
2921 break;
2922
2923 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002924 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07002925 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002926 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002927 return -EINVAL;
2928 }
2929 }
2930 }
2931 else {
2932 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002933 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002934 }
2935 break;
2936
2937 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002938 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002940 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002941 return 0;
2942 }
2943 }
2944 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2945 {
2946 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2947 wps_genie = wps_genie + 1;
2948 switch ( wps_genie[0] )
2949 {
2950 case DOT11F_EID_WPA:
2951 if (wps_genie[1] < 2 + 4)
2952 {
2953 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002954 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 return -EINVAL;
2956 }
2957 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2958 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002959 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 pos = &wps_genie[6];
2961 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2962 {
2963 switch((u_int16_t)(*pos<<8) | *(pos+1))
2964 {
2965 case HDD_WPS_ELEM_VERSION:
2966 pos += 4;
2967 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002968 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2970 pos += 1;
2971 break;
2972
2973 case HDD_WPS_ELEM_WPS_STATE:
2974 pos +=4;
2975 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002976 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2978 pos += 1;
2979 break;
2980 case HDD_WPS_ELEM_APSETUPLOCK:
2981 pos += 4;
2982 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002983 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002984 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2985 pos += 1;
2986 break;
2987 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2988 pos += 4;
2989 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002990 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2992 pos += 1;
2993 break;
2994 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2995 pos += 4;
2996 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002997 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002998 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2999 pos += 2;
3000 break;
3001 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
3002 pos += 4;
3003 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003004 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003005 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
3006 pos += 2;
3007 break;
3008 case HDD_WPS_ELEM_RSP_TYPE:
3009 pos += 4;
3010 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003011 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07003012 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
3013 pos += 1;
3014 break;
3015 case HDD_WPS_ELEM_UUID_E:
3016 pos += 2;
3017 length = *pos<<8 | *(pos+1);
3018 pos += 2;
3019 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
3020 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
3021 pos += length;
3022 break;
3023
3024 case HDD_WPS_ELEM_MANUFACTURER:
3025 pos += 2;
3026 length = *pos<<8 | *(pos+1);
3027 pos += 2;
3028 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
3029 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
3030 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
3031 pos += length;
3032 break;
3033
3034 case HDD_WPS_ELEM_MODEL_NAME:
3035 pos += 2;
3036 length = *pos<<8 | *(pos+1);
3037 pos += 2;
3038 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
3039 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
3040 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
3041 pos += length;
3042 break;
3043 case HDD_WPS_ELEM_MODEL_NUM:
3044 pos += 2;
3045 length = *pos<<8 | *(pos+1);
3046 pos += 2;
3047 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
3048 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
3049 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
3050 pos += length;
3051 break;
3052 case HDD_WPS_ELEM_SERIAL_NUM:
3053 pos += 2;
3054 length = *pos<<8 | *(pos+1);
3055 pos += 2;
3056 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
3057 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
3058 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
3059 pos += length;
3060 break;
3061 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
3062 pos += 4;
3063 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003064 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003065 pos += 2;
3066
3067 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003068 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003069 pos += 4;
3070 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003071 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 pos += 2;
3073 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
3074 break;
3075 case HDD_WPS_ELEM_DEVICE_NAME:
3076 pos += 2;
3077 length = *pos<<8 | *(pos+1);
3078 pos += 2;
3079 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
3080 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
3081 pos += length;
3082 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
3083 break;
3084 case HDD_WPS_ELEM_CONFIG_METHODS:
3085 pos += 4;
3086 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08003087 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 pos += 2;
3089 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
3090 break;
3091
3092 case HDD_WPS_ELEM_RF_BANDS:
3093 pos += 4;
3094 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08003095 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 pos += 1;
3097 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
3098 break;
3099 } // switch
3100 }
3101 }
3102 else
3103 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003104 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003105 }
3106
3107 } // switch
3108 }
3109 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
3110 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3111 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3112 {
3113 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3114 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3115 WLANSAP_Update_WpsIe ( pVosContext );
3116 }
3117
3118 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003119 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003120 EXIT();
3121 return halStatus;
3122}
3123
3124static int iw_softap_stopbss(struct net_device *dev,
3125 struct iw_request_info *info,
3126 union iwreq_data *wrqu,
3127 char *extra)
3128{
3129 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3130 VOS_STATUS status = VOS_STATUS_SUCCESS;
3131 ENTER();
3132 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3133 {
3134 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
3135 {
3136 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3137
3138 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
3139
3140 if (!VOS_IS_STATUS_SUCCESS(status))
3141 {
3142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003143 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003144 VOS_ASSERT(0);
3145 }
3146 }
3147 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
3148 }
3149 EXIT();
3150 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
3151}
3152
3153static int iw_softap_version(struct net_device *dev,
3154 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003155 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07003156 char *extra)
3157{
Jeff Johnson295189b2012-06-20 16:38:30 -07003158 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003159
Jeff Johnson295189b2012-06-20 16:38:30 -07003160 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003161 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003162 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003163 return 0;
3164}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003165
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003166VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003167{
3168 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003169 int len = 0;
3170 const char sta_info_header[] = "staId staAddress\n";
3171
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003172 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003173 pBuf += len;
3174 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003175
3176 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
3177 {
3178 if(pAdapter->aStaInfo[i].isUsed)
3179 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003180 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003181 pAdapter->aStaInfo[i].ucSTAId,
3182 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
3183 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
3184 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
3185 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
3186 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
3187 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003188 pBuf += len;
3189 buf_len -= len;
3190 }
3191 if(WE_GET_STA_INFO_SIZE > buf_len)
3192 {
3193 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003194 }
3195 }
3196 return VOS_STATUS_SUCCESS;
3197}
3198
3199static int iw_softap_get_sta_info(struct net_device *dev,
3200 struct iw_request_info *info,
3201 union iwreq_data *wrqu,
3202 char *extra)
3203{
3204 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3205 VOS_STATUS status;
3206 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003207 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003208 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003210 return -EINVAL;
3211 }
3212 wrqu->data.length = strlen(extra);
3213 EXIT();
3214 return 0;
3215}
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217static int iw_set_ap_genie(struct net_device *dev,
3218 struct iw_request_info *info,
3219 union iwreq_data *wrqu,
3220 char *extra)
3221{
3222
3223 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3224 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3225 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003226 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003227
3228 ENTER();
3229
3230 if(!wrqu->data.length)
3231 {
3232 EXIT();
3233 return 0;
3234 }
Arif Hussained667642013-10-27 23:01:14 -07003235
Jeff Johnson295189b2012-06-20 16:38:30 -07003236 switch (genie[0])
3237 {
3238 case DOT11F_EID_WPA:
3239 case DOT11F_EID_RSN:
3240 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3241 {
3242 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3243 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3244 }
3245 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003246 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003247 break;
3248
3249 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003250 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003251 halStatus = 0;
3252 }
3253
3254 EXIT();
3255 return halStatus;
3256}
3257
3258static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3259{
3260 eHalStatus hstatus;
3261 long lrc;
3262 struct statsContext context;
3263
3264 if (NULL == pAdapter)
3265 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303266 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003267 return VOS_STATUS_E_FAULT;
3268 }
3269
3270 init_completion(&context.completion);
3271 context.pAdapter = pAdapter;
3272 context.magic = STATS_CONTEXT_MAGIC;
3273 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3274 eCSR_HDD,
3275 SME_GLOBAL_CLASSA_STATS,
3276 hdd_GetClassA_statisticsCB,
3277 0, // not periodic
3278 FALSE, //non-cached results
3279 staid,
3280 &context);
3281 if (eHAL_STATUS_SUCCESS != hstatus)
3282 {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003285 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003286 }
3287 else
3288 {
3289 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3290 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003291 if (lrc <= 0)
3292 {
3293 hddLog(VOS_TRACE_LEVEL_ERROR,
3294 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003295 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003296 }
3297 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003298
3299 /* either we never sent a request, we sent a request and received a
3300 response or we sent a request and timed out. if we never sent a
3301 request or if we sent a request and got a response, we want to
3302 clear the magic out of paranoia. if we timed out there is a
3303 race condition such that the callback function could be
3304 executing at the same time we are. of primary concern is if the
3305 callback function had already verified the "magic" but had not
3306 yet set the completion variable when a timeout occurred. we
3307 serialize these activities by invalidating the magic while
3308 holding a shared spinlock which will cause us to block if the
3309 callback is currently executing */
3310 spin_lock(&hdd_context_lock);
3311 context.magic = 0;
3312 spin_unlock(&hdd_context_lock);
3313
Jeff Johnson295189b2012-06-20 16:38:30 -07003314 return VOS_STATUS_SUCCESS;
3315}
3316
3317int iw_get_softap_linkspeed(struct net_device *dev,
3318 struct iw_request_info *info,
3319 union iwreq_data *wrqu,
3320 char *extra)
3321
3322{
3323 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303324 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003325 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003326 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303327 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003328 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303329 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003330 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003331 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303332 int rc, valid;
3333
3334 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3335
3336 valid = wlan_hdd_validate_context(pHddCtx);
3337
3338 if (0 != valid)
3339 {
3340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3341 return valid;
3342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003343
Arif Hussain6d2a3322013-11-17 19:50:10 -08003344 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003345
3346 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003347 {
Arif Hussaina9571842014-01-15 16:43:41 -08003348 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3349 if (NULL == pmacAddress) {
3350 hddLog(LOG1, "unable to allocate memory");
3351 return -ENOMEM;
3352 }
3353 if (copy_from_user((void *)pmacAddress,
3354 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3355 {
3356 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3357 kfree(pmacAddress);
3358 return -EFAULT;
3359 }
3360 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3361
3362 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003363 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003364
3365 if (!VOS_IS_STATUS_SUCCESS(status ))
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3368 }
Arif Hussained667642013-10-27 23:01:14 -07003369 }
Kiet Lam61589852013-09-19 17:10:58 +05303370 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303371 * link speed for first connected client will be returned.
3372 */
Arif Hussaina9571842014-01-15 16:43:41 -08003373 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303374 {
3375 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3376 }
3377 else
3378 {
3379 status = hdd_softap_GetStaId(pHostapdAdapter,
3380 (v_MACADDR_t *)macAddress, (void *)(&staId));
3381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003382
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303383 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003384 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003386 link_speed = 0;
3387 }
3388 else
3389 {
3390 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303391
Jeff Johnson295189b2012-06-20 16:38:30 -07003392 if (!VOS_IS_STATUS_SUCCESS(status ))
3393 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 return -EINVAL;
3396 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303397
3398 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3399 staId, &link_speed);
3400
3401 link_speed = link_speed / 10;
3402
3403 if (0 == link_speed)
3404 {
3405 /* The linkspeed returned by HAL is in units of 500kbps.
3406 * converting it to mbps.
3407 * This is required to support legacy firmware which does
3408 * not return link capacity.
3409 */
3410 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3411 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 }
3413
3414 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003415 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303416
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 if ((rc < 0) || (rc >= len))
3418 {
3419 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303420 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003421 return -EIO;
3422 }
3423
3424 return 0;
3425}
3426
3427static const iw_handler hostapd_handler[] =
3428{
3429 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3430 (iw_handler) NULL, /* SIOCGIWNAME */
3431 (iw_handler) NULL, /* SIOCSIWNWID */
3432 (iw_handler) NULL, /* SIOCGIWNWID */
3433 (iw_handler) NULL, /* SIOCSIWFREQ */
3434 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3435 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303436 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003437 (iw_handler) NULL, /* SIOCSIWSENS */
3438 (iw_handler) NULL, /* SIOCGIWSENS */
3439 (iw_handler) NULL, /* SIOCSIWRANGE */
3440 (iw_handler) NULL, /* SIOCGIWRANGE */
3441 (iw_handler) NULL, /* SIOCSIWPRIV */
3442 (iw_handler) NULL, /* SIOCGIWPRIV */
3443 (iw_handler) NULL, /* SIOCSIWSTATS */
3444 (iw_handler) NULL, /* SIOCGIWSTATS */
3445 (iw_handler) NULL, /* SIOCSIWSPY */
3446 (iw_handler) NULL, /* SIOCGIWSPY */
3447 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3448 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3449 (iw_handler) NULL, /* SIOCSIWAP */
3450 (iw_handler) NULL, /* SIOCGIWAP */
3451 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3452 (iw_handler) NULL, /* SIOCGIWAPLIST */
3453 (iw_handler) NULL, /* SIOCSIWSCAN */
3454 (iw_handler) NULL, /* SIOCGIWSCAN */
3455 (iw_handler) NULL, /* SIOCSIWESSID */
3456 (iw_handler) NULL, /* SIOCGIWESSID */
3457 (iw_handler) NULL, /* SIOCSIWNICKN */
3458 (iw_handler) NULL, /* SIOCGIWNICKN */
3459 (iw_handler) NULL, /* -- hole -- */
3460 (iw_handler) NULL, /* -- hole -- */
3461 (iw_handler) NULL, /* SIOCSIWRATE */
3462 (iw_handler) NULL, /* SIOCGIWRATE */
3463 (iw_handler) NULL, /* SIOCSIWRTS */
3464 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3465 (iw_handler) NULL, /* SIOCSIWFRAG */
3466 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3467 (iw_handler) NULL, /* SIOCSIWTXPOW */
3468 (iw_handler) NULL, /* SIOCGIWTXPOW */
3469 (iw_handler) NULL, /* SIOCSIWRETRY */
3470 (iw_handler) NULL, /* SIOCGIWRETRY */
3471 (iw_handler) NULL, /* SIOCSIWENCODE */
3472 (iw_handler) NULL, /* SIOCGIWENCODE */
3473 (iw_handler) NULL, /* SIOCSIWPOWER */
3474 (iw_handler) NULL, /* SIOCGIWPOWER */
3475 (iw_handler) NULL, /* -- hole -- */
3476 (iw_handler) NULL, /* -- hole -- */
3477 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3478 (iw_handler) NULL, /* SIOCGIWGENIE */
3479 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3480 (iw_handler) NULL, /* SIOCGIWAUTH */
3481 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3482 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3483 (iw_handler) NULL, /* SIOCSIWPMKSA */
3484};
3485
Jeff Johnson224f3702014-03-26 11:09:47 -07003486/*
3487 * Note that the following ioctls were defined with semantics which
3488 * cannot be handled by the "iwpriv" userspace application and hence
3489 * they are not included in the hostapd_private_args array
3490 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3491 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003492
3493static const struct iw_priv_args hostapd_private_args[] = {
3494 { QCSAP_IOCTL_SETPARAM,
3495 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3496 { QCSAP_IOCTL_SETPARAM,
3497 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3498 { QCSAP_PARAM_MAX_ASSOC,
3499 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3500 { QCSAP_PARAM_HIDE_SSID,
3501 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003502 { QCSAP_PARAM_SET_MC_RATE,
3503 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003504 { QCSAP_IOCTL_GETPARAM,
3505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3506 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3507 { QCSAP_IOCTL_GETPARAM, 0,
3508 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3509 { QCSAP_PARAM_MAX_ASSOC, 0,
3510 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003511 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3513 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3514 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 { QCSAP_PARAM_MODULE_DOWN_IND, 0,
3516 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" },
3517 { QCSAP_PARAM_CLR_ACL, 0,
3518 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3519 { QCSAP_PARAM_ACL_MODE,
3520 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
3521 { QCSAP_IOCTL_COMMIT,
3522 IW_PRIV_TYPE_BYTE | sizeof(struct s_CommitConfig) | IW_PRIV_SIZE_FIXED, 0, "commit" },
3523 { QCSAP_IOCTL_SETMLME,
3524 IW_PRIV_TYPE_BYTE | sizeof(struct sQcSapreq_mlme)| IW_PRIV_SIZE_FIXED, 0, "setmlme" },
3525 { QCSAP_IOCTL_GET_STAWPAIE,
3526 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3527 { QCSAP_IOCTL_SETWPAIE,
3528 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3529 { QCSAP_IOCTL_STOPBSS,
3530 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3531 { QCSAP_IOCTL_VERSION, 0,
3532 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003533 { QCSAP_IOCTL_GET_STA_INFO, 0,
3534 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003535 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003536 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003537 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003538 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003539 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003540 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
3541 { QCSAP_IOCTL_AP_STATS,
3542 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE, 0, "ap_stats" },
3543 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3544 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303545 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003546
3547 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3548 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3549 /* handlers for sub-ioctl */
3550 { WE_SET_WLAN_DBG,
3551 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3552 0,
3553 "setwlandbg" },
3554
3555 /* handlers for main ioctl */
3556 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3557 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3558 0,
3559 "" },
3560
3561 /* handlers for sub-ioctl */
3562 { WE_LOG_DUMP_CMD,
3563 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3564 0,
3565 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003566 { WE_P2P_NOA_CMD,
3567 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3568 0,
3569 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003570 /* handlers for sub ioctl */
3571 {
3572 WE_MCC_CONFIG_CREDENTIAL,
3573 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3574 0,
3575 "setMccCrdnl" },
3576
3577 /* handlers for sub ioctl */
3578 {
3579 WE_MCC_CONFIG_PARAMS,
3580 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3581 0,
3582 "setMccConfig" },
3583
Jeff Johnson295189b2012-06-20 16:38:30 -07003584 /* handlers for main ioctl */
3585 { QCSAP_IOCTL_MODIFY_ACL,
3586 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3587 0,
3588 "modify_acl" },
3589
3590 /* handlers for main ioctl */
3591 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3592 0,
3593 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3594 "getChannelList" },
3595
Jeff Johnsone7245742012-09-05 17:12:55 -07003596 /* handlers for main ioctl */
3597 { QCSAP_IOCTL_SET_TX_POWER,
3598 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3599 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303600 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003601
3602 /* handlers for main ioctl */
3603 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3604 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3605 0,
3606 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303607
3608 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3609 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3610 0,
3611 "dataSnapshot" },
3612
3613 /* handlers for main ioctl */
3614 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3615 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3616 0,
3617 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003618};
Jeff Johnsone7245742012-09-05 17:12:55 -07003619
Jeff Johnson295189b2012-06-20 16:38:30 -07003620static const iw_handler hostapd_private[] = {
3621 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3622 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
3623 [QCSAP_IOCTL_COMMIT - SIOCIWFIRSTPRIV] = iw_softap_commit, //get priv ioctl
3624 [QCSAP_IOCTL_SETMLME - SIOCIWFIRSTPRIV] = iw_softap_setmlme,
3625 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3626 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3627 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3628 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3629 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3630 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3631 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3632 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3633 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3634 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3635 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3636 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3637 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3638 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003639 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003640 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3641 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003642 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303643 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303644 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003645};
3646const struct iw_handler_def hostapd_handler_def = {
3647 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3648 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3649 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3650 .standard = (iw_handler *)hostapd_handler,
3651 .private = (iw_handler *)hostapd_private,
3652 .private_args = hostapd_private_args,
3653 .get_wireless_stats = NULL,
3654};
3655#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3656struct net_device_ops net_ops_struct = {
3657 .ndo_open = hdd_hostapd_open,
3658 .ndo_stop = hdd_hostapd_stop,
3659 .ndo_uninit = hdd_hostapd_uninit,
3660 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3661 .ndo_tx_timeout = hdd_softap_tx_timeout,
3662 .ndo_get_stats = hdd_softap_stats,
3663 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3664 .ndo_do_ioctl = hdd_hostapd_ioctl,
3665 .ndo_change_mtu = hdd_hostapd_change_mtu,
3666 .ndo_select_queue = hdd_hostapd_select_queue,
3667 };
3668#endif
3669
3670int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3671{
3672 return VOS_STATUS_SUCCESS;
3673}
3674
3675void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3676{
3677#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3678 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3679#else
3680 pWlanHostapdDev->open = hdd_hostapd_open;
3681 pWlanHostapdDev->stop = hdd_hostapd_stop;
3682 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3683 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3684 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3685 pWlanHostapdDev->get_stats = hdd_softap_stats;
3686 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3687 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3688#endif
3689}
3690
3691VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
3692{
3693 hdd_hostapd_state_t * phostapdBuf;
3694 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003695 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003696 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08003697#ifdef FEATURE_WLAN_CH_AVOID
3698 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
3699 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
3700 v_U16_t unsafeChannelCount;
3701#endif /* FEATURE_WLAN_CH_AVOID */
3702
Jeff Johnson295189b2012-06-20 16:38:30 -07003703 ENTER();
3704 // Allocate the Wireless Extensions state structure
3705 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
3706
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003707 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
3708
Leo Chang0b0e45a2013-12-15 15:18:55 -08003709#ifdef FEATURE_WLAN_CH_AVOID
3710 /* Get unsafe cahnnel list from cached location */
3711 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
3712 sizeof(unsafeChannelList),
3713 &unsafeChannelCount);
3714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3715 "%s : Unsafe Channel count %d",
3716 __func__, unsafeChannelCount);
3717 hdd_hostapd_update_unsafe_channel_list(pVosContext,
3718 unsafeChannelList,
3719 unsafeChannelCount);
3720#endif /* FEATURE_WLAN_CH_AVOID */
3721
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 // Zero the memory. This zeros the profile structure.
3723 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
3724
3725 // Set up the pointer to the Wireless Extensions state structure
3726 // NOP
3727 status = hdd_set_hostapd(pAdapter);
3728 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 return status;
3731 }
3732
3733 status = vos_event_init(&phostapdBuf->vosEvent);
3734 if (!VOS_IS_STATUS_SUCCESS(status))
3735 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003737 return status;
3738 }
3739
3740 init_completion(&pAdapter->session_close_comp_var);
3741 init_completion(&pAdapter->session_open_comp_var);
3742
3743 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
3744
3745 // Register as a wireless device
3746 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
3747
3748 //Initialize the data path module
3749 status = hdd_softap_init_tx_rx(pAdapter);
3750 if ( !VOS_IS_STATUS_SUCCESS( status ))
3751 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003752 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003753 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303754
3755 status = hdd_wmm_adapter_init( pAdapter );
3756 if (!VOS_IS_STATUS_SUCCESS(status))
3757 {
3758 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003759 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303760 status, status );
3761 goto error_wmm_init;
3762 }
3763
3764 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3765
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303767
3768 return status;
3769
3770error_wmm_init:
3771 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003772 EXIT();
3773 return status;
3774}
3775
3776hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
3777{
3778 struct net_device *pWlanHostapdDev = NULL;
3779 hdd_adapter_t *pHostapdAdapter = NULL;
3780 v_CONTEXT_t pVosContext= NULL;
3781
Jeff Johnson295189b2012-06-20 16:38:30 -07003782 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07003783
3784 if (pWlanHostapdDev != NULL)
3785 {
3786 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
3787
3788 //Init the net_device structure
3789 ether_setup(pWlanHostapdDev);
3790
3791 //Initialize the adapter context to zeros.
3792 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
3793 pHostapdAdapter->dev = pWlanHostapdDev;
3794 pHostapdAdapter->pHddCtx = pHddCtx;
3795 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3796
3797 //Get the Global VOSS context.
3798 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3799 //Save the adapter context in global context for future.
3800 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3801
3802 //Init the net_device structure
3803 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3804
3805 hdd_set_ap_ops( pHostapdAdapter->dev );
3806
Jeff Johnson295189b2012-06-20 16:38:30 -07003807 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3808 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3809
3810 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3811 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3812
3813 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003814 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3815 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3816 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3817 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003818 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3819 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
3820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3821 init_completion(&pHostapdAdapter->offchannel_tx_event);
3822#endif
3823
Jeff Johnson295189b2012-06-20 16:38:30 -07003824 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3825 }
3826 return pHostapdAdapter;
3827}
3828
3829VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3830{
3831 struct net_device *dev = pAdapter->dev;
3832 VOS_STATUS status = VOS_STATUS_SUCCESS;
3833
3834 ENTER();
3835
3836 if( rtnl_lock_held )
3837 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003838 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003839 if( dev_alloc_name(dev, dev->name) < 0 )
3840 {
3841 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3842 return VOS_STATUS_E_FAILURE;
3843 }
3844 }
3845 if (register_netdevice(dev))
3846 {
3847 hddLog(VOS_TRACE_LEVEL_FATAL,
3848 "%s:Failed:register_netdevice", __func__);
3849 return VOS_STATUS_E_FAILURE;
3850 }
3851 }
3852 else
3853 {
3854 if (register_netdev(dev))
3855 {
3856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3857 return VOS_STATUS_E_FAILURE;
3858 }
3859 }
3860 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3861
3862 EXIT();
3863 return status;
3864}
3865
3866VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3867{
3868 ENTER();
3869
3870 hdd_softap_deinit_tx_rx(pAdapter);
3871
3872 /* if we are being called during driver unload, then the dev has already
3873 been invalidated. if we are being called at other times, then we can
3874 detatch the wireless device handlers */
3875 if (pAdapter->dev)
3876 {
3877 pAdapter->dev->wireless_handlers = NULL;
3878 }
3879 EXIT();
3880 return 0;
3881}