blob: 5eddeabe2c69eaaf27d2b0bfe7a3beadab0b222f [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
Agarwal Ashish51325b52014-06-16 16:50:49 +0530481#ifdef DISABLE_CONCURRENCY_AUTOSAVE
482 if (vos_concurrent_open_sessions_running())
Jeff Johnson295189b2012-06-20 16:38:30 -0700483 {
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;
Agarwal Ashish51325b52014-06-16 16:50:49 +0530574 hdd_context_t *pHddCtx = NULL;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800575 VOS_STATUS status = VOS_STATUS_SUCCESS;
576 dev = (struct net_device *)usrDataForCallback;
577 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +0530578
579 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
580 status = wlan_hdd_validate_context(pHddCtx);
581
582 if (0 != status) {
583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
584 return status;
585 }
586
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800587 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
588 {
589 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
592 }
593 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +0530594 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800595 }
596 EXIT();
597 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
598}
Jeff Johnson295189b2012-06-20 16:38:30 -0700599
600VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
601{
602 hdd_adapter_t *pHostapdAdapter;
603 hdd_ap_ctx_t *pHddApCtx;
604 hdd_hostapd_state_t *pHostapdState;
605 struct net_device *dev;
606 eSapHddEvent sapEvent;
607 union iwreq_data wrqu;
608 v_BYTE_t *we_custom_event_generic = NULL;
609 int we_event = 0;
610 int i = 0;
611 v_U8_t staId;
612 VOS_STATUS vos_status;
613 v_BOOL_t bWPSState;
614 v_BOOL_t bApActive = FALSE;
615 v_BOOL_t bAuthRequired = TRUE;
616 tpSap_AssocMacAddr pAssocStasArray = NULL;
617 char unknownSTAEvent[IW_CUSTOM_MAX+1];
618 char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
619 v_BYTE_t we_custom_start_event[64];
620 char *startBssEvent;
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800621 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800622 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson5f12e902013-04-03 10:21:46 -0700623 struct iw_michaelmicfailure msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700624
625 dev = (struct net_device *)usrDataForCallback;
626 pHostapdAdapter = netdev_priv(dev);
Madan Mohan Koyyalamudie1b791f2013-07-24 12:53:33 +0530627
628 if ((NULL == pHostapdAdapter) ||
629 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
630 {
631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
632 "invalid adapter or adapter has invalid magic");
633 return eHAL_STATUS_FAILURE;
634 }
635
Jeff Johnson295189b2012-06-20 16:38:30 -0700636 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
637 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
638 sapEvent = pSapEvent->sapHddEventCode;
639 memset(&wrqu, '\0', sizeof(wrqu));
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800640 pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700641
642 switch(sapEvent)
643 {
644 case eSAP_START_BSS_EVENT :
Arif Hussain6d2a3322013-11-17 19:50:10 -0800645 hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700646 pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
647 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
648 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
649
650 pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
651 vos_status = vos_event_set(&pHostapdState->vosEvent);
652
653 if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
654 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700656 goto stopbss;
657 }
658 else
659 {
660 pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
661 //@@@ need wep logic here to set privacy bit
c_hpothuffdb5272013-10-02 16:42:35 +0530662 vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
663 if (!VOS_IS_STATUS_SUCCESS(vos_status))
664 hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700665 }
666
667 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
668 {
669 // AP Inactivity timer init and start
670 vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
671 hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
672 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800673 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700674
675 vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
676 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800677 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700678
679 }
680 pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
681 pHostapdState->bssState = BSS_START;
682
683 // Send current operating channel of SoftAP to BTC-ES
684 send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0);
685
Jeff Johnson295189b2012-06-20 16:38:30 -0700686 //Check if there is any group key pending to set.
687 if( pHddApCtx->groupKey.keyLength )
688 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700689 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700690 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
691 &pHddApCtx->groupKey ) )
692 {
693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
694 "%s: WLANSAP_SetKeySta failed", __func__);
695 }
696 pHddApCtx->groupKey.keyLength = 0;
697 }
698 else if ( pHddApCtx->wepKey[0].keyLength )
699 {
700 int i=0;
701 for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
702 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700703 if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta(
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
705 &pHddApCtx->wepKey[i] ) )
706 {
707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
708 "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
709 }
710 pHddApCtx->wepKey[i].keyLength = 0;
711 }
712 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700713 //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
714 startBssEvent = "SOFTAP.enabled";
715 memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
716 memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
717 memset(&wrqu, 0, sizeof(wrqu));
718 wrqu.data.length = strlen(startBssEvent);
719 we_event = IWEVCUSTOM;
720 we_custom_event_generic = we_custom_start_event;
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -0700721 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700722 break; //Event will be sent after Switch-Case stmt
723
724 case eSAP_STOP_BSS_EVENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -0800725 hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700726 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
727
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700728 //Free up Channel List incase if it is set
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700729 sapCleanupChannelList();
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -0700730
Jeff Johnson295189b2012-06-20 16:38:30 -0700731 pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
Jeff Johnson295189b2012-06-20 16:38:30 -0700732 goto stopbss;
733 case eSAP_STA_SET_KEY_EVENT:
734 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800735 hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700736 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
737 return VOS_STATUS_SUCCESS;
738 case eSAP_STA_DEL_KEY_EVENT:
739 //TODO: forward the message to hostapd once implementtation is done for now just print
Arif Hussain6d2a3322013-11-17 19:50:10 -0800740 hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
Jeff Johnson295189b2012-06-20 16:38:30 -0700741 return VOS_STATUS_SUCCESS;
742 case eSAP_STA_MIC_FAILURE_EVENT:
743 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700744 memset(&msg, '\0', sizeof(msg));
745 msg.src_addr.sa_family = ARPHRD_ETHER;
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800746 memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800747 hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
Jeff Johnson43971f52012-07-17 12:26:56 -0700748 if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 msg.flags = IW_MICFAILURE_GROUP;
750 else
751 msg.flags = IW_MICFAILURE_PAIRWISE;
752 memset(&wrqu, 0, sizeof(wrqu));
753 wrqu.data.length = sizeof(msg);
754 we_event = IWEVMICHAELMICFAILURE;
755 we_custom_event_generic = (v_BYTE_t *)&msg;
756 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700757 /* inform mic failure to nl80211 */
758 cfg80211_michael_mic_failure(dev,
759 pSapEvent->sapevt.
760 sapStationMICFailureEvent.staMac.bytes,
Jeff Johnson43971f52012-07-17 12:26:56 -0700761 ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
Jeff Johnson295189b2012-06-20 16:38:30 -0700762 NL80211_KEYTYPE_GROUP :
763 NL80211_KEYTYPE_PAIRWISE),
764 pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
765 pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
766 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 break;
768
769 case eSAP_STA_ASSOC_EVENT:
770 case eSAP_STA_REASSOC_EVENT:
771 wrqu.addr.sa_family = ARPHRD_ETHER;
772 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800773 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800774 hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700775 we_event = IWEVREGISTERED;
776
777 WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
778
779 if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
780 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
781 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
782 {
783 bAuthRequired = FALSE;
784 }
785
786 if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
787 {
c_hpothuffdb5272013-10-02 16:42:35 +0530788 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700789 TRUE,
790 pHddApCtx->uPrivacy,
791 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
792 0,
793 0,
794 (v_MACADDR_t *)wrqu.addr.sa_data,
795 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530796
797 if (!VOS_IS_STATUS_SUCCESS(vos_status))
798 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
799 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700800 }
801 else
802 {
c_hpothuffdb5272013-10-02 16:42:35 +0530803 vos_status = hdd_softap_RegisterSTA( pHostapdAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 FALSE,
805 pHddApCtx->uPrivacy,
806 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId,
807 0,
808 0,
809 (v_MACADDR_t *)wrqu.addr.sa_data,
810 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled);
c_hpothuffdb5272013-10-02 16:42:35 +0530811 if (!VOS_IS_STATUS_SUCCESS(vos_status))
812 hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
813 vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Amar Singhal6144c002013-05-03 16:11:42 -0700814 }
815
Jeff Johnson295189b2012-06-20 16:38:30 -0700816 // Stop AP inactivity timer
817 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
818 {
819 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
820 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800821 hddLog(LOGE, FL("Failed to start AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800823#ifdef WLAN_OPEN_SOURCE
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -0800824 if (wake_lock_active(&pHddCtx->sap_wake_lock))
825 {
826 wake_unlock(&pHddCtx->sap_wake_lock);
827 }
Amar Singhal6144c002013-05-03 16:11:42 -0700828 wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
831 {
832 struct station_info staInfo;
833 v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
834
835 memset(&staInfo, 0, sizeof(staInfo));
836 if (iesLen <= MAX_ASSOC_IND_IE_LEN )
837 {
838 staInfo.assoc_req_ies =
839 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
840 staInfo.assoc_req_ies_len = iesLen;
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700842 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
843#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 cfg80211_new_sta(dev,
845 (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
846 &staInfo, GFP_KERNEL);
847 }
848 else
849 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800850 hddLog(LOGE, FL(" Assoc Ie length is too long"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700851 }
852 }
853#endif
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800854 pScanInfo = &pHddCtx->scan_info;
855 // Lets do abort scan to ensure smooth authentication for client
856 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
857 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530858 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
859 eCSR_SCAN_ABORT_DEFAULT);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800860 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700861
862 break;
863 case eSAP_STA_DISASSOC_EVENT:
864 memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
Kumar Pavan0cf0cf22012-12-13 15:13:41 -0800865 sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800866 hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Jeff Johnson295189b2012-06-20 16:38:30 -0700867 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
868 hddLog(LOG1," User initiated disassociation");
869 else
870 hddLog(LOG1," MAC initiated disassociation");
871 we_event = IWEVEXPIRED;
872 vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
873 if (!VOS_IS_STATUS_SUCCESS(vos_status))
874 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700875 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 -0700876 return VOS_STATUS_E_FAILURE;
877 }
878 hdd_softap_DeregisterSTA(pHostapdAdapter, staId);
879
880 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
881 {
882 spin_lock_bh( &pHostapdAdapter->staInfo_lock );
883 // Start AP inactivity timer if no stations associated with it
884 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
885 {
886 if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
887 {
888 bApActive = TRUE;
889 break;
890 }
891 }
892 spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
893
894 if (bApActive == FALSE)
895 {
896 if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
897 {
898 vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
899 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Arif Hussain6d2a3322013-11-17 19:50:10 -0800900 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 }
902 else
903 VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
904 }
905 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700906#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
907 cfg80211_del_sta(dev,
908 (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
909 GFP_KERNEL);
910#endif
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -0800911 //Update the beacon Interval if it is P2P GO
c_hpothuffdb5272013-10-02 16:42:35 +0530912 vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
913 if (VOS_STATUS_SUCCESS != vos_status)
914 {
915 hddLog(LOGE, "%s: failed to update Beacon interval %d",
916 __func__, vos_status);
917 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700918 break;
919 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
920 {
921 static const char * message ="MLMEWPSPBCPROBEREQ.indication";
922 union iwreq_data wreq;
923
924 down(&pHddApCtx->semWpsPBCOverlapInd);
925 pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;
926
927 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
928 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
929
930 vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
Arif Hussain6d2a3322013-11-17 19:50:10 -0800931 hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 memset(&wreq, 0, sizeof(wreq));
933 wreq.data.length = strlen(message); // This is length of message
934 wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);
935
936 return VOS_STATUS_SUCCESS;
937 }
938 case eSAP_ASSOC_STA_CALLBACK_EVENT:
939 pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
940 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
941 { // List of associated stations
942 for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
943 {
944 hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
945 i+1,
946 pAssocStasArray->assocId,
947 pAssocStasArray->staId,
948 MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
949 pAssocStasArray++;
950 }
951 }
952 vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800953 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 case eSAP_INDICATE_MGMT_FRAME:
956 hdd_indicateMgmtFrame( pHostapdAdapter,
957 pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength,
958 pSapEvent->sapevt.sapManagementFrameInfo.pbFrames,
959 pSapEvent->sapevt.sapManagementFrameInfo.frameType,
Chilam NG571c65a2013-01-19 12:27:36 +0530960 pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700961 return VOS_STATUS_SUCCESS;
962 case eSAP_REMAIN_CHAN_READY:
963 hdd_remainChanReadyHandler( pHostapdAdapter );
964 return VOS_STATUS_SUCCESS;
965 case eSAP_SEND_ACTION_CNF:
966 hdd_sendActionCnf( pHostapdAdapter,
967 ( eSAP_STATUS_SUCCESS ==
968 pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ?
969 TRUE : FALSE );
970 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 case eSAP_UNKNOWN_STA_JOIN:
972 snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
973 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
974 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
975 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
976 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
977 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
978 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
979 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
980 wrqu.data.pointer = unknownSTAEvent;
981 wrqu.data.length = strlen(unknownSTAEvent);
982 we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
Agarwal Ashish971c2882013-10-30 20:11:12 +0530983 hddLog(LOGE,"%s", unknownSTAEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700984 break;
985
986 case eSAP_MAX_ASSOC_EXCEEDED:
987 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
988 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
989 " one or more devices to enable the new device connection",
990 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
991 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
992 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
993 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
994 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
995 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
996 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
997 wrqu.data.pointer = maxAssocExceededEvent;
998 wrqu.data.length = strlen(maxAssocExceededEvent);
999 we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
Arif Hussain6d2a3322013-11-17 19:50:10 -08001000 hddLog(LOG1,"%s", maxAssocExceededEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -07001001 break;
1002 case eSAP_STA_ASSOC_IND:
1003 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001004
1005 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001006 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001007 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
1008 return VOS_STATUS_SUCCESS;
1009
1010 case eSAP_MAC_TRIG_STOP_BSS_EVENT :
c_hpothuffdb5272013-10-02 16:42:35 +05301011 vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
1012 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1013 {
1014 hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status);
1015 }
Madan Mohan Koyyalamudi167b95e2012-11-27 15:53:38 -08001016 return VOS_STATUS_SUCCESS;
1017
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08001019 hddLog(LOG1,"SAP message is not handled");
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 goto stopbss;
1021 return VOS_STATUS_SUCCESS;
1022 }
1023 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
1024 return VOS_STATUS_SUCCESS;
1025
1026stopbss :
1027 {
1028 v_BYTE_t we_custom_event[64];
1029 char *stopBssEvent = "STOP-BSS.response";//17
1030 int event_len = strlen(stopBssEvent);
1031
1032 hddLog(LOG1, FL("BSS stop status = %s"),
1033 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1034 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1035
1036 /* Change the BSS state now since, as we are shutting things down,
1037 * we don't want interfaces to become re-enabled */
1038 pHostapdState->bssState = BSS_STOP;
1039
Gopichand Nakkalaf8fe15d2013-05-27 13:55:40 +05301040 if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
1041 {
1042 if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
1043 {
1044 vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
1045 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1046 hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
1047 }
1048
1049 vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
1050 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1051 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1052 }
1053
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 /* Stop the pkts from n/w stack as we are going to free all of
1055 * the TX WMM queues for all STAID's */
1056 hdd_hostapd_stop(dev);
1057
1058 /* reclaim all resources allocated to the BSS */
c_hpothuffdb5272013-10-02 16:42:35 +05301059 vos_status = hdd_softap_stop_bss(pHostapdAdapter);
1060 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1061 hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001062
Amar Singhal37e6f052013-03-05 16:16:54 -08001063 /* once the event is set, structure dev/pHostapdAdapter should
1064 * not be touched since they are now subject to being deleted
1065 * by another thread */
1066 if (eSAP_STOP_BSS_EVENT == sapEvent)
1067 vos_event_set(&pHostapdState->vosEvent);
1068
Jeff Johnson295189b2012-06-20 16:38:30 -07001069 /* notify userspace that the BSS has stopped */
1070 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1071 memcpy(&we_custom_event, stopBssEvent, event_len);
1072 memset(&wrqu, 0, sizeof(wrqu));
1073 wrqu.data.length = event_len;
1074 we_event = IWEVCUSTOM;
1075 we_custom_event_generic = we_custom_event;
1076 wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07001077 hdd_dump_concurrency_info(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 }
1079 return VOS_STATUS_SUCCESS;
1080}
Chet Lanctot8cecea22014-02-11 19:09:36 -08001081
1082int hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001083 tHalHandle halHandle,
Chet Lanctot8cecea22014-02-11 19:09:36 -08001084 eCsrEncryptionType *pEncryptType,
1085 eCsrEncryptionType *mcEncryptType,
1086 eCsrAuthType *pAuthType,
1087 v_BOOL_t *pMFPCapable,
1088 v_BOOL_t *pMFPRequired,
1089 u_int16_t gen_ie_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 u_int8_t *gen_ie )
1091{
1092 tDot11fIERSN dot11RSNIE;
1093 tDot11fIEWPA dot11WPAIE;
1094
1095 tANI_U8 *pRsnIe;
1096 tANI_U16 RSNIeLen;
1097
1098 if (NULL == halHandle)
1099 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001100 hddLog(LOGE, FL("Error haHandle returned NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 return -EINVAL;
1102 }
1103
1104 // Validity checks
1105 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1106 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1107 return -EINVAL;
1108 // Type check
1109 if ( gen_ie[0] == DOT11F_EID_RSN)
1110 {
1111 // Validity checks
1112 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1113 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1114 {
1115 return VOS_STATUS_E_FAILURE;
1116 }
1117 // Skip past the EID byte and length byte
1118 pRsnIe = gen_ie + 2;
1119 RSNIeLen = gen_ie_len - 2;
1120 // Unpack the RSN IE
1121 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1122 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1123 pRsnIe,
1124 RSNIeLen,
1125 &dot11RSNIE);
1126 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001127 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001128 __func__, dot11RSNIE.pwise_cipher_suite_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001129 hddLog(LOG1, FL("%s: authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001130 __func__, dot11RSNIE.akm_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001131 /*Here we have followed the apple base code,
1132 but probably I suspect we can do something different*/
1133 //dot11RSNIE.akm_suite_count
1134 // Just translate the FIRST one
1135 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1136 //dot11RSNIE.pwise_cipher_suite_count
1137 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1138 //dot11RSNIE.gp_cipher_suite_count
1139 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1140 // Set the PMKSA ID Cache for this interface
Chet Lanctot8cecea22014-02-11 19:09:36 -08001141 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1142 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Jeff Johnson295189b2012-06-20 16:38:30 -07001143
1144 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1145 } else
1146 if (gen_ie[0] == DOT11F_EID_WPA)
1147 {
1148 // Validity checks
1149 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
1150 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
1151 {
1152 return VOS_STATUS_E_FAILURE;
1153 }
1154 // Skip past the EID byte and length byte - and four byte WiFi OUI
1155 pRsnIe = gen_ie + 2 + 4;
1156 RSNIeLen = gen_ie_len - (2 + 4);
1157 // Unpack the WPA IE
1158 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1159 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
1160 pRsnIe,
1161 RSNIeLen,
1162 &dot11WPAIE);
1163 // Copy out the encryption and authentication types
Arif Hussain6d2a3322013-11-17 19:50:10 -08001164 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001165 __func__, dot11WPAIE.unicast_cipher_count );
Arif Hussain6d2a3322013-11-17 19:50:10 -08001166 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001167 __func__, dot11WPAIE.auth_suite_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07001168 //dot11WPAIE.auth_suite_count
1169 // Just translate the FIRST one
1170 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
1171 //dot11WPAIE.unicast_cipher_count
1172 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
1173 //dot11WPAIE.unicast_cipher_count
1174 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001175 *pMFPCapable = VOS_FALSE;
1176 *pMFPRequired = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001177 }
1178 else
1179 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001180 hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 return VOS_STATUS_E_FAILURE;
1182 }
1183 return VOS_STATUS_SUCCESS;
1184}
Leo Chang614d2072013-08-22 14:59:44 -07001185
Leo Chang0b0e45a2013-12-15 15:18:55 -08001186#ifdef FEATURE_WLAN_CH_AVOID
1187/**---------------------------------------------------------------------------
1188
1189 \brief hdd_hostapd_freq_to_chn() -
1190
1191 Input frequency translated into channel number
1192
1193 \param - freq input frequency with order of kHz
1194
1195 \return - corresponding channel number.
1196 incannot find correct channel number, return 0
1197
1198 --------------------------------------------------------------------------*/
1199v_U16_t hdd_hostapd_freq_to_chn
1200(
1201 v_U16_t freq
1202)
1203{
1204 int loop;
1205
1206 for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++)
1207 {
1208 if (rfChannels[loop].targetFreq == freq)
1209 {
1210 return rfChannels[loop].channelNum;
1211 }
1212 }
1213
1214 return (0);
1215}
1216
1217/*==========================================================================
1218 FUNCTION sapUpdateUnsafeChannelList
1219
1220 DESCRIPTION
1221 Function Undate unsafe channel list table
1222
1223 DEPENDENCIES
1224 NA.
1225
1226 PARAMETERS
1227
1228 IN
1229 pSapCtx : SAP context pointer, include unsafe channel list
1230
1231 RETURN VALUE
1232 NONE
1233============================================================================*/
1234void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx,
1235 v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount)
1236{
1237 v_U16_t i, j;
1238
1239 vos_mem_zero((void *)pHddCtx->unsafeChannelList,
1240 sizeof(pHddCtx->unsafeChannelList));
1241 if (0 == unsafeChannelCount)
1242 {
1243 pHddCtx->unsafeChannelCount = 0;
1244 }
1245 else
1246 {
1247 vos_mem_copy((void *)pHddCtx->unsafeChannelList,
1248 unsafeChannelList,
1249 unsafeChannelCount * sizeof(tANI_U16));
1250 pHddCtx->unsafeChannelCount = unsafeChannelCount;
1251 }
1252
1253 /* Flush, default set all channel safe */
1254 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
1255 {
1256 safeChannels[i].isSafe = VOS_TRUE;
1257 }
1258
1259 /* Try to find unsafe channel */
1260 for (i = 0; i < pHddCtx->unsafeChannelCount; i++)
1261 {
1262 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
1263 {
1264 if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i])
1265 {
1266 /* Found unsafe channel, update it */
1267 safeChannels[j].isSafe = VOS_FALSE;
1268 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
1269 "%s : CH %d is not safe",
1270 __func__, pHddCtx->unsafeChannelList[i]);
1271 break;
1272 }
1273 }
1274 }
1275
1276 return;
1277}
1278
1279/**---------------------------------------------------------------------------
Sushant Kaushikba6764e2014-06-30 19:52:09 +05301280 \brief hdd_restart_softap() -
1281 Restart SAP on STA channel to support
1282 STA + SAP concurrency.
1283
1284 --------------------------------------------------------------------------*/
1285void hdd_restart_softap
1286(
1287 hdd_context_t *pHddCtx,
1288 hdd_adapter_t *pHostapdAdapter
1289)
1290{
1291 tSirChAvoidIndType *chAvoidInd;
1292
1293 chAvoidInd =
1294 (tSirChAvoidIndType *)vos_mem_malloc(sizeof(tSirChAvoidIndType));
1295 if (NULL == chAvoidInd)
1296 {
1297 hddLog(VOS_TRACE_LEVEL_INFO, FL("CH_AVOID IND buffer alloc Fail"));
1298 return ;
1299 }
1300 chAvoidInd->avoidRangeCount = 1;
1301 chAvoidInd->avoidFreqRange[0].startFreq =
1302 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1303 chAvoidInd->avoidFreqRange[0].endFreq =
1304 vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
1305 hdd_hostapd_ch_avoid_cb((void *)pHddCtx, (void *)chAvoidInd);
1306}
1307/**---------------------------------------------------------------------------
Leo Chang0b0e45a2013-12-15 15:18:55 -08001308
1309 \brief hdd_hostapd_ch_avoid_cb() -
1310
1311 Avoid channel notification from FW handler.
1312 FW will send un-safe channle list to avoid overwrapping.
1313 hostapd should not use notified channel
1314
1315 \param - pAdapter HDD adapter pointer
1316 indParam channel avoid notification parameter
1317
1318 \return - None
1319
1320 --------------------------------------------------------------------------*/
1321void hdd_hostapd_ch_avoid_cb
1322(
1323 void *pAdapter,
1324 void *indParam
1325)
1326{
1327 hdd_adapter_t *pHostapdAdapter = NULL;
1328 hdd_context_t *hddCtxt;
1329 tSirChAvoidIndType *chAvoidInd;
1330 v_U8_t rangeLoop;
1331 v_U16_t channelLoop;
1332 v_U16_t dupCheck;
1333 v_U16_t startChannel;
1334 v_U16_t endChannel;
1335 v_U16_t unsafeChannelCount = 0;
1336 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
1337 v_CONTEXT_t pVosContext;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001338 tHddAvoidFreqList hddAvoidFreqList;
1339 tANI_U32 i;
Leo Chang0b0e45a2013-12-15 15:18:55 -08001340
1341 /* Basic sanity */
1342 if ((NULL == pAdapter) || (NULL == indParam))
1343 {
1344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1345 "%s : Invalid arguments", __func__);
1346 return;
1347 }
1348
1349 hddCtxt = (hdd_context_t *)pAdapter;
1350 chAvoidInd = (tSirChAvoidIndType *)indParam;
1351 pVosContext = hddCtxt->pvosContext;
1352
1353 /* Make unsafe channel list */
1354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1355 "%s : band count %d",
1356 __func__, chAvoidInd->avoidRangeCount);
1357 vos_mem_zero((void *)unsafeChannelList,
1358 NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t));
1359 for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++)
1360 {
1361 startChannel = hdd_hostapd_freq_to_chn(
1362 chAvoidInd->avoidFreqRange[rangeLoop].startFreq);
1363 endChannel = hdd_hostapd_freq_to_chn(
1364 chAvoidInd->avoidFreqRange[rangeLoop].endFreq);
1365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1366 "%s : start %d : %d, end %d : %d",
1367 __func__,
1368 chAvoidInd->avoidFreqRange[rangeLoop].startFreq,
1369 startChannel,
1370 chAvoidInd->avoidFreqRange[rangeLoop].endFreq,
1371 endChannel);
1372 for (channelLoop = startChannel;
1373 channelLoop < (endChannel + 1);
1374 channelLoop++)
1375 {
1376 /* Channel duplicate check routine */
1377 for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++)
1378 {
1379 if (unsafeChannelList[dupCheck] == channelLoop)
1380 {
1381 /* This channel is duplicated */
1382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1383 "%s : found duplicated channel %d",
1384 __func__, channelLoop);
1385 break;
1386 }
1387 }
1388 if (dupCheck == unsafeChannelCount)
1389 {
1390 unsafeChannelList[unsafeChannelCount] = channelLoop;
1391 unsafeChannelCount++;
1392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1393 "%s : unsafe channel %d, count %d",
1394 __func__,
1395 channelLoop, unsafeChannelCount);
1396 }
1397 else
1398 {
1399 /* DUP, do nothing */
1400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1401 "%s : duplicated channel %d",
1402 __func__, channelLoop);
1403 }
1404 }
1405 }
1406 /* Update unsafe channel cache
1407 * WCN Platform Driver cache */
1408 wcnss_set_wlan_unsafe_channel(unsafeChannelList,
1409 unsafeChannelCount);
1410
1411 /* Store into local cache
1412 * Start with STA and later start SAP
1413 * in this scenario, local cache will be used */
1414 hdd_hostapd_update_unsafe_channel_list(hddCtxt,
1415 unsafeChannelList,
1416 unsafeChannelCount);
1417
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08001418 /* generate vendor specific event */
1419 vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList));
1420 for (i = 0; i < chAvoidInd->avoidRangeCount; i++)
1421 {
1422 hddAvoidFreqList.avoidFreqRange[i].startFreq =
1423 chAvoidInd->avoidFreqRange[i].startFreq;
1424 hddAvoidFreqList.avoidFreqRange[i].endFreq =
1425 chAvoidInd->avoidFreqRange[i].endFreq;
1426 }
1427 hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount;
1428
1429 wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList);
1430
Leo Chang0b0e45a2013-12-15 15:18:55 -08001431 /* Get SAP context first
1432 * SAP and P2PGO would not concurrent */
1433 pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP);
1434 if ((pHostapdAdapter) && (unsafeChannelCount))
1435 {
1436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1437 "%s : Current operation channel %d",
1438 __func__,
1439 pHostapdAdapter->sessionCtx.ap.operatingChannel);
1440 for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++)
1441 {
1442 if (((unsafeChannelList[channelLoop] ==
1443 pHostapdAdapter->sessionCtx.ap.operatingChannel)) &&
1444 (AUTO_CHANNEL_SELECT ==
1445 pHostapdAdapter->sessionCtx.ap.sapConfig.channel))
1446 {
1447 /* current operating channel is un-safe channel
1448 * restart driver */
1449 hdd_hostapd_stop(pHostapdAdapter->dev);
1450 break;
1451 }
1452 }
1453 }
1454
1455 return;
1456}
1457
1458#endif /* FEATURE_WLAN_CH_AVOID */
1459
Jeff Johnson295189b2012-06-20 16:38:30 -07001460int
1461static iw_softap_setparam(struct net_device *dev,
1462 struct iw_request_info *info,
1463 union iwreq_data *wrqu, char *extra)
1464{
1465 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001466 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -07001467 int *value = (int *)extra;
1468 int sub_cmd = value[0];
1469 int set_value = value[1];
1470 eHalStatus status;
1471 int ret = 0; /* success */
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001472 v_CONTEXT_t pVosContext;
1473
1474 if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx)
1475 {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1477 "%s: either hostapd Adapter is null or HDD ctx is null",
1478 __func__);
1479 return -1;
1480 }
1481
1482 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1483 if (!hHal)
1484 {
1485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1486 "%s: Hal ctx is null", __func__);
1487 return -1;
1488 }
1489
1490 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1491 if (!pVosContext)
1492 {
1493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1494 "%s: Vos ctx is null", __func__);
1495 return -1;
1496 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001497
1498 switch(sub_cmd)
1499 {
1500
1501 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001502 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001503 {
1504 ret = -EIO;
1505 }
1506 break;
1507
1508 case QCSAP_PARAM_ACL_MODE:
1509 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
1510 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
1511 {
1512 hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
1513 ret = -EINVAL;
1514 }
1515 else
1516 {
1517 WLANSAP_SetMode(pVosContext, set_value);
1518 }
1519 break;
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05301520
1521 case QCSAP_PARAM_SET_AUTO_CHANNEL:
1522 if ((0 != set_value) && (1 != set_value))
1523 {
1524 hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value);
1525 ret = -EINVAL;
1526 }
1527 else
1528 {
1529 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value;
1530 }
1531 break;
1532
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 case QCSAP_PARAM_MAX_ASSOC:
1534 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
1535 {
1536 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
1537 ret = -EINVAL;
1538 }
1539 else
1540 {
1541 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
1542 {
1543 hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
1544 "Setting it to max allowed and continuing"),
1545 set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
1546 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
1547 }
1548 status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
1549 set_value, NULL, eANI_BOOLEAN_FALSE);
1550 if ( status != eHAL_STATUS_SUCCESS )
1551 {
1552 hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
1553 status);
1554 ret = -EIO;
1555 }
1556 }
1557 break;
1558
1559 case QCSAP_PARAM_HIDE_SSID:
1560 {
1561 eHalStatus status = eHAL_STATUS_SUCCESS;
1562 status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
1563 if(eHAL_STATUS_SUCCESS != status)
1564 {
1565 hddLog(VOS_TRACE_LEVEL_ERROR,
1566 "%s: QCSAP_PARAM_HIDE_SSID failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001567 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 return status;
1569 }
1570 break;
1571 }
1572
Leo Chang614d2072013-08-22 14:59:44 -07001573 case QCSAP_PARAM_SET_MC_RATE:
1574 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07001575 tSirRateUpdateInd *rateUpdate;
1576
1577 rateUpdate = (tSirRateUpdateInd *)
1578 vos_mem_malloc(sizeof(tSirRateUpdateInd));
1579 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07001580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR,
Leo Chang1f98cbd2013-10-17 15:03:52 -07001582 "%s: SET_MC_RATE indication alloc fail", __func__);
1583 ret = -1;
1584 break;
1585 }
1586 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
1587
1588 hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
1589 /* Ignore unicast */
1590 rateUpdate->ucastDataRate = -1;
1591 rateUpdate->mcastDataRate24GHz = set_value;
1592 rateUpdate->mcastDataRate5GHz = set_value;
1593 rateUpdate->mcastDataRate24GHzTxFlag = 0;
1594 rateUpdate->mcastDataRate5GHzTxFlag = 0;
1595 status = sme_SendRateUpdateInd(hHal, rateUpdate);
1596 if (eHAL_STATUS_SUCCESS != status)
1597 {
1598 hddLog(VOS_TRACE_LEVEL_ERROR,
1599 "%s: SET_MC_RATE failed", __func__);
1600 vos_mem_free(rateUpdate);
1601 ret = -1;
Leo Chang614d2072013-08-22 14:59:44 -07001602 }
1603 break;
1604 }
1605
Jeff Johnson295189b2012-06-20 16:38:30 -07001606 default:
1607 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
1608 sub_cmd, set_value);
1609 ret = -EINVAL;
1610 break;
1611 }
1612
1613 return ret;
1614}
1615
1616
1617int
1618static iw_softap_getparam(struct net_device *dev,
1619 struct iw_request_info *info,
1620 union iwreq_data *wrqu, char *extra)
1621{
1622 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1623 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1624 int *value = (int *)extra;
1625 int sub_cmd = value[0];
1626 eHalStatus status;
1627 int ret = 0; /* success */
1628 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1629
1630 switch (sub_cmd)
1631 {
1632 case QCSAP_PARAM_MAX_ASSOC:
1633 status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
1634 if (eHAL_STATUS_SUCCESS != status)
1635 {
c_hpothuffdb5272013-10-02 16:42:35 +05301636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1637 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001638 ret = -EIO;
1639 }
1640 break;
1641
1642 case QCSAP_PARAM_CLR_ACL:
Jeff Johnson43971f52012-07-17 12:26:56 -07001643 if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 {
c_hpothuffdb5272013-10-02 16:42:35 +05301645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1646 FL("WLANSAP_ClearACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 ret = -EIO;
1648 }
1649 *value = 0;
1650 break;
1651
Jeff Johnson43971f52012-07-17 12:26:56 -07001652 case QCSAP_PARAM_GET_WLAN_DBG:
1653 {
1654 vos_trace_display();
1655 *value = 0;
1656 break;
1657 }
1658
1659 case QCSAP_PARAM_AUTO_CHANNEL:
1660 {
1661 *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection;
1662 break;
1663 }
1664
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 default:
1666 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
1667 ret = -EINVAL;
1668 break;
1669
1670 }
1671
1672 return ret;
1673}
1674
1675/* Usage:
1676 BLACK_LIST = 0
1677 WHITE_LIST = 1
1678 ADD MAC = 0
1679 REMOVE MAC = 1
1680
1681 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1682 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1683 while using this ioctl
1684
1685 Syntax:
1686 iwpriv softap.0 modify_acl
1687 <6 octet mac addr> <list type> <cmd type>
1688
1689 Examples:
1690 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
1691 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1692 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
1693 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1694*/
1695int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
1696 union iwreq_data *wrqu, char *extra)
1697{
1698 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1699 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1700 v_BYTE_t *value = (v_BYTE_t*)extra;
1701 v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
1702 int listType, cmd, i;
1703 int ret = 0; /* success */
1704
1705 ENTER();
1706 for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
1707 {
1708 pPeerStaMac[i] = *(value+i);
1709 }
1710 listType = (int)(*(value+i));
1711 i++;
1712 cmd = (int)(*(value+i));
1713
Arif Hussain24bafea2013-11-15 15:10:03 -08001714 hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
1715 __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07001716
1717 if (WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd)
1718 != VOS_STATUS_SUCCESS)
1719 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001720 hddLog(LOGE, FL("Modify ACL failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001721 ret = -EIO;
1722 }
1723 EXIT();
1724 return ret;
1725}
1726
1727int
1728static iw_softap_getchannel(struct net_device *dev,
1729 struct iw_request_info *info,
1730 union iwreq_data *wrqu, char *extra)
1731{
1732 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1733
Jeff Johnson43971f52012-07-17 12:26:56 -07001734 int *value = (int *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001735
Jeff Johnson43971f52012-07-17 12:26:56 -07001736 *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07001737 return 0;
1738}
1739
Jeff Johnsone7245742012-09-05 17:12:55 -07001740int
schang86c22c42013-03-13 18:41:24 -07001741static iw_softap_set_max_tx_power(struct net_device *dev,
Jeff Johnsone7245742012-09-05 17:12:55 -07001742 struct iw_request_info *info,
1743 union iwreq_data *wrqu, char *extra)
1744{
1745 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1746 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
schang86c22c42013-03-13 18:41:24 -07001747 int *value = (int *)extra;
Jeff Johnsone7245742012-09-05 17:12:55 -07001748 int set_value;
1749 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1750 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
1751
schang86c22c42013-03-13 18:41:24 -07001752 if (NULL == value)
Jeff Johnsone7245742012-09-05 17:12:55 -07001753 return -ENOMEM;
1754
Leo Changd37675a2013-08-01 13:19:45 -07001755 /* Assign correct slef MAC address */
1756 vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
1757 VOS_MAC_ADDR_SIZE);
1758 vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
1759 VOS_MAC_ADDR_SIZE);
1760
schang86c22c42013-03-13 18:41:24 -07001761 set_value = value[0];
1762 if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
1763 {
1764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001765 __func__);
schang86c22c42013-03-13 18:41:24 -07001766 return -EIO;
1767 }
1768
1769 return 0;
1770}
1771
1772int
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05301773static iw_display_data_path_snapshot(struct net_device *dev,
1774 struct iw_request_info *info,
1775 union iwreq_data *wrqu, char *extra)
1776{
1777
1778 /* Function intitiating dumping states of
1779 * HDD(WMM Tx Queues)
1780 * TL State (with Per Client infor)
1781 * DXE Snapshot (Called at the end of TL Snapshot)
1782 */
1783 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1784 hddLog(LOGE, "%s: called for SAP",__func__);
1785 hdd_wmm_tx_snapshot(pHostapdAdapter);
1786 WLANTL_TLDebugMessage(VOS_TRUE);
1787 return 0;
1788}
1789
1790int
schang86c22c42013-03-13 18:41:24 -07001791static iw_softap_set_tx_power(struct net_device *dev,
1792 struct iw_request_info *info,
1793 union iwreq_data *wrqu, char *extra)
1794{
1795 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1796 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
1797 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
1798 int *value = (int *)extra;
1799 int set_value;
1800 ptSapContext pSapCtx = NULL;
1801
1802 if (NULL == value)
1803 return -ENOMEM;
1804
1805 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1806 if (NULL == pSapCtx)
1807 {
1808 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1809 "%s: Invalid SAP pointer from pvosGCtx", __func__);
1810 return VOS_STATUS_E_FAULT;
Jeff Johnsone7245742012-09-05 17:12:55 -07001811 }
1812
1813 set_value = value[0];
schang86c22c42013-03-13 18:41:24 -07001814 if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value))
Jeff Johnsone7245742012-09-05 17:12:55 -07001815 {
schang86c22c42013-03-13 18:41:24 -07001816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
Jeff Johnsone7245742012-09-05 17:12:55 -07001817 __func__);
1818 return -EIO;
1819 }
1820
1821 return 0;
1822}
1823
Kiet Lambcf38522013-10-26 18:28:27 +05301824/**---------------------------------------------------------------------------
1825
1826 \brief iw_softap_set_trafficmonitor() -
1827 This function dynamically enable/disable traffic monitor functonality
1828 the command iwpriv wlanX setTrafficMon <value>.
1829
1830 \param - dev - Pointer to the net device.
1831 - addr - Pointer to the sockaddr.
1832 \return - 0 for success, non zero for failure
1833
1834 --------------------------------------------------------------------------*/
1835
1836static int iw_softap_set_trafficmonitor(struct net_device *dev,
1837 struct iw_request_info *info,
1838 union iwreq_data *wrqu, char *extra)
1839{
1840 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik128a0bb2014-08-07 20:24:54 +05301841 int *isSetTrafficMon = (int *)extra;
Kiet Lambcf38522013-10-26 18:28:27 +05301842 hdd_context_t *pHddCtx;
1843 int status;
1844
1845 if (NULL == pAdapter)
1846 {
1847 VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1848 "%s: HDD adapter is Null", __func__);
1849 return -ENODEV;
1850 }
1851
1852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1853
1854 status = wlan_hdd_validate_context(pHddCtx);
1855
1856 if (0 != status)
1857 {
1858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1859 "%s: HDD context is not valid", __func__);
1860 return status;
1861 }
1862
1863 hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__);
1864
1865 if (NULL == isSetTrafficMon)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
1868 "%s: Invalid SAP pointer from extra", __func__);
1869 return -ENOMEM;
1870 }
1871
1872 if (TRUE == *isSetTrafficMon)
1873 {
1874 pHddCtx->cfg_ini->enableTrafficMonitor= TRUE;
1875 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
1876 {
1877 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1878 "%s: failed to Start Traffic Monitor timer ", __func__ );
1879 return -EIO;
1880 }
1881 }
1882 else if (FALSE == *isSetTrafficMon)
1883 {
1884 pHddCtx->cfg_ini->enableTrafficMonitor= FALSE;
1885 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
1886 {
1887 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1888 "%s: failed to Stop Traffic Monitor timer ", __func__ );
1889 return -EIO;
1890 }
1891
1892 }
1893 return 0;
1894}
1895
Jeff Johnson295189b2012-06-20 16:38:30 -07001896#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
1897
1898int
1899static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1900 struct iw_request_info *info,
1901 union iwreq_data *wrqu, char *extra)
1902{
1903 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
Jeff Johnson224f3702014-03-26 11:09:47 -07001905 char *buf;
1906 int cnt = 0;
1907 int left;
1908 int ret = 0;
1909 /* maclist_index must be u32 to match userspace */
1910 u32 maclist_index;
Jeff Johnson295189b2012-06-20 16:38:30 -07001911
Jeff Johnson224f3702014-03-26 11:09:47 -07001912 /*
1913 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
1914 * number, and even numbered iocts are supposed to have "set"
1915 * semantics. Hence the wireless extensions support in the kernel
1916 * won't correctly copy the result to userspace, so the ioctl
1917 * handler itself must copy the data. Output format is 32-bit
1918 * record length, followed by 0 or more 6-byte STA MAC addresses.
1919 *
1920 * Further note that due to the incorrect semantics, the "iwpriv"
1921 * userspace application is unable to correctly invoke this API,
1922 * hence it is not registered in the hostapd_private_args. This
1923 * API can only be invoked by directly invoking the ioctl() system
1924 * call.
1925 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001926
Jeff Johnson224f3702014-03-26 11:09:47 -07001927 /* make sure userspace allocated a reasonable buffer size */
1928 if (wrqu->data.length < sizeof(maclist_index)) {
1929 hddLog(LOG1, "%s: invalid userspace buffer", __func__);
1930 return -EINVAL;
Arif Hussained667642013-10-27 23:01:14 -07001931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001932
Jeff Johnson224f3702014-03-26 11:09:47 -07001933 /* allocate local buffer to build the response */
1934 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
1935 if (!buf) {
1936 hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
1937 return -ENOMEM;
1938 }
1939
1940 /* start indexing beyond where the record count will be written */
1941 maclist_index = sizeof(maclist_index);
1942 left = wrqu->data.length - maclist_index;
1943
1944 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1945 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
1946 if ((pStaInfo[cnt].isUsed) &&
1947 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
1948 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
1949 VOS_MAC_ADDR_SIZE);
1950 maclist_index += VOS_MAC_ADDR_SIZE;
1951 left -= VOS_MAC_ADDR_SIZE;
1952 }
1953 cnt++;
1954 }
1955 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1956
1957 *((u32 *)buf) = maclist_index;
1958 wrqu->data.length = maclist_index;
1959 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
1960 hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
1961 ret = -EFAULT;
1962 }
1963 kfree(buf);
1964 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001965}
1966
1967/* Usage:
1968 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
1969 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
1970 while using this ioctl
1971
1972 Syntax:
1973 iwpriv softap.0 disassoc_sta <6 octet mac address>
1974
1975 e.g.
1976 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1977 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1978*/
1979
1980int
1981static iw_softap_disassoc_sta(struct net_device *dev,
1982 struct iw_request_info *info,
1983 union iwreq_data *wrqu, char *extra)
1984{
1985 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1986 v_U8_t *peerMacAddr;
1987
1988 ENTER();
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301989 /* iwpriv tool or framework calls this ioctl with
1990 * data passed in extra (less than 16 octets);
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 */
Gopichand Nakkala252c9ef2013-02-27 17:01:23 +05301992 peerMacAddr = (v_U8_t *)(extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07001993
Arif Hussain24bafea2013-11-15 15:10:03 -08001994 hddLog(LOG1, "%s data " MAC_ADDRESS_STR,
1995 __func__, MAC_ADDR_ARRAY(peerMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
1997 EXIT();
1998 return 0;
1999}
2000
2001int
2002static iw_softap_ap_stats(struct net_device *dev,
2003 struct iw_request_info *info,
2004 union iwreq_data *wrqu, char *extra)
2005{
2006 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2007 WLANTL_TRANSFER_STA_TYPE statBuffer;
2008 char *pstatbuf;
Girish Gowlif3769802014-06-16 21:17:16 +05302009 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07002010
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002011 memset(&statBuffer, 0, sizeof(statBuffer));
Arif Hussained667642013-10-27 23:01:14 -07002012 WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
2013 &statBuffer, (v_BOOL_t)wrqu->data.flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002014
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302015 pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL);
Arif Hussained667642013-10-27 23:01:14 -07002016 if(NULL == pstatbuf) {
2017 hddLog(LOG1, "unable to allocate memory");
2018 return -ENOMEM;
2019 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302020
2021 len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE,
Arif Hussained667642013-10-27 23:01:14 -07002022 "RUF=%d RMF=%d RBF=%d "
2023 "RUB=%d RMB=%d RBB=%d "
2024 "TUF=%d TMF=%d TBF=%d "
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302025 "TUB=%d TMB=%d TBB=%d ",
Arif Hussained667642013-10-27 23:01:14 -07002026 (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
2027 (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
2028 (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
2029 (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
2030 (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
2031 (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002032
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302033 if (len >= QCSAP_MAX_WSC_IE) {
Arif Hussained667642013-10-27 23:01:14 -07002034 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2035 kfree(pstatbuf);
2036 return -EFAULT;
2037 }
Sandeep Puligilla38e31bf2014-05-12 15:37:02 +05302038
2039 strlcpy(extra, pstatbuf, len);
2040 wrqu->data.length = len;
Arif Hussained667642013-10-27 23:01:14 -07002041 kfree(pstatbuf);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 return 0;
2043}
2044
Jeff Johnson295189b2012-06-20 16:38:30 -07002045static int iw_softap_set_channel_range(struct net_device *dev,
2046 struct iw_request_info *info,
2047 union iwreq_data *wrqu, char *extra)
2048{
2049 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2050 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08002051 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002052
2053 int *value = (int *)extra;
2054 int startChannel = value[0];
2055 int endChannel = value[1];
2056 int band = value[2];
Jeff Johnson43971f52012-07-17 12:26:56 -07002057 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 int ret = 0; /* success */
2059
2060 status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band);
2061 if(status != VOS_STATUS_SUCCESS)
2062 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002063 hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 startChannel,endChannel, band);
2065 ret = -EINVAL;
2066 }
Gopichand Nakkalaf7e53c52013-01-07 14:52:52 -08002067
2068 pHddCtx->is_dynamic_channel_range_set = 1;
2069
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 return ret;
2071}
2072
2073int iw_softap_get_channel_list(struct net_device *dev,
2074 struct iw_request_info *info,
2075 union iwreq_data *wrqu, char *extra)
2076{
2077 v_U32_t num_channels = 0;
2078 v_U8_t i = 0;
2079 v_U8_t bandStartChannel = RF_CHAN_1;
2080 v_U8_t bandEndChannel = RF_CHAN_165;
2081 v_U32_t temp_num_channels = 0;
2082 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2083 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2084 v_REGDOMAIN_t domainIdCurrentSoftap;
Jeff Johnson295189b2012-06-20 16:38:30 -07002085 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002086 eCsrBand curBand = eCSR_BAND_ALL;
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302087 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002088
2089 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
2090 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002091 hddLog(LOGE,FL("not able get the current frequency band"));
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002092 return -EIO;
2093 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 wrqu->data.length = sizeof(tChannelListInfo);
2095 ENTER();
2096
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002097 if (eCSR_BAND_24 == curBand)
2098 {
2099 bandStartChannel = RF_CHAN_1;
2100 bandEndChannel = RF_CHAN_14;
2101 }
2102 else if (eCSR_BAND_5G == curBand)
2103 {
2104 bandStartChannel = RF_CHAN_36;
2105 bandEndChannel = RF_CHAN_165;
2106 }
2107
Arif Hussain6d2a3322013-11-17 19:50:10 -08002108 hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
Gopichand Nakkala29d00192013-06-20 19:03:52 +05302109 "bandEndChannel = %hu "), curBand,
Madan Mohan Koyyalamudibb7b43a2012-10-11 14:55:09 -07002110 bandStartChannel, bandEndChannel );
2111
Jeff Johnson295189b2012-06-20 16:38:30 -07002112 for( i = bandStartChannel; i <= bandEndChannel; i++ )
2113 {
2114 if( NV_CHANNEL_ENABLE == regChannels[i].enabled )
2115 {
2116 channel_list->channels[num_channels] = rfChannels[i].channelNum;
2117 num_channels++;
2118 }
2119 }
2120
2121 /* remove indoor channels if the domain is FCC, channels 36 - 48 */
2122
2123 temp_num_channels = num_channels;
2124
2125 if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap))
2126 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05302127 hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002128 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 }
2130
Agarwal Ashish7b557c02014-07-02 12:32:39 +05302131 if(REGDOMAIN_FCC == domainIdCurrentSoftap &&
2132 pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC )
Jeff Johnson295189b2012-06-20 16:38:30 -07002133 {
2134 for(i = 0; i < temp_num_channels; i++)
2135 {
2136
2137 if((channel_list->channels[i] > 35) &&
2138 (channel_list->channels[i] < 49))
2139 {
2140 vos_mem_move(&channel_list->channels[i],
2141 &channel_list->channels[i+1],
2142 temp_num_channels - (i-1));
2143 num_channels--;
2144 temp_num_channels--;
2145 i--;
2146 }
2147 }
2148 }
2149
Arif Hussain6d2a3322013-11-17 19:50:10 -08002150 hddLog(LOG1,FL(" number of channels %d"), num_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07002151
2152 if (num_channels > IW_MAX_FREQUENCIES)
2153 {
2154 num_channels = IW_MAX_FREQUENCIES;
2155 }
2156
2157 channel_list->num_channels = num_channels;
2158 EXIT();
2159
2160 return 0;
2161}
2162
2163static
2164int iw_get_genie(struct net_device *dev,
2165 struct iw_request_info *info,
2166 union iwreq_data *wrqu, char *extra)
2167{
2168 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2169 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2170 eHalStatus status;
2171 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
2172 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2173 ENTER();
Arif Hussain6d2a3322013-11-17 19:50:10 -08002174 hddLog(LOG1,FL("getGEN_IE ioctl"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
2176 status = WLANSap_getstationIE_information(pVosContext,
2177 &length,
2178 genIeBytes);
Arif Hussained667642013-10-27 23:01:14 -07002179 length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
2180 if (wrqu->data.length < length ||
2181 copy_to_user(wrqu->data.pointer,
2182 (v_VOID_t*)genIeBytes, length))
2183 {
2184 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2185 return -EFAULT;
2186 }
2187 wrqu->data.length = length;
Jeff Johnson295189b2012-06-20 16:38:30 -07002188
Arif Hussain6d2a3322013-11-17 19:50:10 -08002189 hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length );
Jeff Johnson295189b2012-06-20 16:38:30 -07002190
2191
2192 EXIT();
2193 return 0;
2194}
2195static
2196int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
2197 struct iw_request_info *info,
2198 union iwreq_data *wrqu, char *extra)
2199{
2200 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Arif Hussained667642013-10-27 23:01:14 -07002201 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
2203 ENTER();
Arif Hussained667642013-10-27 23:01:14 -07002204
Arif Hussain6d2a3322013-11-17 19:50:10 -08002205 hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl"));
Arif Hussained667642013-10-27 23:01:14 -07002206 memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
2207
2208 WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
2209 vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
2210 pHddApCtx->WPSPBCProbeReq.probeReqIE,
2211 WPSPBCProbeReqIEs.probeReqIELen);
2212 vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
2213 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
2214 sizeof(v_MACADDR_t));
2215 if (copy_to_user(wrqu->data.pointer,
2216 (void *)&WPSPBCProbeReqIEs,
2217 sizeof(WPSPBCProbeReqIEs)))
2218 {
2219 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
2220 return -EFAULT;
2221 }
2222 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002223 hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
Arif Hussained667642013-10-27 23:01:14 -07002224 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 up(&pHddApCtx->semWpsPBCOverlapInd);
2226 EXIT();
2227 return 0;
2228}
2229
2230/**---------------------------------------------------------------------------
2231
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302232 \brief __iw_set_auth_hostap() -
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 This function sets the auth type received from the wpa_supplicant.
2234
2235 \param - dev - Pointer to the net device.
2236 - info - Pointer to the iw_request_info.
2237 - wrqu - Pointer to the iwreq_data.
2238 - extra - Pointer to the data.
2239 \return - 0 for success, non zero for failure
2240
2241 --------------------------------------------------------------------------*/
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302242int __iw_set_auth_hostap(struct net_device *dev,
2243 struct iw_request_info *info,
2244 union iwreq_data *wrqu,char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002245{
2246 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2247 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2248
2249 ENTER();
2250 switch(wrqu->param.flags & IW_AUTH_INDEX)
2251 {
2252 case IW_AUTH_TKIP_COUNTERMEASURES:
2253 {
2254 if(wrqu->param.value) {
2255 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2256 "Counter Measure started %d", wrqu->param.value);
2257 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2258 }
2259 else {
2260 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2261 "Counter Measure stopped=%d", wrqu->param.value);
2262 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2263 }
2264
2265 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
2266 wrqu->param.value);
2267 }
2268 break;
2269
2270 default:
2271
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002272 hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002273 wrqu->param.flags & IW_AUTH_INDEX);
2274 break;
2275 }
2276
2277 EXIT();
2278 return 0;
2279}
2280
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302281int iw_set_auth_hostap(struct net_device *dev,
2282 struct iw_request_info *info,
2283 union iwreq_data *wrqu,char *extra)
2284{
2285 int ret;
2286
2287 vos_ssr_protect(__func__);
2288 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
2289 vos_ssr_unprotect(__func__);
2290
2291 return ret;
2292}
2293
2294static int __iw_set_ap_encodeext(struct net_device *dev,
2295 struct iw_request_info *info,
2296 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002297{
2298 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2299 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2300 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson43971f52012-07-17 12:26:56 -07002301 int retval = 0;
2302 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07002303 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2304 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2305 int key_index;
2306 struct iw_point *encoding = &wrqu->encoding;
2307 tCsrRoamSetKey setKey;
2308// tCsrRoamRemoveKey RemoveKey;
2309 int i;
Jeff Johnson43971f52012-07-17 12:26:56 -07002310
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 ENTER();
2312
2313 key_index = encoding->flags & IW_ENCODE_INDEX;
2314
2315 if(key_index > 0) {
2316
2317 /*Convert from 1-based to 0-based keying*/
2318 key_index--;
2319 }
2320 if(!ext->key_len) {
2321#if 0
2322 /*Set the encrytion type to NONE*/
2323#if 0
2324 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2325#endif
2326
2327 RemoveKey.keyId = key_index;
2328 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2329 /*Key direction for group is RX only*/
2330 vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2331 }
2332 else {
2333 vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2334 }
2335 switch(ext->alg)
2336 {
2337 case IW_ENCODE_ALG_NONE:
2338 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2339 break;
2340 case IW_ENCODE_ALG_WEP:
2341 RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2342 break;
2343 case IW_ENCODE_ALG_TKIP:
2344 RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson43971f52012-07-17 12:26:56 -07002345 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002346 case IW_ENCODE_ALG_CCMP:
2347 RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
2348 break;
2349 default:
2350 RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2351 break;
2352 }
Arif Hussain6d2a3322013-11-17 19:50:10 -08002353 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 -07002354 __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002356 __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002357 );
Jeff Johnson43971f52012-07-17 12:26:56 -07002358 vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey);
2359 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 {
2361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
Jeff Johnson43971f52012-07-17 12:26:56 -07002362 __LINE__, vstatus );
2363 retval = -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 }
Jeff Johnson43971f52012-07-17 12:26:56 -07002365#endif
2366 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002367
Jeff Johnson43971f52012-07-17 12:26:56 -07002368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002369
2370 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2371
2372 setKey.keyId = key_index;
2373 setKey.keyLength = ext->key_len;
2374
2375 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2376 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2377 }
2378
2379 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2380 /*Key direction for group is RX only*/
2381 setKey.keyDirection = eSIR_RX_ONLY;
2382 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2383 }
2384 else {
2385
2386 setKey.keyDirection = eSIR_TX_RX;
2387 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2388 }
2389 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2390 {
2391 setKey.keyDirection = eSIR_TX_DEFAULT;
2392 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
2393 }
2394
2395 /*For supplicant pae role is zero*/
2396 setKey.paeRole = 0;
2397
2398 switch(ext->alg)
2399 {
2400 case IW_ENCODE_ALG_NONE:
2401 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2402 break;
2403
2404 case IW_ENCODE_ALG_WEP:
2405 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
2406 pHddApCtx->uPrivacy = 1;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002407 hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002408 break;
2409
2410 case IW_ENCODE_ALG_TKIP:
2411 {
2412 v_U8_t *pKey = &setKey.Key[0];
2413
2414 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
2415
2416 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
2417
2418 /*Supplicant sends the 32bytes key in this order
2419
2420 |--------------|----------|----------|
2421 | Tk1 |TX-MIC | RX Mic |
2422 |--------------|----------|----------|
2423 <---16bytes---><--8bytes--><--8bytes-->
2424
2425 */
2426 /*Sme expects the 32 bytes key to be in the below order
2427
2428 |--------------|----------|----------|
2429 | Tk1 |RX-MIC | TX Mic |
2430 |--------------|----------|----------|
2431 <---16bytes---><--8bytes--><--8bytes-->
2432 */
2433 /* Copy the Temporal Key 1 (TK1) */
2434 vos_mem_copy(pKey,ext->key,16);
2435
2436 /*Copy the rx mic first*/
2437 vos_mem_copy(&pKey[16],&ext->key[24],8);
2438
2439 /*Copy the tx mic */
2440 vos_mem_copy(&pKey[24],&ext->key[16],8);
2441
2442 }
2443 break;
2444
2445 case IW_ENCODE_ALG_CCMP:
2446 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
2447 break;
2448
2449 default:
2450 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
2451 break;
2452 }
2453
2454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302455 ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 setKey.keyId);
2457 for(i=0; i< ext->key_len; i++)
2458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2459 ("%02x"), setKey.Key[i]);
Jeff Johnson43971f52012-07-17 12:26:56 -07002460
2461 vstatus = WLANSAP_SetKeySta( pVosContext, &setKey);
2462 if ( vstatus != VOS_STATUS_SUCCESS )
Jeff Johnson295189b2012-06-20 16:38:30 -07002463 {
2464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson43971f52012-07-17 12:26:56 -07002465 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
2466 retval = -EINVAL;
2467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002468
Jeff Johnson43971f52012-07-17 12:26:56 -07002469 return retval;
Jeff Johnson295189b2012-06-20 16:38:30 -07002470}
Jeff Johnson43971f52012-07-17 12:26:56 -07002471
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302472static int iw_set_ap_encodeext(struct net_device *dev,
2473 struct iw_request_info *info,
2474 union iwreq_data *wrqu, char *extra)
2475{
2476 int ret;
2477
2478 vos_ssr_protect(__func__);
2479 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
2480 vos_ssr_unprotect(__func__);
2481
2482 return ret;
2483}
Jeff Johnson43971f52012-07-17 12:26:56 -07002484
Jeff Johnson295189b2012-06-20 16:38:30 -07002485static int iw_set_ap_mlme(struct net_device *dev,
2486 struct iw_request_info *info,
2487 union iwreq_data *wrqu,
2488 char *extra)
2489{
2490#if 0
2491 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2492 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2493
2494 ENTER();
2495
2496 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
2497 switch (mlme->cmd) {
2498 case IW_MLME_DISASSOC:
2499 case IW_MLME_DEAUTH:
2500 hddLog(LOG1, "Station disassociate");
2501 if( pAdapter->conn_info.connState == eConnectionState_Associated )
2502 {
2503 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
2504
2505 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
2506 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
2507
2508 status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason);
2509
2510 //clear all the reason codes
2511 if (status != 0)
2512 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002513 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002514 }
2515
2516 netif_stop_queue(dev);
2517 netif_carrier_off(dev);
2518 }
2519 else
2520 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002521 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 -07002522 }
2523 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002524 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd);
Jeff Johnson295189b2012-06-20 16:38:30 -07002525 return -EINVAL;
2526 }//end of switch
2527 EXIT();
2528#endif
2529 return 0;
2530// return status;
2531}
2532
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302533static int __iw_get_ap_rts_threshold(struct net_device *dev,
2534 struct iw_request_info *info,
2535 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002536{
2537 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2538 v_U32_t status = 0;
2539
2540 status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
2541
2542 return status;
2543}
2544
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302545static int iw_get_ap_rts_threshold(struct net_device *dev,
2546 struct iw_request_info *info,
2547 union iwreq_data *wrqu, char *extra)
2548{
2549 int ret;
2550
2551 vos_ssr_protect(__func__);
2552 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
2553 vos_ssr_unprotect(__func__);
2554
2555 return ret;
2556}
2557
2558static int __iw_get_ap_frag_threshold(struct net_device *dev,
2559 struct iw_request_info *info,
2560 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002561{
2562 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2563 v_U32_t status = 0;
2564
2565 status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
2566
2567 return status;
2568}
2569
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302570static int iw_get_ap_frag_threshold(struct net_device *dev,
2571 struct iw_request_info *info,
2572 union iwreq_data *wrqu, char *extra)
2573{
2574 int ret;
2575
2576 vos_ssr_protect(__func__);
2577 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
2578 vos_ssr_unprotect(__func__);
2579
2580 return ret;
2581}
2582
2583static int __iw_get_ap_freq(struct net_device *dev,
2584 struct iw_request_info *info,
2585 struct iw_freq *fwrq, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07002586{
Jeff Johnsone7245742012-09-05 17:12:55 -07002587 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2589 tHalHandle hHal;
2590 hdd_hostapd_state_t *pHostapdState;
Jeff Johnsone7245742012-09-05 17:12:55 -07002591 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002592
2593 ENTER();
2594
2595 if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) {
2596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2597 "%s:LOGP in Progress. Ignore!!!",__func__);
2598 return status;
2599 }
2600
2601 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
2602 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2603
2604 if(pHostapdState->bssState == BSS_STOP )
2605 {
2606 if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
2607 != eHAL_STATUS_SUCCESS)
2608 {
c_hpothuffdb5272013-10-02 16:42:35 +05302609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2610 FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002611 return -EIO;
2612 }
2613 else
2614 {
2615 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002616 if( TRUE == status)
2617 {
2618 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2619 * iwlist & iwconfig command shows frequency into proper
2620 * format (2.412 GHz instead of 246.2 MHz)*/
2621 fwrq->m = freq;
2622 fwrq->e = MHZ;
2623 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 }
2625 }
2626 else
2627 {
2628 channel = pHddApCtx->operatingChannel;
2629 status = hdd_wlan_get_freq(channel, &freq);
Jeff Johnsone7245742012-09-05 17:12:55 -07002630 if( TRUE == status)
2631 {
2632 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2633 * iwlist & iwconfig command shows frequency into proper
2634 * format (2.412 GHz instead of 246.2 MHz)*/
2635 fwrq->m = freq;
2636 fwrq->e = MHZ;
2637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002638 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002639 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002640}
2641
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302642static int iw_get_ap_freq(struct net_device *dev,
2643 struct iw_request_info *info,
2644 struct iw_freq *fwrq, char *extra)
2645{
2646 int ret;
2647
2648 vos_ssr_protect(__func__);
2649 ret = __iw_get_ap_freq(dev, info, fwrq, extra);
2650 vos_ssr_unprotect(__func__);
2651
2652 return ret;
2653}
2654
2655static int __iw_get_mode(struct net_device *dev,
2656 struct iw_request_info *info,
2657 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05302658{
2659 int status = 0;
2660
2661 wrqu->mode = IW_MODE_MASTER;
2662
2663 return status;
2664}
2665
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05302666static int iw_get_mode(struct net_device *dev,
2667 struct iw_request_info *info,
2668 union iwreq_data *wrqu, char *extra)
2669{
2670 int ret;
2671
2672 vos_ssr_protect(__func__);
2673 ret = __iw_get_mode(dev, info, wrqu, extra);
2674 vos_ssr_unprotect(__func__);
2675
2676 return ret;
2677}
2678
Jeff Johnson295189b2012-06-20 16:38:30 -07002679static int iw_softap_setwpsie(struct net_device *dev,
2680 struct iw_request_info *info,
2681 union iwreq_data *wrqu,
2682 char *extra)
2683{
2684 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2685 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
2686 hdd_hostapd_state_t *pHostapdState;
2687 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07002688 u_int8_t *wps_genie;
2689 u_int8_t *fwps_genie;
Jeff Johnson295189b2012-06-20 16:38:30 -07002690 u_int8_t *pos;
2691 tpSap_WPSIE pSap_WPSIe;
2692 u_int8_t WPSIeType;
2693 u_int16_t length;
Girish Gowli07c05ec2014-06-17 20:47:03 +05302694 struct iw_point s_priv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 ENTER();
2696
Girish Gowli07c05ec2014-06-17 20:47:03 +05302697 /* helper function to get iwreq_data with compat handling. */
2698 if (hdd_priv_get_data(&s_priv_data, wrqu))
2699 {
2700 return -EINVAL;
2701 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002702
Girish Gowli07c05ec2014-06-17 20:47:03 +05302703 if ((NULL == s_priv_data.pointer) || (s_priv_data.length < QCSAP_MAX_WSC_IE))
2704 {
2705 return -EINVAL;
2706 }
2707
2708 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
2709 s_priv_data.length);
Arif Hussained667642013-10-27 23:01:14 -07002710
Girish Gowli86c471e2014-06-17 19:28:05 +05302711 if(NULL == wps_genie)
Arif Hussained667642013-10-27 23:01:14 -07002712 {
Girish Gowli86c471e2014-06-17 19:28:05 +05302713 hddLog(LOG1, "%s: failed to alloc memory "
2714 "and copy data from user buffer", __func__);
Arif Hussained667642013-10-27 23:01:14 -07002715 return -EFAULT;
2716 }
2717
Girish Gowli86c471e2014-06-17 19:28:05 +05302718 fwps_genie = wps_genie;
2719
Jeff Johnson295189b2012-06-20 16:38:30 -07002720 pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
2721 if (NULL == pSap_WPSIe)
2722 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002723 hddLog(LOGE, "VOS unable to allocate memory");
Arif Hussained667642013-10-27 23:01:14 -07002724 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 return -ENOMEM;
2726 }
2727 vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
2728
Arif Hussain6d2a3322013-11-17 19:50:10 -08002729 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 -07002730 WPSIeType = wps_genie[0];
2731 if ( wps_genie[0] == eQC_WPS_BEACON_IE)
2732 {
2733 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
2734 wps_genie = wps_genie + 1;
2735 switch ( wps_genie[0] )
2736 {
2737 case DOT11F_EID_WPA:
2738 if (wps_genie[1] < 2 + 4)
2739 {
2740 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002741 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002742 return -EINVAL;
2743 }
2744 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2745 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002746 hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002747 pos = &wps_genie[6];
2748 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2749 {
2750 switch((u_int16_t)(*pos<<8) | *(pos+1))
2751 {
2752 case HDD_WPS_ELEM_VERSION:
2753 pos += 4;
2754 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002755 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT;
2757 pos += 1;
2758 break;
2759
2760 case HDD_WPS_ELEM_WPS_STATE:
2761 pos +=4;
2762 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002763 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002764 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT;
2765 pos += 1;
2766 break;
2767 case HDD_WPS_ELEM_APSETUPLOCK:
2768 pos += 4;
2769 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002770 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002771 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT;
2772 pos += 1;
2773 break;
2774 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2775 pos += 4;
2776 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002777 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002778 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT;
2779 pos += 1;
2780 break;
2781 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2782 pos += 4;
2783 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002784 hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002785 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT;
2786 pos += 2;
2787 break;
2788 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2789 pos += 4;
2790 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002791 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002792 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
2793 pos += 2;
2794 break;
2795
2796 case HDD_WPS_ELEM_UUID_E:
2797 pos += 2;
2798 length = *pos<<8 | *(pos+1);
2799 pos += 2;
2800 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length);
2801 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT;
2802 pos += length;
2803 break;
2804 case HDD_WPS_ELEM_RF_BANDS:
2805 pos += 4;
2806 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002807 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002808 pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT;
2809 pos += 1;
2810 break;
2811
2812 default:
Arif Hussain6d2a3322013-11-17 19:50:10 -08002813 hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1)));
Jeff Johnson295189b2012-06-20 16:38:30 -07002814 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002815 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002816 return -EINVAL;
2817 }
2818 }
2819 }
2820 else {
2821 hddLog (LOGE, "%s WPS IE Mismatch %X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002822 __func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002823 }
2824 break;
2825
2826 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002827 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002828 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002829 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002830 return 0;
2831 }
2832 }
2833 else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE)
2834 {
2835 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
2836 wps_genie = wps_genie + 1;
2837 switch ( wps_genie[0] )
2838 {
2839 case DOT11F_EID_WPA:
2840 if (wps_genie[1] < 2 + 4)
2841 {
2842 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07002843 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07002844 return -EINVAL;
2845 }
2846 else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
2847 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002848 hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2);
Jeff Johnson295189b2012-06-20 16:38:30 -07002849 pos = &wps_genie[6];
2850 while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) )
2851 {
2852 switch((u_int16_t)(*pos<<8) | *(pos+1))
2853 {
2854 case HDD_WPS_ELEM_VERSION:
2855 pos += 4;
2856 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002857 hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version);
Jeff Johnson295189b2012-06-20 16:38:30 -07002858 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT;
2859 pos += 1;
2860 break;
2861
2862 case HDD_WPS_ELEM_WPS_STATE:
2863 pos +=4;
2864 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002865 hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002866 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT;
2867 pos += 1;
2868 break;
2869 case HDD_WPS_ELEM_APSETUPLOCK:
2870 pos += 4;
2871 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002872 hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked);
Jeff Johnson295189b2012-06-20 16:38:30 -07002873 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT;
2874 pos += 1;
2875 break;
2876 case HDD_WPS_ELEM_SELECTEDREGISTRA:
2877 pos += 4;
2878 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002879 hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra);
Jeff Johnson295189b2012-06-20 16:38:30 -07002880 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
2881 pos += 1;
2882 break;
2883 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
2884 pos += 4;
2885 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002886 hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID);
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
2888 pos += 2;
2889 break;
2890 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
2891 pos += 4;
2892 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002893 hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002894 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
2895 pos += 2;
2896 break;
2897 case HDD_WPS_ELEM_RSP_TYPE:
2898 pos += 4;
2899 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002900 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002901 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT;
2902 pos += 1;
2903 break;
2904 case HDD_WPS_ELEM_UUID_E:
2905 pos += 2;
2906 length = *pos<<8 | *(pos+1);
2907 pos += 2;
2908 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length);
2909 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT;
2910 pos += length;
2911 break;
2912
2913 case HDD_WPS_ELEM_MANUFACTURER:
2914 pos += 2;
2915 length = *pos<<8 | *(pos+1);
2916 pos += 2;
2917 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length;
2918 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length);
2919 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT;
2920 pos += length;
2921 break;
2922
2923 case HDD_WPS_ELEM_MODEL_NAME:
2924 pos += 2;
2925 length = *pos<<8 | *(pos+1);
2926 pos += 2;
2927 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length;
2928 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length);
2929 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT;
2930 pos += length;
2931 break;
2932 case HDD_WPS_ELEM_MODEL_NUM:
2933 pos += 2;
2934 length = *pos<<8 | *(pos+1);
2935 pos += 2;
2936 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length;
2937 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length);
2938 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT;
2939 pos += length;
2940 break;
2941 case HDD_WPS_ELEM_SERIAL_NUM:
2942 pos += 2;
2943 length = *pos<<8 | *(pos+1);
2944 pos += 2;
2945 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length;
2946 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length);
2947 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT;
2948 pos += length;
2949 break;
2950 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
2951 pos += 4;
2952 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002953 hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002954 pos += 2;
2955
2956 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002957 hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002958 pos += 4;
2959 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002960 hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory);
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 pos += 2;
2962 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
2963 break;
2964 case HDD_WPS_ELEM_DEVICE_NAME:
2965 pos += 2;
2966 length = *pos<<8 | *(pos+1);
2967 pos += 2;
2968 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length;
2969 vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length);
2970 pos += length;
2971 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT;
2972 break;
2973 case HDD_WPS_ELEM_CONFIG_METHODS:
2974 pos += 4;
2975 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1);
Arif Hussain6d2a3322013-11-17 19:50:10 -08002976 hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod);
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 pos += 2;
2978 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT;
2979 break;
2980
2981 case HDD_WPS_ELEM_RF_BANDS:
2982 pos += 4;
2983 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos;
Arif Hussain6d2a3322013-11-17 19:50:10 -08002984 hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand);
Jeff Johnson295189b2012-06-20 16:38:30 -07002985 pos += 1;
2986 pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT;
2987 break;
2988 } // switch
2989 }
2990 }
2991 else
2992 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002993 hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002994 }
2995
2996 } // switch
2997 }
2998 halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe);
2999 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3000 if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE)
3001 {
3002 //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3003 //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext;
3004 WLANSAP_Update_WpsIe ( pVosContext );
3005 }
3006
3007 vos_mem_free(pSap_WPSIe);
Arif Hussained667642013-10-27 23:01:14 -07003008 kfree(fwps_genie);
Jeff Johnson295189b2012-06-20 16:38:30 -07003009 EXIT();
3010 return halStatus;
3011}
3012
3013static int iw_softap_stopbss(struct net_device *dev,
3014 struct iw_request_info *info,
3015 union iwreq_data *wrqu,
3016 char *extra)
3017{
3018 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3019 VOS_STATUS status = VOS_STATUS_SUCCESS;
Agarwal Ashish51325b52014-06-16 16:50:49 +05303020 hdd_context_t *pHddCtx = NULL;
3021
Jeff Johnson295189b2012-06-20 16:38:30 -07003022 ENTER();
Agarwal Ashish51325b52014-06-16 16:50:49 +05303023
3024 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3025 status = wlan_hdd_validate_context(pHddCtx);
3026
3027 if (0 != status) {
3028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
3029 return status;
3030 }
3031
Jeff Johnson295189b2012-06-20 16:38:30 -07003032 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3033 {
3034 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
3035 {
3036 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
3037
3038 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
3039
3040 if (!VOS_IS_STATUS_SUCCESS(status))
3041 {
3042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003043 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003044 VOS_ASSERT(0);
3045 }
3046 }
3047 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05303048 wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003049 }
3050 EXIT();
3051 return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
3052}
3053
3054static int iw_softap_version(struct net_device *dev,
3055 struct iw_request_info *info,
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003056 union iwreq_data *wrqu,
Jeff Johnson295189b2012-06-20 16:38:30 -07003057 char *extra)
3058{
Jeff Johnson295189b2012-06-20 16:38:30 -07003059 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003060
Jeff Johnson295189b2012-06-20 16:38:30 -07003061 ENTER();
Jeff Johnson4824d4c2013-02-12 14:23:57 -08003062 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
Jeff Johnson295189b2012-06-20 16:38:30 -07003063 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003064 return 0;
3065}
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003066
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003067VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003068{
3069 v_U8_t i;
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003070 int len = 0;
3071 const char sta_info_header[] = "staId staAddress\n";
3072
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003073 len = scnprintf(pBuf, buf_len, sta_info_header);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003074 pBuf += len;
3075 buf_len -= len;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003076
3077 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
3078 {
3079 if(pAdapter->aStaInfo[i].isUsed)
3080 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08003081 len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n",
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003082 pAdapter->aStaInfo[i].ucSTAId,
3083 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
3084 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
3085 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
3086 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
3087 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
3088 pAdapter->aStaInfo[i].macAddrSTA.bytes[5]);
Yathish Hanumapuradoddi Shivanna7b659402013-03-25 14:12:32 -07003089 pBuf += len;
3090 buf_len -= len;
3091 }
3092 if(WE_GET_STA_INFO_SIZE > buf_len)
3093 {
3094 break;
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003095 }
3096 }
3097 return VOS_STATUS_SUCCESS;
3098}
3099
3100static int iw_softap_get_sta_info(struct net_device *dev,
3101 struct iw_request_info *info,
3102 union iwreq_data *wrqu,
3103 char *extra)
3104{
3105 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3106 VOS_STATUS status;
3107 ENTER();
Yathish Hanumapuradoddi Shivanna4171f7d2013-04-08 20:05:56 -07003108 status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003109 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003111 return -EINVAL;
3112 }
3113 wrqu->data.length = strlen(extra);
3114 EXIT();
3115 return 0;
3116}
3117
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303118static int __iw_set_ap_genie(struct net_device *dev,
3119 struct iw_request_info *info,
3120 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -07003121{
3122
3123 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3124 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
3125 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
Arif Hussained667642013-10-27 23:01:14 -07003126 u_int8_t *genie = (u_int8_t *)extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07003127
3128 ENTER();
3129
3130 if(!wrqu->data.length)
3131 {
3132 EXIT();
3133 return 0;
3134 }
Arif Hussained667642013-10-27 23:01:14 -07003135
Jeff Johnson295189b2012-06-20 16:38:30 -07003136 switch (genie[0])
3137 {
3138 case DOT11F_EID_WPA:
3139 case DOT11F_EID_RSN:
3140 if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
3141 {
3142 hdd_softap_Deregister_BC_STA(pHostapdAdapter);
3143 hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
3144 }
3145 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Arif Hussained667642013-10-27 23:01:14 -07003146 halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 break;
3148
3149 default:
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003150 hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07003151 halStatus = 0;
3152 }
3153
3154 EXIT();
3155 return halStatus;
3156}
3157
Mahesh A Saptasagarf176a862014-08-20 21:25:21 +05303158static int iw_set_ap_genie(struct net_device *dev,
3159 struct iw_request_info *info,
3160 union iwreq_data *wrqu, char *extra)
3161{
3162 int ret;
3163
3164 vos_ssr_protect(__func__);
3165 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
3166 vos_ssr_unprotect(__func__);
3167
3168 return ret;
3169}
3170
Jeff Johnson295189b2012-06-20 16:38:30 -07003171static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid)
3172{
3173 eHalStatus hstatus;
3174 long lrc;
3175 struct statsContext context;
3176
3177 if (NULL == pAdapter)
3178 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05303179 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180 return VOS_STATUS_E_FAULT;
3181 }
3182
3183 init_completion(&context.completion);
3184 context.pAdapter = pAdapter;
3185 context.magic = STATS_CONTEXT_MAGIC;
3186 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
3187 eCSR_HDD,
3188 SME_GLOBAL_CLASSA_STATS,
3189 hdd_GetClassA_statisticsCB,
3190 0, // not periodic
3191 FALSE, //non-cached results
3192 staid,
3193 &context);
3194 if (eHAL_STATUS_SUCCESS != hstatus)
3195 {
3196 hddLog(VOS_TRACE_LEVEL_ERROR,
3197 "%s: Unable to retrieve statistics for link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003198 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 }
3200 else
3201 {
3202 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3203 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Jeff Johnson295189b2012-06-20 16:38:30 -07003204 if (lrc <= 0)
3205 {
3206 hddLog(VOS_TRACE_LEVEL_ERROR,
3207 "%s: SME %s while retrieving link speed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003208 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07003209 }
3210 }
Jeff Johnson72a40512013-12-19 10:14:15 -08003211
3212 /* either we never sent a request, we sent a request and received a
3213 response or we sent a request and timed out. if we never sent a
3214 request or if we sent a request and got a response, we want to
3215 clear the magic out of paranoia. if we timed out there is a
3216 race condition such that the callback function could be
3217 executing at the same time we are. of primary concern is if the
3218 callback function had already verified the "magic" but had not
3219 yet set the completion variable when a timeout occurred. we
3220 serialize these activities by invalidating the magic while
3221 holding a shared spinlock which will cause us to block if the
3222 callback is currently executing */
3223 spin_lock(&hdd_context_lock);
3224 context.magic = 0;
3225 spin_unlock(&hdd_context_lock);
3226
Jeff Johnson295189b2012-06-20 16:38:30 -07003227 return VOS_STATUS_SUCCESS;
3228}
3229
3230int iw_get_softap_linkspeed(struct net_device *dev,
3231 struct iw_request_info *info,
3232 union iwreq_data *wrqu,
3233 char *extra)
3234
3235{
3236 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303237 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003238 char *pLinkSpeed = (char*)extra;
Arif Hussained667642013-10-27 23:01:14 -07003239 char *pmacAddress;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303240 v_U32_t link_speed;
Jeff Johnson295189b2012-06-20 16:38:30 -07003241 unsigned short staId;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303242 int len = sizeof(v_U32_t)+1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003243 v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE];
Arif Hussaina9571842014-01-15 16:43:41 -08003244 VOS_STATUS status = VOS_STATUS_E_FAILURE;
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303245 int rc, valid;
3246
3247 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3248
3249 valid = wlan_hdd_validate_context(pHddCtx);
3250
3251 if (0 != valid)
3252 {
3253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid"));
3254 return valid;
3255 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003256
Arif Hussain6d2a3322013-11-17 19:50:10 -08003257 hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length);
Arif Hussaina9571842014-01-15 16:43:41 -08003258
3259 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
Arif Hussained667642013-10-27 23:01:14 -07003260 {
Arif Hussaina9571842014-01-15 16:43:41 -08003261 pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
3262 if (NULL == pmacAddress) {
3263 hddLog(LOG1, "unable to allocate memory");
3264 return -ENOMEM;
3265 }
3266 if (copy_from_user((void *)pmacAddress,
3267 wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
3268 {
3269 hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
3270 kfree(pmacAddress);
3271 return -EFAULT;
3272 }
3273 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
3274
3275 status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
Arif Hussained667642013-10-27 23:01:14 -07003276 kfree(pmacAddress);
Arif Hussaina9571842014-01-15 16:43:41 -08003277
3278 if (!VOS_IS_STATUS_SUCCESS(status ))
3279 {
3280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
3281 }
Arif Hussained667642013-10-27 23:01:14 -07003282 }
Kiet Lam61589852013-09-19 17:10:58 +05303283 /* If no mac address is passed and/or its length is less than 17,
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303284 * link speed for first connected client will be returned.
3285 */
Arif Hussaina9571842014-01-15 16:43:41 -08003286 if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status ))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05303287 {
3288 status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId));
3289 }
3290 else
3291 {
3292 status = hdd_softap_GetStaId(pHostapdAdapter,
3293 (v_MACADDR_t *)macAddress, (void *)(&staId));
3294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003295
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303296 if (!VOS_IS_STATUS_SUCCESS(status))
Jeff Johnson295189b2012-06-20 16:38:30 -07003297 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003299 link_speed = 0;
3300 }
3301 else
3302 {
3303 status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303304
Jeff Johnson295189b2012-06-20 16:38:30 -07003305 if (!VOS_IS_STATUS_SUCCESS(status ))
3306 {
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003308 return -EINVAL;
3309 }
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303310
3311 WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext,
3312 staId, &link_speed);
3313
3314 link_speed = link_speed / 10;
3315
3316 if (0 == link_speed)
3317 {
3318 /* The linkspeed returned by HAL is in units of 500kbps.
3319 * converting it to mbps.
3320 * This is required to support legacy firmware which does
3321 * not return link capacity.
3322 */
3323 link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2;
3324 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003325 }
3326
3327 wrqu->data.length = len;
Jeff Johnson02797792013-10-26 19:17:13 -07003328 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303329
Jeff Johnson295189b2012-06-20 16:38:30 -07003330 if ((rc < 0) || (rc >= len))
3331 {
3332 // encoding or length error?
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303333 hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 return -EIO;
3335 }
3336
3337 return 0;
3338}
3339
3340static const iw_handler hostapd_handler[] =
3341{
3342 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3343 (iw_handler) NULL, /* SIOCGIWNAME */
3344 (iw_handler) NULL, /* SIOCSIWNWID */
3345 (iw_handler) NULL, /* SIOCGIWNWID */
3346 (iw_handler) NULL, /* SIOCSIWFREQ */
3347 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
3348 (iw_handler) NULL, /* SIOCSIWMODE */
Madan Mohan Koyyalamudi0c2ba1b2013-10-01 19:47:50 +05303349 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
Jeff Johnson295189b2012-06-20 16:38:30 -07003350 (iw_handler) NULL, /* SIOCSIWSENS */
3351 (iw_handler) NULL, /* SIOCGIWSENS */
3352 (iw_handler) NULL, /* SIOCSIWRANGE */
3353 (iw_handler) NULL, /* SIOCGIWRANGE */
3354 (iw_handler) NULL, /* SIOCSIWPRIV */
3355 (iw_handler) NULL, /* SIOCGIWPRIV */
3356 (iw_handler) NULL, /* SIOCSIWSTATS */
3357 (iw_handler) NULL, /* SIOCGIWSTATS */
3358 (iw_handler) NULL, /* SIOCSIWSPY */
3359 (iw_handler) NULL, /* SIOCGIWSPY */
3360 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3361 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3362 (iw_handler) NULL, /* SIOCSIWAP */
3363 (iw_handler) NULL, /* SIOCGIWAP */
3364 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
3365 (iw_handler) NULL, /* SIOCGIWAPLIST */
3366 (iw_handler) NULL, /* SIOCSIWSCAN */
3367 (iw_handler) NULL, /* SIOCGIWSCAN */
3368 (iw_handler) NULL, /* SIOCSIWESSID */
3369 (iw_handler) NULL, /* SIOCGIWESSID */
3370 (iw_handler) NULL, /* SIOCSIWNICKN */
3371 (iw_handler) NULL, /* SIOCGIWNICKN */
3372 (iw_handler) NULL, /* -- hole -- */
3373 (iw_handler) NULL, /* -- hole -- */
3374 (iw_handler) NULL, /* SIOCSIWRATE */
3375 (iw_handler) NULL, /* SIOCGIWRATE */
3376 (iw_handler) NULL, /* SIOCSIWRTS */
3377 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
3378 (iw_handler) NULL, /* SIOCSIWFRAG */
3379 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
3380 (iw_handler) NULL, /* SIOCSIWTXPOW */
3381 (iw_handler) NULL, /* SIOCGIWTXPOW */
3382 (iw_handler) NULL, /* SIOCSIWRETRY */
3383 (iw_handler) NULL, /* SIOCGIWRETRY */
3384 (iw_handler) NULL, /* SIOCSIWENCODE */
3385 (iw_handler) NULL, /* SIOCGIWENCODE */
3386 (iw_handler) NULL, /* SIOCSIWPOWER */
3387 (iw_handler) NULL, /* SIOCGIWPOWER */
3388 (iw_handler) NULL, /* -- hole -- */
3389 (iw_handler) NULL, /* -- hole -- */
3390 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
3391 (iw_handler) NULL, /* SIOCGIWGENIE */
3392 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
3393 (iw_handler) NULL, /* SIOCGIWAUTH */
3394 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
3395 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
3396 (iw_handler) NULL, /* SIOCSIWPMKSA */
3397};
3398
Jeff Johnson224f3702014-03-26 11:09:47 -07003399/*
3400 * Note that the following ioctls were defined with semantics which
3401 * cannot be handled by the "iwpriv" userspace application and hence
3402 * they are not included in the hostapd_private_args array
3403 * QCSAP_IOCTL_ASSOC_STA_MACADDR
3404 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003405
3406static const struct iw_priv_args hostapd_private_args[] = {
3407 { QCSAP_IOCTL_SETPARAM,
3408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
3409 { QCSAP_IOCTL_SETPARAM,
3410 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
3411 { QCSAP_PARAM_MAX_ASSOC,
3412 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
3413 { QCSAP_PARAM_HIDE_SSID,
3414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
Leo Chang614d2072013-08-22 14:59:44 -07003415 { QCSAP_PARAM_SET_MC_RATE,
3416 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 { QCSAP_IOCTL_GETPARAM,
3418 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3419 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" },
3420 { QCSAP_IOCTL_GETPARAM, 0,
3421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
3422 { QCSAP_PARAM_MAX_ASSOC, 0,
3423 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" },
Jeff Johnson43971f52012-07-17 12:26:56 -07003424 { QCSAP_PARAM_GET_WLAN_DBG, 0,
3425 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" },
3426 { QCSAP_PARAM_AUTO_CHANNEL, 0,
3427 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" },
Ravi Shankar Upadrastabb216bb2014-06-13 14:40:24 +05303428 { QCSAP_PARAM_SET_AUTO_CHANNEL,
3429 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003430 { QCSAP_PARAM_CLR_ACL, 0,
3431 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" },
3432 { QCSAP_PARAM_ACL_MODE,
3433 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003434 { QCSAP_IOCTL_GET_STAWPAIE,
3435 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" },
3436 { QCSAP_IOCTL_SETWPAIE,
3437 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" },
3438 { QCSAP_IOCTL_STOPBSS,
3439 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
3440 { QCSAP_IOCTL_VERSION, 0,
3441 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" },
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003442 { QCSAP_IOCTL_GET_STA_INFO, 0,
3443 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003444 { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
Arif Hussaind443e332013-11-18 23:59:44 -08003445 IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003446 { QCSAP_IOCTL_GET_CHANNEL, 0,
Jeff Johnson43971f52012-07-17 12:26:56 -07003447 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
Jeff Johnson224f3702014-03-26 11:09:47 -07003448 { QCSAP_IOCTL_DISASSOC_STA,
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
Girish Gowlif3769802014-06-16 21:17:16 +05303450 { QCSAP_IOCTL_AP_STATS, 0,
3451 IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003452 { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3453 IW_PRIV_TYPE_CHAR | 18,
Gopichand Nakkala8a2b1442013-05-29 15:33:14 +05303454 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003455
3456 { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3457 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
3458 /* handlers for sub-ioctl */
3459 { WE_SET_WLAN_DBG,
3460 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3461 0,
3462 "setwlandbg" },
3463
3464 /* handlers for main ioctl */
3465 { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3466 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3467 0,
3468 "" },
3469
3470 /* handlers for sub-ioctl */
3471 { WE_LOG_DUMP_CMD,
3472 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3473 0,
3474 "dump" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003475 { WE_P2P_NOA_CMD,
3476 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3477 0,
3478 "SetP2pPs" },
Madan Mohan Koyyalamudid5f04ca2012-11-06 15:51:26 -08003479 /* handlers for sub ioctl */
3480 {
3481 WE_MCC_CONFIG_CREDENTIAL,
3482 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3483 0,
3484 "setMccCrdnl" },
3485
3486 /* handlers for sub ioctl */
3487 {
3488 WE_MCC_CONFIG_PARAMS,
3489 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3490 0,
3491 "setMccConfig" },
3492
Jeff Johnson295189b2012-06-20 16:38:30 -07003493 /* handlers for main ioctl */
3494 { QCSAP_IOCTL_MODIFY_ACL,
3495 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
3496 0,
3497 "modify_acl" },
3498
3499 /* handlers for main ioctl */
3500 { QCSAP_IOCTL_GET_CHANNEL_LIST,
3501 0,
3502 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
3503 "getChannelList" },
3504
Jeff Johnsone7245742012-09-05 17:12:55 -07003505 /* handlers for main ioctl */
3506 { QCSAP_IOCTL_SET_TX_POWER,
3507 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3508 0,
Madan Mohan Koyyalamudid12bf052012-11-27 19:07:55 +05303509 "setTxPower" },
schang86c22c42013-03-13 18:41:24 -07003510
3511 /* handlers for main ioctl */
3512 { QCSAP_IOCTL_SET_MAX_TX_POWER,
3513 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3514 0,
3515 "setTxMaxPower" },
Kiet Lambcf38522013-10-26 18:28:27 +05303516
3517 { QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
3518 IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
3519 0,
3520 "dataSnapshot" },
3521
3522 /* handlers for main ioctl */
3523 { QCSAP_IOCTL_SET_TRAFFIC_MONITOR,
3524 IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
3525 0,
3526 "setTrafficMon" },
Jeff Johnson295189b2012-06-20 16:38:30 -07003527};
Jeff Johnsone7245742012-09-05 17:12:55 -07003528
Jeff Johnson295189b2012-06-20 16:38:30 -07003529static const iw_handler hostapd_private[] = {
3530 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl
3531 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl
Jeff Johnson295189b2012-06-20 16:38:30 -07003532 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
3533 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
3534 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss
3535 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version
3536 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
3537 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
3538 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
3539 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
3540 [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
3541 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
3542 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
3543 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range,
3544 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl,
3545 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list,
Gopichand Nakkala976e3252013-01-03 15:45:56 -08003546 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
Jeff Johnsone7245742012-09-05 17:12:55 -07003547 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed,
3548 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power,
schang86c22c42013-03-13 18:41:24 -07003549 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power,
Madan Mohan Koyyalamudia96f5442013-05-10 11:32:06 +05303550 [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot,
Kiet Lambcf38522013-10-26 18:28:27 +05303551 [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor,
Jeff Johnson295189b2012-06-20 16:38:30 -07003552};
3553const struct iw_handler_def hostapd_handler_def = {
3554 .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
3555 .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
3556 .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
3557 .standard = (iw_handler *)hostapd_handler,
3558 .private = (iw_handler *)hostapd_private,
3559 .private_args = hostapd_private_args,
3560 .get_wireless_stats = NULL,
3561};
3562#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3563struct net_device_ops net_ops_struct = {
3564 .ndo_open = hdd_hostapd_open,
3565 .ndo_stop = hdd_hostapd_stop,
3566 .ndo_uninit = hdd_hostapd_uninit,
3567 .ndo_start_xmit = hdd_softap_hard_start_xmit,
3568 .ndo_tx_timeout = hdd_softap_tx_timeout,
3569 .ndo_get_stats = hdd_softap_stats,
3570 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
3571 .ndo_do_ioctl = hdd_hostapd_ioctl,
3572 .ndo_change_mtu = hdd_hostapd_change_mtu,
3573 .ndo_select_queue = hdd_hostapd_select_queue,
3574 };
3575#endif
3576
3577int hdd_set_hostapd(hdd_adapter_t *pAdapter)
3578{
3579 return VOS_STATUS_SUCCESS;
3580}
3581
3582void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
3583{
3584#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3585 pWlanHostapdDev->netdev_ops = &net_ops_struct;
3586#else
3587 pWlanHostapdDev->open = hdd_hostapd_open;
3588 pWlanHostapdDev->stop = hdd_hostapd_stop;
3589 pWlanHostapdDev->uninit = hdd_hostapd_uninit;
3590 pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit;
3591 pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout;
3592 pWlanHostapdDev->get_stats = hdd_softap_stats;
3593 pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address;
3594 pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl;
3595#endif
3596}
3597
3598VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
3599{
3600 hdd_hostapd_state_t * phostapdBuf;
3601 struct net_device *dev = pAdapter->dev;
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003602 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003603 VOS_STATUS status;
Leo Chang0b0e45a2013-12-15 15:18:55 -08003604#ifdef FEATURE_WLAN_CH_AVOID
Leo Chang0b0e45a2013-12-15 15:18:55 -08003605 v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS];
3606 v_U16_t unsafeChannelCount;
3607#endif /* FEATURE_WLAN_CH_AVOID */
3608
Jeff Johnson295189b2012-06-20 16:38:30 -07003609 ENTER();
3610 // Allocate the Wireless Extensions state structure
3611 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
3612
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003613 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
3614
Leo Chang0b0e45a2013-12-15 15:18:55 -08003615#ifdef FEATURE_WLAN_CH_AVOID
3616 /* Get unsafe cahnnel list from cached location */
3617 wcnss_get_wlan_unsafe_channel(unsafeChannelList,
3618 sizeof(unsafeChannelList),
3619 &unsafeChannelCount);
3620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3621 "%s : Unsafe Channel count %d",
3622 __func__, unsafeChannelCount);
Sushant Kaushik389e7f02014-06-11 19:56:10 +05303623 hdd_hostapd_update_unsafe_channel_list(pHddCtx,
Leo Chang0b0e45a2013-12-15 15:18:55 -08003624 unsafeChannelList,
3625 unsafeChannelCount);
3626#endif /* FEATURE_WLAN_CH_AVOID */
3627
Jeff Johnson295189b2012-06-20 16:38:30 -07003628 // Zero the memory. This zeros the profile structure.
3629 memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));
3630
3631 // Set up the pointer to the Wireless Extensions state structure
3632 // NOP
3633 status = hdd_set_hostapd(pAdapter);
3634 if(!VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003636 return status;
3637 }
3638
3639 status = vos_event_init(&phostapdBuf->vosEvent);
3640 if (!VOS_IS_STATUS_SUCCESS(status))
3641 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08003642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003643 return status;
3644 }
3645
3646 init_completion(&pAdapter->session_close_comp_var);
3647 init_completion(&pAdapter->session_open_comp_var);
3648
3649 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
3650
3651 // Register as a wireless device
3652 dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
3653
3654 //Initialize the data path module
3655 status = hdd_softap_init_tx_rx(pAdapter);
3656 if ( !VOS_IS_STATUS_SUCCESS( status ))
3657 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003658 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 }
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303660
3661 status = hdd_wmm_adapter_init( pAdapter );
3662 if (!VOS_IS_STATUS_SUCCESS(status))
3663 {
3664 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003665 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303666 status, status );
3667 goto error_wmm_init;
3668 }
3669
3670 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3671
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter );
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303673
3674 return status;
3675
3676error_wmm_init:
3677 hdd_softap_deinit_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003678 EXIT();
3679 return status;
3680}
3681
3682hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name )
3683{
3684 struct net_device *pWlanHostapdDev = NULL;
3685 hdd_adapter_t *pHostapdAdapter = NULL;
3686 v_CONTEXT_t pVosContext= NULL;
3687
Jeff Johnson295189b2012-06-20 16:38:30 -07003688 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07003689
3690 if (pWlanHostapdDev != NULL)
3691 {
3692 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
3693
3694 //Init the net_device structure
3695 ether_setup(pWlanHostapdDev);
3696
3697 //Initialize the adapter context to zeros.
3698 vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
3699 pHostapdAdapter->dev = pWlanHostapdDev;
3700 pHostapdAdapter->pHddCtx = pHddCtx;
3701 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3702
3703 //Get the Global VOSS context.
3704 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3705 //Save the adapter context in global context for future.
3706 ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter;
3707
3708 //Init the net_device structure
3709 strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);
3710
3711 hdd_set_ap_ops( pHostapdAdapter->dev );
3712
Jeff Johnson295189b2012-06-20 16:38:30 -07003713 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
3714 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
3715
3716 vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
3717 vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));
3718
3719 pWlanHostapdDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003720 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
3721 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
3722 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
3723 init_completion(&pHostapdAdapter->tx_action_cnf_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
3725 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
Mahesh A Saptasagar60de76d2014-04-25 18:37:08 +05303726 init_completion(&pHostapdAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07003727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3728 init_completion(&pHostapdAdapter->offchannel_tx_event);
3729#endif
3730
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
3732 }
3733 return pHostapdAdapter;
3734}
3735
3736VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3737{
3738 struct net_device *dev = pAdapter->dev;
3739 VOS_STATUS status = VOS_STATUS_SUCCESS;
3740
3741 ENTER();
3742
3743 if( rtnl_lock_held )
3744 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003745 if (strnchr(dev->name, strlen(dev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003746 if( dev_alloc_name(dev, dev->name) < 0 )
3747 {
3748 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
3749 return VOS_STATUS_E_FAILURE;
3750 }
3751 }
3752 if (register_netdevice(dev))
3753 {
3754 hddLog(VOS_TRACE_LEVEL_FATAL,
3755 "%s:Failed:register_netdevice", __func__);
3756 return VOS_STATUS_E_FAILURE;
3757 }
3758 }
3759 else
3760 {
3761 if (register_netdev(dev))
3762 {
3763 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
3764 return VOS_STATUS_E_FAILURE;
3765 }
3766 }
3767 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3768
3769 EXIT();
3770 return status;
3771}
3772
3773VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter)
3774{
3775 ENTER();
3776
3777 hdd_softap_deinit_tx_rx(pAdapter);
3778
3779 /* if we are being called during driver unload, then the dev has already
3780 been invalidated. if we are being called at other times, then we can
3781 detatch the wireless device handlers */
3782 if (pAdapter->dev)
3783 {
3784 pAdapter->dev->wireless_handlers = NULL;
3785 }
3786 EXIT();
3787 return 0;
3788}