blob: 2332ac717c6cf35018799d6e095947616a3c5a0f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, 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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*========================================================================
43
44 \file wlan_hdd_main.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 04/5/09 Shailender Created module.
69 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
70 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
71 ==========================================================================*/
72
73/*--------------------------------------------------------------------------
74 Include Files
75 ------------------------------------------------------------------------*/
76//#include <wlan_qct_driver.h>
77#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070078#include <vos_api.h>
79#include <vos_sched.h>
80#include <vos_power.h>
81#include <linux/etherdevice.h>
82#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#ifdef ANI_BUS_TYPE_PLATFORM
84#include <linux/wcnss_wlan.h>
85#endif //ANI_BUS_TYPE_PLATFORM
86#ifdef ANI_BUS_TYPE_PCI
87#include "wcnss_wlan.h"
88#endif /* ANI_BUS_TYPE_PCI */
89#include <wlan_hdd_tx_rx.h>
90#include <palTimer.h>
91#include <wniApi.h>
92#include <wlan_nlink_srv.h>
93#include <wlan_btc_svc.h>
94#include <wlan_hdd_cfg.h>
95#include <wlan_ptt_sock_svc.h>
96#include <wlan_hdd_wowl.h>
97#include <wlan_hdd_misc.h>
98#include <wlan_hdd_wext.h>
99#ifdef WLAN_BTAMP_FEATURE
100#include <bap_hdd_main.h>
101#include <bapInternal.h>
102#endif // WLAN_BTAMP_FEATURE
103
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include <linux/wireless.h>
105#include <net/cfg80211.h>
106#include "wlan_hdd_cfg80211.h"
107#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700109int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "sapApi.h"
111#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700112#include <linux/ctype.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include <mach/subsystem_restart.h>
114#include <wlan_hdd_hostapd.h>
115#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700117#include "wlan_hdd_dev_pwr.h"
118#ifdef WLAN_BTAMP_FEATURE
119#include "bap_hdd_misc.h"
120#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700121#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700122#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800123#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530124#ifdef FEATURE_WLAN_TDLS
125#include "wlan_hdd_tdls.h"
126#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700127#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129#ifdef MODULE
130#define WLAN_MODULE_NAME module_name(THIS_MODULE)
131#else
132#define WLAN_MODULE_NAME "wlan"
133#endif
134
135#ifdef TIMER_MANAGER
136#define TIMER_MANAGER_STR " +TIMER_MANAGER"
137#else
138#define TIMER_MANAGER_STR ""
139#endif
140
141#ifdef MEMORY_DEBUG
142#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
143#else
144#define MEMORY_DEBUG_STR ""
145#endif
146
147/* the Android framework expects this param even though we don't use it */
148#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700149static char fwpath_buffer[BUF_LEN];
150static struct kparam_string fwpath = {
151 .string = fwpath_buffer,
152 .maxlen = BUF_LEN,
153};
Arif Hussain66559122013-11-21 10:11:40 -0800154
155static char *country_code;
156static int enable_11d = -1;
157static int enable_dfs_chan_scan = -1;
158
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700159#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700160static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700161#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700162
Jeff Johnsone7245742012-09-05 17:12:55 -0700163/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800164 * spinlock for synchronizing asynchronous request/response
165 * (full description of use in wlan_hdd_main.h)
166 */
167DEFINE_SPINLOCK(hdd_context_lock);
168
169/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700170 * The rate at which the driver sends RESTART event to supplicant
171 * once the function 'vos_wlanRestart()' is called
172 *
173 */
174#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
175#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700176
177/*
178 * Size of Driver command strings from upper layer
179 */
180#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
181#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
182
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700183#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
184#define TID_MIN_VALUE 0
185#define TID_MAX_VALUE 15
186static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
187 tAniTrafStrmMetrics* pTsmMetrics);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -0800188static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
189 tCsrCcxBeaconReq *pCcxBcnReq);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
191
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700192/*
193 * Driver miracast parameters 0-Disabled
194 * 1-Source, 2-Sink
195 */
196#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
197#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
198
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800199#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700200static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700202/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700203static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700204
205//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700206static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
207static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
208static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
209void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800210void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212v_U16_t hdd_select_queue(struct net_device *dev,
213 struct sk_buff *skb);
214
215#ifdef WLAN_FEATURE_PACKET_FILTERING
216static void hdd_set_multicast_list(struct net_device *dev);
217#endif
218
219void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
Amar Singhal4c723bd2013-03-25 18:14:15 -0700220int isWDresetInProgress(void);
Jeff Johnson295189b2012-06-20 16:38:30 -0700221
222extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Amar Singhal0a402232013-10-11 20:57:16 -0700223
Srinivas Girigowdade697412013-02-14 16:31:48 -0800224#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
225void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
226static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700227static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
228 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
229 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700230static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
231 tANI_U8 *pTargetApBssid,
232 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800233#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
235VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
236#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
237
Jeff Johnson295189b2012-06-20 16:38:30 -0700238static int hdd_netdev_notifier_call(struct notifier_block * nb,
239 unsigned long state,
240 void *ndev)
241{
242 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700243 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700244 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700245#ifdef WLAN_BTAMP_FEATURE
246 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700247#endif
248
249 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700250 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700251 (strncmp(dev->name, "p2p", 3)))
252 return NOTIFY_DONE;
253
254 if (isWDresetInProgress())
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 return NOTIFY_DONE;
256
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700258 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700259
Jeff Johnson27cee452013-03-27 11:10:24 -0700260 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800262 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 VOS_ASSERT(0);
264 return NOTIFY_DONE;
265 }
266
Jeff Johnson27cee452013-03-27 11:10:24 -0700267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
268 if (NULL == pHddCtx)
269 {
270 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
271 VOS_ASSERT(0);
272 return NOTIFY_DONE;
273 }
274
275 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
276 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278 switch (state) {
279 case NETDEV_REGISTER:
280 break;
281
282 case NETDEV_UNREGISTER:
283 break;
284
285 case NETDEV_UP:
286 break;
287
288 case NETDEV_DOWN:
289 break;
290
291 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700292 if(TRUE == pAdapter->isLinkUpSvcNeeded)
293 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 break;
295
296 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700297 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 {
299 int result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800300 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +0530301 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800303 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
305 if(!result)
306 {
307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson902c9832012-12-10 14:28:09 -0800308 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700309 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 }
311 }
312 else
313 {
314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700315 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 }
317#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 status = WLANBAP_StopAmp();
320 if(VOS_STATUS_SUCCESS != status )
321 {
322 pHddCtx->isAmpAllowed = VOS_TRUE;
323 hddLog(VOS_TRACE_LEVEL_FATAL,
324 "%s: Failed to stop AMP", __func__);
325 }
326 else
327 {
328 //a state m/c implementation in PAL is TBD to avoid this delay
329 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700330 if ( pHddCtx->isAmpAllowed )
331 {
332 WLANBAP_DeregisterFromHCI();
333 pHddCtx->isAmpAllowed = VOS_FALSE;
334 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 }
336#endif //WLAN_BTAMP_FEATURE
337 break;
338
339 default:
340 break;
341 }
342
343 return NOTIFY_DONE;
344}
345
346struct notifier_block hdd_netdev_notifier = {
347 .notifier_call = hdd_netdev_notifier_call,
348};
349
350/*---------------------------------------------------------------------------
351 * Function definitions
352 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700353void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
354void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700355//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700356static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700357#ifndef MODULE
358/* current con_mode - used only for statically linked driver
359 * con_mode is changed by userspace to indicate a mode change which will
360 * result in calling the module exit and init functions. The module
361 * exit function will clean up based on the value of con_mode prior to it
362 * being changed by userspace. So curr_con_mode records the current con_mode
363 * for exit when con_mode becomes the next mode for init
364 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700365static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700366#endif
367
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800368/**---------------------------------------------------------------------------
369
370 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
371
372 Called immediately after the cfg.ini is read in order to configure
373 the desired trace levels.
374
375 \param - moduleId - module whose trace level is being configured
376 \param - bitmask - bitmask of log levels to be enabled
377
378 \return - void
379
380 --------------------------------------------------------------------------*/
381static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
382{
383 wpt_tracelevel level;
384
385 /* if the bitmask is the default value, then a bitmask was not
386 specified in cfg.ini, so leave the logging level alone (it
387 will remain at the "compiled in" default value) */
388 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
389 {
390 return;
391 }
392
393 /* a mask was specified. start by disabling all logging */
394 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
395
396 /* now cycle through the bitmask until all "set" bits are serviced */
397 level = VOS_TRACE_LEVEL_FATAL;
398 while (0 != bitmask)
399 {
400 if (bitmask & 1)
401 {
402 vos_trace_setValue(moduleId, level, 1);
403 }
404 level++;
405 bitmask >>= 1;
406 }
407}
408
409
Jeff Johnson295189b2012-06-20 16:38:30 -0700410/**---------------------------------------------------------------------------
411
412 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
413
414 Called immediately after the cfg.ini is read in order to configure
415 the desired trace levels in the WDI.
416
417 \param - moduleId - module whose trace level is being configured
418 \param - bitmask - bitmask of log levels to be enabled
419
420 \return - void
421
422 --------------------------------------------------------------------------*/
423static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
424{
425 wpt_tracelevel level;
426
427 /* if the bitmask is the default value, then a bitmask was not
428 specified in cfg.ini, so leave the logging level alone (it
429 will remain at the "compiled in" default value) */
430 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
431 {
432 return;
433 }
434
435 /* a mask was specified. start by disabling all logging */
436 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
437
438 /* now cycle through the bitmask until all "set" bits are serviced */
439 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
440 while (0 != bitmask)
441 {
442 if (bitmask & 1)
443 {
444 wpalTraceSetLevel(moduleId, level, 1);
445 }
446 level++;
447 bitmask >>= 1;
448 }
449}
Jeff Johnson295189b2012-06-20 16:38:30 -0700450
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530451/*
452 * FUNCTION: wlan_hdd_validate_context
453 * This function is used to check the HDD context
454 */
455int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
456{
457 ENTER();
458
459 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
460 {
461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
462 "%s: HDD context is Null", __func__);
463 return -ENODEV;
464 }
465
466 if (pHddCtx->isLogpInProgress)
467 {
468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
469 "%s: LOGP in Progress. Ignore!!!", __func__);
470 return -EAGAIN;
471 }
472
473 if (pHddCtx->isLoadUnloadInProgress)
474 {
475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
476 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
477 return -EAGAIN;
478 }
479 return 0;
480}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700481#ifdef CONFIG_ENABLE_LINUX_REG
482void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
483{
484 hdd_adapter_t *pAdapter = NULL;
485 hdd_station_ctx_t *pHddStaCtx = NULL;
486 eCsrPhyMode phyMode;
487 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530488
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700489 if (NULL == pHddCtx)
490 {
491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
492 "HDD Context is null !!");
493 return ;
494 }
495
496 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
497 if (NULL == pAdapter)
498 {
499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
500 "pAdapter is null !!");
501 return ;
502 }
503
504 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
505 if (NULL == pHddStaCtx)
506 {
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
508 "pHddStaCtx is null !!");
509 return ;
510 }
511
512 cfg_param = pHddCtx->cfg_ini;
513 if (NULL == cfg_param)
514 {
515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
516 "cfg_params not available !!");
517 return ;
518 }
519
520 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
521
522 if (!pHddCtx->isVHT80Allowed)
523 {
524 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
525 (eCSR_DOT11_MODE_11ac == phyMode) ||
526 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
527 {
528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
529 "Setting phymode to 11n!!");
530 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
531 }
532 }
533 else
534 {
535 /*New country Supports 11ac as well resetting value back from .ini*/
536 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
537 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
538 return ;
539 }
540
541 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
542 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
543 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
544 {
545 VOS_STATUS vosStatus;
546
547 // need to issue a disconnect to CSR.
548 INIT_COMPLETION(pAdapter->disconnect_comp_var);
549 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
550 pAdapter->sessionId,
551 eCSR_DISCONNECT_REASON_UNSPECIFIED );
552
553 if (VOS_STATUS_SUCCESS == vosStatus)
554 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
555 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
556
557 }
558}
559#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530560void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
561{
562 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
563 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
564 hdd_config_t *cfg_param;
565 eCsrPhyMode phyMode;
566
567 if (NULL == pHddCtx)
568 {
569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
570 "HDD Context is null !!");
571 return ;
572 }
573
574 cfg_param = pHddCtx->cfg_ini;
575
576 if (NULL == cfg_param)
577 {
578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
579 "cfg_params not available !!");
580 return ;
581 }
582
583 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
584
585 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
586 {
587 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
588 (eCSR_DOT11_MODE_11ac == phyMode) ||
589 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
592 "Setting phymode to 11n!!");
593 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
594 }
595 }
596 else
597 {
598 /*New country Supports 11ac as well resetting value back from .ini*/
599 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
600 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
601 return ;
602 }
603
604 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
605 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
606 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
607 {
608 VOS_STATUS vosStatus;
609
610 // need to issue a disconnect to CSR.
611 INIT_COMPLETION(pAdapter->disconnect_comp_var);
612 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
613 pAdapter->sessionId,
614 eCSR_DISCONNECT_REASON_UNSPECIFIED );
615
616 if (VOS_STATUS_SUCCESS == vosStatus)
617 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
618 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
619
620 }
621}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700622#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530623
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700624void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
625{
626 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
627 hdd_config_t *cfg_param;
628
629 if (NULL == pHddCtx)
630 {
631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
632 "HDD Context is null !!");
633 return ;
634 }
635
636 cfg_param = pHddCtx->cfg_ini;
637
638 if (NULL == cfg_param)
639 {
640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
641 "cfg_params not available !!");
642 return ;
643 }
644
645 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
646 {
647 /*New country doesn't support DFS */
648 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
649 }
650 else
651 {
652 /*New country Supports DFS as well resetting value back from .ini*/
653 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
654 }
655
656}
657
Rajeev79dbe4c2013-10-05 11:03:42 +0530658#ifdef FEATURE_WLAN_BATCH_SCAN
659
660/**---------------------------------------------------------------------------
661
662 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
663 input string
664
665 This function extracts assigned integer from string in below format:
666 "STRING=10" : extracts integer 10 from this string
667
668 \param - pInPtr Pointer to input string
669 \param - base Base for string to int conversion(10 for decimal 16 for hex)
670 \param - pOutPtr Pointer to variable in which extracted integer needs to be
671 assigned
672 \param - pLastArg to tell whether it is last arguement in input string or
673 not
674
675 \return - NULL for failure cases
676 pointer to next arguement in input string for success cases
677 --------------------------------------------------------------------------*/
678static tANI_U8 *
679hdd_extract_assigned_int_from_str
680(
681 tANI_U8 *pInPtr,
682 tANI_U8 base,
683 tANI_U32 *pOutPtr,
684 tANI_U8 *pLastArg
685)
686{
687 int tempInt;
688 int v = 0;
689 char buf[32];
690 int val = 0;
691 *pLastArg = FALSE;
692
693 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
694 if (NULL == pInPtr)
695 {
696 return NULL;
697 }
698
699 pInPtr++;
700
701 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
702
703 val = sscanf(pInPtr, "%32s ", buf);
704 if (val < 0 && val > strlen(pInPtr))
705 {
706 return NULL;
707 }
708 pInPtr += val;
709 v = kstrtos32(buf, base, &tempInt);
710 if (v < 0)
711 {
712 return NULL;
713 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800714 if (tempInt < 0)
715 {
716 tempInt = 0;
717 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530718 *pOutPtr = tempInt;
719
720 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
721 if (NULL == pInPtr)
722 {
723 *pLastArg = TRUE;
724 return NULL;
725 }
726 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
727
728 return pInPtr;
729}
730
731/**---------------------------------------------------------------------------
732
733 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
734 input string
735
736 This function extracts assigned character from string in below format:
737 "STRING=A" : extracts char 'A' from this string
738
739 \param - pInPtr Pointer to input string
740 \param - pOutPtr Pointer to variable in which extracted char needs to be
741 assigned
742 \param - pLastArg to tell whether it is last arguement in input string or
743 not
744
745 \return - NULL for failure cases
746 pointer to next arguement in input string for success cases
747 --------------------------------------------------------------------------*/
748static tANI_U8 *
749hdd_extract_assigned_char_from_str
750(
751 tANI_U8 *pInPtr,
752 tANI_U8 *pOutPtr,
753 tANI_U8 *pLastArg
754)
755{
756 *pLastArg = FALSE;
757
758 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
759 if (NULL == pInPtr)
760 {
761 return NULL;
762 }
763
764 pInPtr++;
765
766 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
767
768 *pOutPtr = *pInPtr;
769
770 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
771 if (NULL == pInPtr)
772 {
773 *pLastArg = TRUE;
774 return NULL;
775 }
776 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
777
778 return pInPtr;
779}
780
781
782/**---------------------------------------------------------------------------
783
784 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
785
786 This function parses set batch scan command in below format:
787 WLS_BATCHING_SET <space> followed by below arguements
788 "SCANFREQ=XX" : Optional defaults to 30 sec
789 "MSCAN=XX" : Required number of scans to attempt to batch
790 "BESTN=XX" : Best Network (RSSI) defaults to 16
791 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
792 A. implies only 5 GHz , B. implies only 2.4GHz
793 "RTT=X" : optional defaults to 0
794 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
795 error
796
797 For example input commands:
798 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
799 translated into set batch scan with following parameters:
800 a) Frequence 60 seconds
801 b) Batch 10 scans together
802 c) Best RSSI to be 20
803 d) 5GHz band only
804 e) RTT is equal to 0
805
806 \param - pValue Pointer to input channel list
807 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
808
809 \return - 0 for success non-zero for failure
810
811 --------------------------------------------------------------------------*/
812static int
813hdd_parse_set_batchscan_command
814(
815 tANI_U8 *pValue,
816 tSirSetBatchScanReq *pHddSetBatchScanReq
817)
818{
819 tANI_U8 *inPtr = pValue;
820 tANI_U8 val = 0;
821 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800822 tANI_U32 nScanFreq;
823 tANI_U32 nMscan;
824 tANI_U32 nBestN;
825 tANI_U8 ucRfBand;
826 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800827 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530828
829 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800830 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
831 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
832 nRtt = 0;
833 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530834
835 /*go to space after WLS_BATCHING_SET command*/
836 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
837 /*no argument after the command*/
838 if (NULL == inPtr)
839 {
840 return -EINVAL;
841 }
842
843 /*no space after the command*/
844 else if (SPACE_ASCII_VALUE != *inPtr)
845 {
846 return -EINVAL;
847 }
848
849 /*removing empty spaces*/
850 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
851
852 /*no argument followed by spaces*/
853 if ('\0' == *inPtr)
854 {
855 return -EINVAL;
856 }
857
858 /*check and parse SCANFREQ*/
859 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
860 {
861 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800862 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800863
Rajeev Kumarc933d982013-11-18 20:04:20 -0800864 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800865 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800866 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800867 }
868
Rajeev79dbe4c2013-10-05 11:03:42 +0530869 if ( (NULL == inPtr) || (TRUE == lastArg))
870 {
871 return -EINVAL;
872 }
873 }
874
875 /*check and parse MSCAN*/
876 if ((strncmp(inPtr, "MSCAN", 5) == 0))
877 {
878 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800879 &nMscan, &lastArg);
880
881 if (0 == nMscan)
882 {
883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
884 "invalid MSCAN=%d", nMscan);
885 return -EINVAL;
886 }
887
Rajeev79dbe4c2013-10-05 11:03:42 +0530888 if (TRUE == lastArg)
889 {
890 goto done;
891 }
892 else if (NULL == inPtr)
893 {
894 return -EINVAL;
895 }
896 }
897 else
898 {
899 return -EINVAL;
900 }
901
902 /*check and parse BESTN*/
903 if ((strncmp(inPtr, "BESTN", 5) == 0))
904 {
905 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800906 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800907
Rajeev Kumarc933d982013-11-18 20:04:20 -0800908 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800909 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800910 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800911 }
912
Rajeev79dbe4c2013-10-05 11:03:42 +0530913 if (TRUE == lastArg)
914 {
915 goto done;
916 }
917 else if (NULL == inPtr)
918 {
919 return -EINVAL;
920 }
921 }
922
923 /*check and parse CHANNEL*/
924 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
925 {
926 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800927
Rajeev79dbe4c2013-10-05 11:03:42 +0530928 if (('A' == val) || ('a' == val))
929 {
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800930 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530931 }
932 else if (('B' == val) || ('b' == val))
933 {
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530935 }
936 else
937 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800938 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
939 }
940
941 if (TRUE == lastArg)
942 {
943 goto done;
944 }
945 else if (NULL == inPtr)
946 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530947 return -EINVAL;
948 }
949 }
950
951 /*check and parse RTT*/
952 if ((strncmp(inPtr, "RTT", 3) == 0))
953 {
954 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800955 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530956 if (TRUE == lastArg)
957 {
958 goto done;
959 }
960 if (NULL == inPtr)
961 {
962 return -EINVAL;
963 }
964 }
965
966
967done:
968
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800969 pHddSetBatchScanReq->scanFrequency = nScanFreq;
970 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
971 pHddSetBatchScanReq->bestNetwork = nBestN;
972 pHddSetBatchScanReq->rfBand = ucRfBand;
973 pHddSetBatchScanReq->rtt = nRtt;
974
Rajeev79dbe4c2013-10-05 11:03:42 +0530975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
976 "Received WLS_BATCHING_SET with SCANFREQ=%d "
977 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
978 pHddSetBatchScanReq->scanFrequency,
979 pHddSetBatchScanReq->numberOfScansToBatch,
980 pHddSetBatchScanReq->bestNetwork,
981 pHddSetBatchScanReq->rfBand,
982 pHddSetBatchScanReq->rtt);
983
984 return 0;
985}/*End of hdd_parse_set_batchscan_command*/
986
987/**---------------------------------------------------------------------------
988
989 \brief hdd_set_batch_scan_req_callback () - This function is called after
990 receiving set batch scan response from FW and it saves set batch scan
991 response data FW to HDD context and sets the completion event on
992 which hdd_ioctl is waiting
993
994 \param - callbackContext Pointer to HDD adapter
995 \param - pRsp Pointer to set batch scan response data received from FW
996
997 \return - nothing
998
999 --------------------------------------------------------------------------*/
1000static void hdd_set_batch_scan_req_callback
1001(
1002 void *callbackContext,
1003 tSirSetBatchScanRsp *pRsp
1004)
1005{
1006 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1007 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1008
1009 /*sanity check*/
1010 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1011 {
1012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1013 "%s: Invalid pAdapter magic", __func__);
1014 VOS_ASSERT(0);
1015 return;
1016 }
1017 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1018
1019 /*save set batch scan response*/
1020 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1021
1022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1023 "Received set batch scan rsp from FW with nScansToBatch=%d",
1024 pHddSetBatchScanRsp->nScansToBatch);
1025
1026 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1027 complete(&pAdapter->hdd_set_batch_scan_req_var);
1028
1029 return;
1030}/*End of hdd_set_batch_scan_req_callback*/
1031
1032
1033/**---------------------------------------------------------------------------
1034
1035 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1036 info in hdd batch scan response queue
1037
1038 \param - pAdapter Pointer to hdd adapter
1039 \param - pAPMetaInfo Pointer to access point meta info
1040 \param - scanId scan ID of batch scan response
1041 \param - isLastAp tells whether AP is last AP in batch scan response or not
1042
1043 \return - nothing
1044
1045 --------------------------------------------------------------------------*/
1046static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1047 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1048{
1049 tHddBatchScanRsp *pHead;
1050 tHddBatchScanRsp *pNode;
1051 tHddBatchScanRsp *pPrev;
1052 tHddBatchScanRsp *pTemp;
1053 tANI_U8 ssidLen;
1054
1055 /*head of hdd batch scan response queue*/
1056 pHead = pAdapter->pBatchScanRsp;
1057
1058 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1059 if (NULL == pNode)
1060 {
1061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1062 "%s: Could not allocate memory", __func__);
1063 VOS_ASSERT(0);
1064 return;
1065 }
1066
1067 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1068 sizeof(pNode->ApInfo.bssid));
1069 ssidLen = strlen(pApMetaInfo->ssid);
1070 if (SIR_MAX_SSID_SIZE < ssidLen)
1071 {
1072 /*invalid scan result*/
1073 vos_mem_free(pNode);
1074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1075 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1076 return;
1077 }
1078 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1079 /*null terminate ssid*/
1080 pNode->ApInfo.ssid[ssidLen] = '\0';
1081 pNode->ApInfo.ch = pApMetaInfo->ch;
1082 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1083 pNode->ApInfo.age = pApMetaInfo->timestamp;
1084 pNode->ApInfo.batchId = scanId;
1085 pNode->ApInfo.isLastAp = isLastAp;
1086
1087 pNode->pNext = NULL;
1088 if (NULL == pHead)
1089 {
1090 pAdapter->pBatchScanRsp = pNode;
1091 }
1092 else
1093 {
1094 pTemp = pHead;
1095 while (NULL != pTemp)
1096 {
1097 pPrev = pTemp;
1098 pTemp = pTemp->pNext;
1099 }
1100 pPrev->pNext = pNode;
1101 }
1102
1103 return;
1104}/*End of hdd_populate_batch_scan_rsp_queue*/
1105
1106/**---------------------------------------------------------------------------
1107
1108 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1109 receiving batch scan response indication from FW. It saves get batch scan
1110 response data in HDD batch scan response queue. This callback sets the
1111 completion event on which hdd_ioctl is waiting only after getting complete
1112 batch scan response data from FW
1113
1114 \param - callbackContext Pointer to HDD adapter
1115 \param - pRsp Pointer to get batch scan response data received from FW
1116
1117 \return - nothing
1118
1119 --------------------------------------------------------------------------*/
1120static void hdd_batch_scan_result_ind_callback
1121(
1122 void *callbackContext,
1123 void *pRsp
1124)
1125{
1126 v_BOOL_t isLastAp;
1127 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001128 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301129 tANI_U32 numberScanList;
1130 tANI_U32 nextScanListOffset;
1131 tANI_U32 nextApMetaInfoOffset;
1132 hdd_adapter_t* pAdapter;
1133 tpSirBatchScanList pScanList;
1134 tpSirBatchScanNetworkInfo pApMetaInfo;
1135 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1136 tSirSetBatchScanReq *pReq;
1137
1138 pAdapter = (hdd_adapter_t *)callbackContext;
1139 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001140 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301141 {
1142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1143 "%s: Invalid pAdapter magic", __func__);
1144 VOS_ASSERT(0);
1145 return;
1146 }
1147
1148 /*initialize locals*/
1149 pReq = &pAdapter->hddSetBatchScanReq;
1150 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1151 isLastAp = FALSE;
1152 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001153 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301154 numberScanList = 0;
1155 nextScanListOffset = 0;
1156 nextApMetaInfoOffset = 0;
1157 pScanList = NULL;
1158 pApMetaInfo = NULL;
1159
1160 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1161 {
1162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1163 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1164 isLastAp = TRUE;
1165 goto done;
1166 }
1167
1168 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1170 "Batch scan rsp: numberScalList %d", numberScanList);
1171
1172 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1173 {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1175 "%s: numberScanList %d", __func__, numberScanList);
1176 isLastAp = TRUE;
1177 goto done;
1178 }
1179
1180 while (numberScanList)
1181 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001182 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301183 nextScanListOffset);
1184 if (NULL == pScanList)
1185 {
1186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1187 "%s: pScanList is %p", __func__, pScanList);
1188 isLastAp = TRUE;
1189 goto done;
1190 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001191 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001193 "Batch scan rsp: numApMetaInfo %d scanId %d",
1194 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301195
1196 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1197 {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1199 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1200 isLastAp = TRUE;
1201 goto done;
1202 }
1203
Rajeev Kumarce651e42013-10-21 18:57:15 -07001204 /*Initialize next AP meta info offset for next scan list*/
1205 nextApMetaInfoOffset = 0;
1206
Rajeev79dbe4c2013-10-05 11:03:42 +05301207 while (numApMetaInfo)
1208 {
1209 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1210 nextApMetaInfoOffset);
1211 if (NULL == pApMetaInfo)
1212 {
1213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1214 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1215 isLastAp = TRUE;
1216 goto done;
1217 }
1218 /*calculate AP age*/
1219 pApMetaInfo->timestamp =
1220 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1221
1222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001223 "%s: bssId "MAC_ADDRESS_STR
1224 " ch %d rssi %d timestamp %d", __func__,
1225 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1226 pApMetaInfo->ch, pApMetaInfo->rssi,
1227 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301228
1229 /*mark last AP in batch scan response*/
1230 if ((TRUE == pBatchScanRsp->isLastResult) &&
1231 (1 == numberScanList) && (1 == numApMetaInfo))
1232 {
1233 isLastAp = TRUE;
1234 }
1235
1236 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1237 /*store batch scan repsonse in hdd queue*/
1238 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1239 pScanList->scanId, isLastAp);
1240 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1241
1242 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1243 numApMetaInfo--;
1244 }
1245
Rajeev Kumarce651e42013-10-21 18:57:15 -07001246 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1247 + (sizeof(tSirBatchScanNetworkInfo)
1248 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301249 numberScanList--;
1250 }
1251
1252done:
1253
1254 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1255 requested from hdd_ioctl*/
1256 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1257 (TRUE == isLastAp))
1258 {
1259 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1260 complete(&pAdapter->hdd_get_batch_scan_req_var);
1261 }
1262
1263 return;
1264}/*End of hdd_batch_scan_result_ind_callback*/
1265
1266/**---------------------------------------------------------------------------
1267
1268 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1269 response as per batch scan FR request format by putting proper markers
1270
1271 \param - pDest pointer to destination buffer
1272 \param - cur_len current length
1273 \param - tot_len total remaining size which can be written to user space
1274 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1275 \param - pAdapter Pointer to HDD adapter
1276
1277 \return - ret no of characters written
1278
1279 --------------------------------------------------------------------------*/
1280static tANI_U32
1281hdd_format_batch_scan_rsp
1282(
1283 tANI_U8 *pDest,
1284 tANI_U32 cur_len,
1285 tANI_U32 tot_len,
1286 tHddBatchScanRsp *pApMetaInfo,
1287 hdd_adapter_t* pAdapter
1288)
1289{
1290 tANI_U32 ret = 0;
1291 tANI_U32 rem_len = 0;
1292 tANI_U8 temp_len = 0;
1293 tANI_U8 temp_total_len = 0;
1294 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1295 tANI_U8 *pTemp = temp;
1296
1297 /*Batch scan reponse needs to be returned to user space in
1298 following format:
1299 "scancount=X\n" where X is the number of scans in current batch
1300 batch
1301 "trunc\n" optional present if current scan truncated
1302 "bssid=XX:XX:XX:XX:XX:XX\n"
1303 "ssid=XXXX\n"
1304 "freq=X\n" frequency in Mhz
1305 "level=XX\n"
1306 "age=X\n" ms
1307 "dist=X\n" cm (-1 if not available)
1308 "errror=X\n" (-1if not available)
1309 "====\n" (end of ap marker)
1310 "####\n" (end of scan marker)
1311 "----\n" (end of results)*/
1312 /*send scan result in above format to user space based on
1313 available length*/
1314 /*The GET response may have more data than the driver can return in its
1315 buffer. In that case the buffer should be filled to the nearest complete
1316 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1317 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1318 The final buffer should end with "----\n"*/
1319
1320 /*sanity*/
1321 if (cur_len > tot_len)
1322 {
1323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1324 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1325 return 0;
1326 }
1327 else
1328 {
1329 rem_len = (tot_len - cur_len);
1330 }
1331
1332 /*end scan marker*/
1333 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1334 {
1335 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1336 pTemp += temp_len;
1337 temp_total_len += temp_len;
1338 }
1339
1340 /*bssid*/
1341 temp_len = snprintf(pTemp, sizeof(temp),
1342 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1343 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1344 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1345 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1346 pTemp += temp_len;
1347 temp_total_len += temp_len;
1348
1349 /*ssid*/
1350 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1351 pApMetaInfo->ApInfo.ssid);
1352 pTemp += temp_len;
1353 temp_total_len += temp_len;
1354
1355 /*freq*/
1356 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001357 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301358 pTemp += temp_len;
1359 temp_total_len += temp_len;
1360
1361 /*level*/
1362 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1363 pApMetaInfo->ApInfo.rssi);
1364 pTemp += temp_len;
1365 temp_total_len += temp_len;
1366
1367 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001368 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301369 pApMetaInfo->ApInfo.age);
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372
1373 /*dist*/
1374 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1375 pTemp += temp_len;
1376 temp_total_len += temp_len;
1377
1378 /*error*/
1379 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1380 pTemp += temp_len;
1381 temp_total_len += temp_len;
1382
1383 /*end AP marker*/
1384 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1385 pTemp += temp_len;
1386 temp_total_len += temp_len;
1387
1388 /*last AP in batch scan response*/
1389 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1390 {
1391 /*end scan marker*/
1392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1393 pTemp += temp_len;
1394 temp_total_len += temp_len;
1395
1396 /*end batch scan result marker*/
1397 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1398 pTemp += temp_len;
1399 temp_total_len += temp_len;
Rajeev Kumarb20d8c82013-11-18 20:04:20 -08001400
1401 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301402 }
1403
1404 if (temp_total_len < rem_len)
1405 {
1406 ret = temp_total_len + 1;
1407 strlcpy(pDest, temp, ret);
1408 pAdapter->isTruncated = FALSE;
1409 }
1410 else
1411 {
1412 pAdapter->isTruncated = TRUE;
1413 if (rem_len >= strlen("%%%%"))
1414 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001415 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301416 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001417 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301418 {
1419 ret = 0;
1420 }
1421 }
1422
1423 return ret;
1424
1425}/*End of hdd_format_batch_scan_rsp*/
1426
1427/**---------------------------------------------------------------------------
1428
1429 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1430 buffer starting with head of hdd batch scan response queue
1431
1432 \param - pAdapter Pointer to HDD adapter
1433 \param - pDest Pointer to user data buffer
1434 \param - cur_len current offset in user buffer
1435 \param - rem_len remaining no of bytes in user buffer
1436
1437 \return - number of bytes written in user buffer
1438
1439 --------------------------------------------------------------------------*/
1440
1441tANI_U32 hdd_populate_user_batch_scan_rsp
1442(
1443 hdd_adapter_t* pAdapter,
1444 tANI_U8 *pDest,
1445 tANI_U32 cur_len,
1446 tANI_U32 rem_len
1447)
1448{
1449 tHddBatchScanRsp *pHead;
1450 tHddBatchScanRsp *pPrev;
1451 tANI_U32 len;
1452
Rajeev79dbe4c2013-10-05 11:03:42 +05301453 pAdapter->isTruncated = FALSE;
1454
1455 /*head of hdd batch scan response queue*/
1456 pHead = pAdapter->pBatchScanRsp;
1457 while (pHead)
1458 {
1459 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1460 pAdapter);
1461 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001462 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301463 cur_len += len;
1464 if(TRUE == pAdapter->isTruncated)
1465 {
1466 /*result is truncated return rest of scan rsp in next req*/
1467 cur_len = rem_len;
1468 break;
1469 }
1470 pPrev = pHead;
1471 pHead = pHead->pNext;
1472 pAdapter->pBatchScanRsp = pHead;
1473 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1474 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001475 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301476 }
1477
1478 return cur_len;
1479}/*End of hdd_populate_user_batch_scan_rsp*/
1480
1481/**---------------------------------------------------------------------------
1482
1483 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1484 scan response data from HDD queue to user space
1485 It does following in detail:
1486 a) if HDD has enough data in its queue then it 1st copies data to user
1487 space and then send get batch scan indication message to FW. In this
1488 case it does not wait on any event and batch scan response data will
1489 be populated in HDD response queue in MC thread context after receiving
1490 indication from FW
1491 b) else send get batch scan indication message to FW and wait on an event
1492 which will be set once HDD receives complete batch scan response from
1493 FW and then this function returns batch scan response to user space
1494
1495 \param - pAdapter Pointer to HDD adapter
1496 \param - pPrivData Pointer to priv_data
1497
1498 \return - 0 for success -EFAULT for failure
1499
1500 --------------------------------------------------------------------------*/
1501
1502int hdd_return_batch_scan_rsp_to_user
1503(
1504 hdd_adapter_t* pAdapter,
1505 hdd_priv_data_t *pPrivData,
1506 tANI_U8 *command
1507)
1508{
1509 tANI_U8 *pDest;
1510 tANI_U32 count = 0;
1511 tANI_U32 len = 0;
1512 tANI_U32 cur_len = 0;
1513 tANI_U32 rem_len = 0;
1514 eHalStatus halStatus;
1515 unsigned long rc;
1516 tSirTriggerBatchScanResultInd *pReq;
1517
1518 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1519 pReq->param = 0;/*batch scan client*/
1520 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1521 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1522
1523 cur_len = pPrivData->used_len;
1524 if (pPrivData->total_len > pPrivData->used_len)
1525 {
1526 rem_len = pPrivData->total_len - pPrivData->used_len;
1527 }
1528 else
1529 {
1530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1531 "%s: Invalid user data buffer total_len %d used_len %d",
1532 __func__, pPrivData->total_len, pPrivData->used_len);
1533 return -EFAULT;
1534 }
1535
1536 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1537 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1538 cur_len, rem_len);
1539 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1540
1541 /*enough scan result available in cache to return to user space or
1542 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001543 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301544 {
1545 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1546 halStatus = sme_TriggerBatchScanResultInd(
1547 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1548 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1549 pAdapter);
1550 if ( eHAL_STATUS_SUCCESS == halStatus )
1551 {
1552 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1553 {
1554 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1555 rc = wait_for_completion_timeout(
1556 &pAdapter->hdd_get_batch_scan_req_var,
1557 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1558 if (0 == rc)
1559 {
1560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 "%s: Timeout waiting to fetch batch scan rsp from fw",
1562 __func__);
1563 return -EFAULT;
1564 }
1565 }
1566
1567 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001568 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301569 pDest += len;
1570 cur_len += len;
1571
1572 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1573 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1574 cur_len, rem_len);
1575 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1576
1577 count = 0;
1578 len = (len - pPrivData->used_len);
1579 pDest = (command + pPrivData->used_len);
1580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001581 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301582 while(count < len)
1583 {
1584 printk("%c", *(pDest + count));
1585 count++;
1586 }
1587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1588 "%s: copy %d data to user buffer", __func__, len);
1589 if (copy_to_user(pPrivData->buf, pDest, len))
1590 {
1591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1592 "%s: failed to copy data to user buffer", __func__);
1593 return -EFAULT;
1594 }
1595 }
1596 else
1597 {
1598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1599 "sme_GetBatchScanScan returned failure halStatus %d",
1600 halStatus);
1601 return -EINVAL;
1602 }
1603 }
1604 else
1605 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301606 count = 0;
1607 len = (len - pPrivData->used_len);
1608 pDest = (command + pPrivData->used_len);
1609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001610 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301611 while(count < len)
1612 {
1613 printk("%c", *(pDest + count));
1614 count++;
1615 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1617 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301618 if (copy_to_user(pPrivData->buf, pDest, len))
1619 {
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1621 "%s: failed to copy data to user buffer", __func__);
1622 return -EFAULT;
1623 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301624 }
1625
1626 return 0;
1627} /*End of hdd_return_batch_scan_rsp_to_user*/
1628
1629#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1630
Jeff Johnson295189b2012-06-20 16:38:30 -07001631int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1632{
1633 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1634 hdd_priv_data_t priv_data;
1635 tANI_U8 *command = NULL;
1636 int ret = 0;
1637
1638 if (NULL == pAdapter)
1639 {
1640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001641 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 ret = -ENODEV;
1643 goto exit;
1644 }
1645
Jeff Johnsone7245742012-09-05 17:12:55 -07001646 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 {
1648 ret = -EINVAL;
1649 goto exit;
1650 }
1651
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001652 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1653 {
1654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1655 "%s:LOGP in Progress. Ignore!!!", __func__);
1656 ret = -EBUSY;
1657 goto exit;
1658 }
1659
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
1661 {
1662 ret = -EFAULT;
1663 goto exit;
1664 }
1665
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001666 if (priv_data.total_len <= 0)
1667 {
1668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1669 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1670 priv_data.total_len);
1671 ret = -EINVAL;
1672 goto exit;
1673 }
1674
1675 /* Allocate +1 for '\0' */
1676 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 if (!command)
1678 {
1679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001680 "%s: failed to allocate memory\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001681 ret = -ENOMEM;
1682 goto exit;
1683 }
1684
1685 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1686 {
1687 ret = -EFAULT;
1688 goto exit;
1689 }
1690
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001691 /* Making sure the command is NUL-terminated */
1692 command[priv_data.total_len] = '\0';
1693
Jeff Johnson295189b2012-06-20 16:38:30 -07001694 if ((SIOCDEVPRIVATE + 1) == cmd)
1695 {
1696 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1697
1698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001699 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001700
1701 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1702 {
1703 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1704 sizeof(tSirMacAddr)))
1705 {
1706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001707 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001708 ret = -EFAULT;
1709 }
1710 }
Amar Singhal0974e402013-02-12 14:27:46 -08001711 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001712 {
Amar Singhal0974e402013-02-12 14:27:46 -08001713 tANI_U8 *ptr = command ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 int ret = 0 ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001715
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001717
1718 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07001719 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08001721 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001722 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001723 ret = hdd_setBand_helper(dev, ptr);
1724 }
Kiet Lamf040f472013-11-20 21:15:23 +05301725 else if(strncmp(command, "SETWMMPS", 8) == 0)
1726 {
1727 tANI_U8 *ptr = command;
1728 ret = hdd_wmmps_helper(pAdapter, ptr);
1729 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001730 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
1731 {
1732 char *country_code;
1733
1734 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001735
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001736 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001737 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07001738#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05301739 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07001740#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001741 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
1742 (void *)(tSmeChangeCountryCallback)
1743 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05301744 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001745 if (eHAL_STATUS_SUCCESS == ret)
1746 {
1747 ret = wait_for_completion_interruptible_timeout(
1748 &pAdapter->change_country_code,
1749 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
1750 if (0 >= ret)
1751 {
1752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out",
1753 __func__);
1754 }
1755 }
1756 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07001757 {
1758 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001759 "%s: SME Change Country code fail ret=%d", __func__, ret);
1760 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001761 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001762
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001763 }
1764 /*
1765 command should be a string having format
1766 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
1767 */
Amar Singhal0974e402013-02-12 14:27:46 -08001768 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001769 {
Amar Singhal0974e402013-02-12 14:27:46 -08001770 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001771
1772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001773 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07001774
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08001775 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001776 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001777 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
1778 {
1779 int suspend = 0;
1780 tANI_U8 *ptr = (tANI_U8*)command + 15;
1781
1782 suspend = *ptr - '0';
1783 hdd_set_wlan_suspend_mode(suspend);
1784 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08001785#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
1786 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
1787 {
1788 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001789 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001790 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
1791 eHalStatus status = eHAL_STATUS_SUCCESS;
1792
1793 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
1794 value = value + 15;
1795
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001796 /* Convert the value from ascii to integer */
1797 ret = kstrtos8(value, 10, &rssi);
1798 if (ret < 0)
1799 {
1800 /* If the input value is greater than max value of datatype, then also
1801 kstrtou8 fails */
1802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1803 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07001804 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001805 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
1806 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
1807 ret = -EINVAL;
1808 goto exit;
1809 }
1810
Srinivas Girigowdade697412013-02-14 16:31:48 -08001811 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001812
Srinivas Girigowdade697412013-02-14 16:31:48 -08001813 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
1814 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
1815 {
1816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1817 "Neighbor lookup threshold value %d is out of range"
1818 " (Min: %d Max: %d)", lookUpThreshold,
1819 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
1820 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
1821 ret = -EINVAL;
1822 goto exit;
1823 }
1824
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1826 "%s: Received Command to Set Roam trigger"
1827 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
1828
1829 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
1830 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
1831 if (eHAL_STATUS_SUCCESS != status)
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "%s: Failed to set roam trigger, try again", __func__);
1835 ret = -EPERM;
1836 goto exit;
1837 }
1838
1839 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
1840 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
1841 }
1842 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
1843 {
1844 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
1845 int rssi = (-1) * lookUpThreshold;
1846 char extra[32];
1847 tANI_U8 len = 0;
1848
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001849 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08001850 if (copy_to_user(priv_data.buf, &extra, len + 1))
1851 {
1852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1853 "%s: failed to copy data to user buffer", __func__);
1854 ret = -EFAULT;
1855 goto exit;
1856 }
1857 }
1858 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
1859 {
1860 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001861 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001862 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001863
Srinivas Girigowdade697412013-02-14 16:31:48 -08001864 /* input refresh period is in terms of seconds */
1865 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
1866 value = value + 18;
1867 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001868 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08001869 if (ret < 0)
1870 {
1871 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001872 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001874 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08001875 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07001876 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
1877 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08001878 ret = -EINVAL;
1879 goto exit;
1880 }
1881
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001882 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
1883 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08001884 {
1885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001886 "Roam scan period value %d is out of range"
1887 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07001888 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
1889 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08001890 ret = -EINVAL;
1891 goto exit;
1892 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001893 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001894
1895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1896 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001897 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08001898
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001899 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
1900 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08001901 }
1902 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
1903 {
1904 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
1905 char extra[32];
1906 tANI_U8 len = 0;
1907
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001908 len = scnprintf(extra, sizeof(extra), "%s %d",
1909 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08001910 /* Returned value is in units of seconds */
1911 if (copy_to_user(priv_data.buf, &extra, len + 1))
1912 {
1913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1914 "%s: failed to copy data to user buffer", __func__);
1915 ret = -EFAULT;
1916 goto exit;
1917 }
1918 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001919 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
1920 {
1921 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001922 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001923 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001924
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001925 /* input refresh period is in terms of seconds */
1926 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
1927 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001928
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001929 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001930 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001931 if (ret < 0)
1932 {
1933 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001934 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001936 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001937 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001938 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
1939 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
1940 ret = -EINVAL;
1941 goto exit;
1942 }
1943
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001944 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
1945 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
1946 {
1947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1948 "Neighbor scan results refresh period value %d is out of range"
1949 " (Min: %d Max: %d)", roamScanRefreshPeriod,
1950 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
1951 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
1952 ret = -EINVAL;
1953 goto exit;
1954 }
1955 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
1956
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1958 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001959 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001960
1961 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
1962 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
1963 }
1964 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
1965 {
1966 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
1967 char extra[32];
1968 tANI_U8 len = 0;
1969
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001970 len = scnprintf(extra, sizeof(extra), "%s %d",
1971 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001972 /* Returned value is in units of seconds */
1973 if (copy_to_user(priv_data.buf, &extra, len + 1))
1974 {
1975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1976 "%s: failed to copy data to user buffer", __func__);
1977 ret = -EFAULT;
1978 goto exit;
1979 }
1980 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07001981#ifdef FEATURE_WLAN_LFR
1982 /* SETROAMMODE */
1983 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
1984 {
1985 tANI_U8 *value = command;
1986 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
1987
1988 /* Move pointer to ahead of SETROAMMODE<delimiter> */
1989 value = value + SIZE_OF_SETROAMMODE + 1;
1990
1991 /* Convert the value from ascii to integer */
1992 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
1993 if (ret < 0)
1994 {
1995 /* If the input value is greater than max value of datatype, then also
1996 kstrtou8 fails */
1997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1998 "%s: kstrtou8 failed range [%d - %d]", __func__,
1999 CFG_LFR_FEATURE_ENABLED_MIN,
2000 CFG_LFR_FEATURE_ENABLED_MAX);
2001 ret = -EINVAL;
2002 goto exit;
2003 }
2004 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2005 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2006 {
2007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2008 "Roam Mode value %d is out of range"
2009 " (Min: %d Max: %d)", roamMode,
2010 CFG_LFR_FEATURE_ENABLED_MIN,
2011 CFG_LFR_FEATURE_ENABLED_MAX);
2012 ret = -EINVAL;
2013 goto exit;
2014 }
2015
2016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2017 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2018 /*
2019 * Note that
2020 * SETROAMMODE 0 is to enable LFR while
2021 * SETROAMMODE 1 is to disable LFR, but
2022 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2023 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2024 */
2025 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2026 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2027 else
2028 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2029
2030 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2031 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2032 }
2033 /* GETROAMMODE */
2034 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2035 {
2036 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2037 char extra[32];
2038 tANI_U8 len = 0;
2039
2040 /*
2041 * roamMode value shall be inverted because the sementics is different.
2042 */
2043 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2044 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2045 else
2046 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2047
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002048 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002049 if (copy_to_user(priv_data.buf, &extra, len + 1))
2050 {
2051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2052 "%s: failed to copy data to user buffer", __func__);
2053 ret = -EFAULT;
2054 goto exit;
2055 }
2056 }
2057#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002058#endif
2059#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2060 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2061 {
2062 tANI_U8 *value = command;
2063 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2064
2065 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2066 value = value + 13;
2067 /* Convert the value from ascii to integer */
2068 ret = kstrtou8(value, 10, &roamRssiDiff);
2069 if (ret < 0)
2070 {
2071 /* If the input value is greater than max value of datatype, then also
2072 kstrtou8 fails */
2073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2074 "%s: kstrtou8 failed range [%d - %d]", __func__,
2075 CFG_ROAM_RSSI_DIFF_MIN,
2076 CFG_ROAM_RSSI_DIFF_MAX);
2077 ret = -EINVAL;
2078 goto exit;
2079 }
2080
2081 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2082 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2083 {
2084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2085 "Roam rssi diff value %d is out of range"
2086 " (Min: %d Max: %d)", roamRssiDiff,
2087 CFG_ROAM_RSSI_DIFF_MIN,
2088 CFG_ROAM_RSSI_DIFF_MAX);
2089 ret = -EINVAL;
2090 goto exit;
2091 }
2092
2093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2094 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2095
2096 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2097 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2098 }
2099 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2100 {
2101 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2102 char extra[32];
2103 tANI_U8 len = 0;
2104
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002105 len = scnprintf(extra, sizeof(extra), "%s %d",
2106 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002107 if (copy_to_user(priv_data.buf, &extra, len + 1))
2108 {
2109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2110 "%s: failed to copy data to user buffer", __func__);
2111 ret = -EFAULT;
2112 goto exit;
2113 }
2114 }
2115#endif
2116#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2117 else if (strncmp(command, "GETBAND", 7) == 0)
2118 {
2119 int band = -1;
2120 char extra[32];
2121 tANI_U8 len = 0;
2122 hdd_getBand_helper(pHddCtx, &band);
2123
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002124 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002125 if (copy_to_user(priv_data.buf, &extra, len + 1))
2126 {
2127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2128 "%s: failed to copy data to user buffer", __func__);
2129 ret = -EFAULT;
2130 goto exit;
2131 }
2132 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002133 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2134 {
2135 tANI_U8 *value = command;
2136 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2137 tANI_U8 numChannels = 0;
2138 eHalStatus status = eHAL_STATUS_SUCCESS;
2139
2140 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2141 if (eHAL_STATUS_SUCCESS != status)
2142 {
2143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2144 "%s: Failed to parse channel list information", __func__);
2145 ret = -EINVAL;
2146 goto exit;
2147 }
2148
2149 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2150 {
2151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2152 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2153 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2154 ret = -EINVAL;
2155 goto exit;
2156 }
2157 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2158 numChannels);
2159 if (eHAL_STATUS_SUCCESS != status)
2160 {
2161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2162 "%s: Failed to update channel list information", __func__);
2163 ret = -EINVAL;
2164 goto exit;
2165 }
2166 }
2167 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2168 {
2169 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2170 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002171 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002172 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002173 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002174
2175 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2176 ChannelList, &numChannels ))
2177 {
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2179 "%s: failed to get roam scan channel list", __func__);
2180 ret = -EFAULT;
2181 goto exit;
2182 }
2183 /* output channel list is of the format
2184 [Number of roam scan channels][Channel1][Channel2]... */
2185 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002186 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002187 for (j = 0; (j < numChannels); j++)
2188 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002189 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2190 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002191 }
2192
2193 if (copy_to_user(priv_data.buf, &extra, len + 1))
2194 {
2195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2196 "%s: failed to copy data to user buffer", __func__);
2197 ret = -EFAULT;
2198 goto exit;
2199 }
2200 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002201 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2202 {
2203 tANI_BOOLEAN ccxMode = sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2204 char extra[32];
2205 tANI_U8 len = 0;
2206
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002207 /* Check if the features OKC/CCX/11R are supported simultaneously,
2208 then this operation is not permitted (return FAILURE) */
2209 if (ccxMode &&
2210 hdd_is_okc_mode_enabled(pHddCtx) &&
2211 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2212 {
2213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2214 "%s: OKC/CCX/11R are supported simultaneously"
2215 " hence this operation is not permitted!", __func__);
2216 ret = -EPERM;
2217 goto exit;
2218 }
2219
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002220 len = scnprintf(extra, sizeof(extra), "%s %d",
2221 "GETCCXMODE", ccxMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002222 if (copy_to_user(priv_data.buf, &extra, len + 1))
2223 {
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 "%s: failed to copy data to user buffer", __func__);
2226 ret = -EFAULT;
2227 goto exit;
2228 }
2229 }
2230 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2231 {
2232 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2233 char extra[32];
2234 tANI_U8 len = 0;
2235
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002236 /* Check if the features OKC/CCX/11R are supported simultaneously,
2237 then this operation is not permitted (return FAILURE) */
2238 if (okcMode &&
2239 sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
2240 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2241 {
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2243 "%s: OKC/CCX/11R are supported simultaneously"
2244 " hence this operation is not permitted!", __func__);
2245 ret = -EPERM;
2246 goto exit;
2247 }
2248
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002249 len = scnprintf(extra, sizeof(extra), "%s %d",
2250 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002251 if (copy_to_user(priv_data.buf, &extra, len + 1))
2252 {
2253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2254 "%s: failed to copy data to user buffer", __func__);
2255 ret = -EFAULT;
2256 goto exit;
2257 }
2258 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002259 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002260 {
2261 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2262 char extra[32];
2263 tANI_U8 len = 0;
2264
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002265 len = scnprintf(extra, sizeof(extra), "%s %d",
2266 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002267 if (copy_to_user(priv_data.buf, &extra, len + 1))
2268 {
2269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2270 "%s: failed to copy data to user buffer", __func__);
2271 ret = -EFAULT;
2272 goto exit;
2273 }
2274 }
2275 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2276 {
2277 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2278 char extra[32];
2279 tANI_U8 len = 0;
2280
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002281 len = scnprintf(extra, sizeof(extra), "%s %d",
2282 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002283 if (copy_to_user(priv_data.buf, &extra, len + 1))
2284 {
2285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2286 "%s: failed to copy data to user buffer", __func__);
2287 ret = -EFAULT;
2288 goto exit;
2289 }
2290 }
2291 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2292 {
2293 tANI_U8 *value = command;
2294 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2295
2296 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2297 value = value + 26;
2298 /* Convert the value from ascii to integer */
2299 ret = kstrtou8(value, 10, &minTime);
2300 if (ret < 0)
2301 {
2302 /* If the input value is greater than max value of datatype, then also
2303 kstrtou8 fails */
2304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2305 "%s: kstrtou8 failed range [%d - %d]", __func__,
2306 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2307 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2308 ret = -EINVAL;
2309 goto exit;
2310 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002311 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2312 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2313 {
2314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2315 "scan min channel time value %d is out of range"
2316 " (Min: %d Max: %d)", minTime,
2317 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2318 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2319 ret = -EINVAL;
2320 goto exit;
2321 }
2322
2323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2324 "%s: Received Command to change channel min time = %d", __func__, minTime);
2325
2326 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2327 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2328 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002329 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2330 {
2331 tANI_U8 *value = command;
2332 tANI_U8 channel = 0;
2333 tANI_U8 dwellTime = 0;
2334 tANI_U8 bufLen = 0;
2335 tANI_U8 *buf = NULL;
2336 tSirMacAddr targetApBssid;
2337 eHalStatus status = eHAL_STATUS_SUCCESS;
2338 struct ieee80211_channel chan;
2339 tANI_U8 finalLen = 0;
2340 tANI_U8 *finalBuf = NULL;
2341 tANI_U8 temp = 0;
2342 u64 cookie;
2343 hdd_station_ctx_t *pHddStaCtx = NULL;
2344 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2345
2346 /* if not associated, no need to send action frame */
2347 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2348 {
2349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2350 ret = -EINVAL;
2351 goto exit;
2352 }
2353
2354 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2355 &dwellTime, &buf, &bufLen);
2356 if (eHAL_STATUS_SUCCESS != status)
2357 {
2358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2359 "%s: Failed to parse send action frame data", __func__);
2360 ret = -EINVAL;
2361 goto exit;
2362 }
2363
2364 /* if the target bssid is different from currently associated AP,
2365 then no need to send action frame */
2366 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2367 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2368 {
2369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2370 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002371 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002372 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002373 goto exit;
2374 }
2375
2376 /* if the channel number is different from operating channel then
2377 no need to send action frame */
2378 if (channel != pHddStaCtx->conn_info.operationChannel)
2379 {
2380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2381 "%s: channel(%d) is different from operating channel(%d)",
2382 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2383 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002384 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002385 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002386 goto exit;
2387 }
2388 chan.center_freq = sme_ChnToFreq(channel);
2389
2390 finalLen = bufLen + 24;
2391 finalBuf = vos_mem_malloc(finalLen);
2392 if (NULL == finalBuf)
2393 {
2394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2395 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002396 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002397 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002398 goto exit;
2399 }
2400 vos_mem_zero(finalBuf, finalLen);
2401
2402 /* Fill subtype */
2403 temp = SIR_MAC_MGMT_ACTION << 4;
2404 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2405
2406 /* Fill type */
2407 temp = SIR_MAC_MGMT_FRAME;
2408 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2409
2410 /* Fill destination address (bssid of the AP) */
2411 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2412
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002413 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002414 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2415
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002416 /* Fill BSSID (AP mac address) */
2417 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002418
2419 /* Fill received buffer from 24th address */
2420 vos_mem_copy(finalBuf + 24, buf, bufLen);
2421
Jeff Johnson11c33152013-04-16 17:52:40 -07002422 /* done with the parsed buffer */
2423 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002424 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002425
Yue Maf49ba872013-08-19 12:04:25 -07002426 wlan_hdd_action( NULL,
2427#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2428 &(pAdapter->wdev),
2429#else
2430 dev,
2431#endif
2432 &chan, 0,
2433#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2434 NL80211_CHAN_HT20, 1,
2435#endif
2436 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002437 1, &cookie );
2438 vos_mem_free(finalBuf);
2439 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002440 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2441 {
2442 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2443 char extra[32];
2444 tANI_U8 len = 0;
2445
2446 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002447 len = scnprintf(extra, sizeof(extra), "%s %d",
2448 "GETROAMSCANCHANNELMINTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002449 if (copy_to_user(priv_data.buf, &extra, len + 1))
2450 {
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2452 "%s: failed to copy data to user buffer", __func__);
2453 ret = -EFAULT;
2454 goto exit;
2455 }
2456 }
2457 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2458 {
2459 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002460 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002461
2462 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2463 value = value + 19;
2464 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002465 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002466 if (ret < 0)
2467 {
2468 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002469 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002471 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002472 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2473 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2474 ret = -EINVAL;
2475 goto exit;
2476 }
2477
2478 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2479 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2480 {
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2482 "lfr mode value %d is out of range"
2483 " (Min: %d Max: %d)", maxTime,
2484 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2485 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2486 ret = -EINVAL;
2487 goto exit;
2488 }
2489
2490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2491 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2492
2493 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2494 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2495 }
2496 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2497 {
2498 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2499 char extra[32];
2500 tANI_U8 len = 0;
2501
2502 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002503 len = scnprintf(extra, sizeof(extra), "%s %d",
2504 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002505 if (copy_to_user(priv_data.buf, &extra, len + 1))
2506 {
2507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2508 "%s: failed to copy data to user buffer", __func__);
2509 ret = -EFAULT;
2510 goto exit;
2511 }
2512 }
2513 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2514 {
2515 tANI_U8 *value = command;
2516 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2517
2518 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2519 value = value + 16;
2520 /* Convert the value from ascii to integer */
2521 ret = kstrtou16(value, 10, &val);
2522 if (ret < 0)
2523 {
2524 /* If the input value is greater than max value of datatype, then also
2525 kstrtou16 fails */
2526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2527 "%s: kstrtou16 failed range [%d - %d]", __func__,
2528 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2529 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2530 ret = -EINVAL;
2531 goto exit;
2532 }
2533
2534 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2535 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2536 {
2537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2538 "scan home time value %d is out of range"
2539 " (Min: %d Max: %d)", val,
2540 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2541 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2542 ret = -EINVAL;
2543 goto exit;
2544 }
2545
2546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2547 "%s: Received Command to change scan home time = %d", __func__, val);
2548
2549 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2550 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2551 }
2552 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2553 {
2554 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2555 char extra[32];
2556 tANI_U8 len = 0;
2557
2558 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002559 len = scnprintf(extra, sizeof(extra), "%s %d",
2560 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002561 if (copy_to_user(priv_data.buf, &extra, len + 1))
2562 {
2563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2564 "%s: failed to copy data to user buffer", __func__);
2565 ret = -EFAULT;
2566 goto exit;
2567 }
2568 }
2569 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2570 {
2571 tANI_U8 *value = command;
2572 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2573
2574 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2575 value = value + 17;
2576 /* Convert the value from ascii to integer */
2577 ret = kstrtou8(value, 10, &val);
2578 if (ret < 0)
2579 {
2580 /* If the input value is greater than max value of datatype, then also
2581 kstrtou8 fails */
2582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2583 "%s: kstrtou8 failed range [%d - %d]", __func__,
2584 CFG_ROAM_INTRA_BAND_MIN,
2585 CFG_ROAM_INTRA_BAND_MAX);
2586 ret = -EINVAL;
2587 goto exit;
2588 }
2589
2590 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2591 (val > CFG_ROAM_INTRA_BAND_MAX))
2592 {
2593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2594 "intra band mode value %d is out of range"
2595 " (Min: %d Max: %d)", val,
2596 CFG_ROAM_INTRA_BAND_MIN,
2597 CFG_ROAM_INTRA_BAND_MAX);
2598 ret = -EINVAL;
2599 goto exit;
2600 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2602 "%s: Received Command to change intra band = %d", __func__, val);
2603
2604 pHddCtx->cfg_ini->nRoamIntraBand = val;
2605 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2606 }
2607 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2608 {
2609 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2610 char extra[32];
2611 tANI_U8 len = 0;
2612
2613 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002614 len = scnprintf(extra, sizeof(extra), "%s %d",
2615 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002616 if (copy_to_user(priv_data.buf, &extra, len + 1))
2617 {
2618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2619 "%s: failed to copy data to user buffer", __func__);
2620 ret = -EFAULT;
2621 goto exit;
2622 }
2623 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002624 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2625 {
2626 tANI_U8 *value = command;
2627 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2628
2629 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2630 value = value + 15;
2631 /* Convert the value from ascii to integer */
2632 ret = kstrtou8(value, 10, &nProbes);
2633 if (ret < 0)
2634 {
2635 /* If the input value is greater than max value of datatype, then also
2636 kstrtou8 fails */
2637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2638 "%s: kstrtou8 failed range [%d - %d]", __func__,
2639 CFG_ROAM_SCAN_N_PROBES_MIN,
2640 CFG_ROAM_SCAN_N_PROBES_MAX);
2641 ret = -EINVAL;
2642 goto exit;
2643 }
2644
2645 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2646 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2647 {
2648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2649 "NProbes value %d is out of range"
2650 " (Min: %d Max: %d)", nProbes,
2651 CFG_ROAM_SCAN_N_PROBES_MIN,
2652 CFG_ROAM_SCAN_N_PROBES_MAX);
2653 ret = -EINVAL;
2654 goto exit;
2655 }
2656
2657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2658 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2659
2660 pHddCtx->cfg_ini->nProbes = nProbes;
2661 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2662 }
2663 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2664 {
2665 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
2666 char extra[32];
2667 tANI_U8 len = 0;
2668
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002669 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002670 if (copy_to_user(priv_data.buf, &extra, len + 1))
2671 {
2672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2673 "%s: failed to copy data to user buffer", __func__);
2674 ret = -EFAULT;
2675 goto exit;
2676 }
2677 }
2678 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
2679 {
2680 tANI_U8 *value = command;
2681 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
2682
2683 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
2684 /* input value is in units of msec */
2685 value = value + 20;
2686 /* Convert the value from ascii to integer */
2687 ret = kstrtou16(value, 10, &homeAwayTime);
2688 if (ret < 0)
2689 {
2690 /* If the input value is greater than max value of datatype, then also
2691 kstrtou8 fails */
2692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2693 "%s: kstrtou8 failed range [%d - %d]", __func__,
2694 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2695 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2696 ret = -EINVAL;
2697 goto exit;
2698 }
2699
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002700 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
2701 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
2702 {
2703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2704 "homeAwayTime value %d is out of range"
2705 " (Min: %d Max: %d)", homeAwayTime,
2706 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2707 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2708 ret = -EINVAL;
2709 goto exit;
2710 }
2711
2712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2713 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07002714 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
2715 {
2716 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
2717 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
2718 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002719 }
2720 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
2721 {
2722 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
2723 char extra[32];
2724 tANI_U8 len = 0;
2725
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002726 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002727 if (copy_to_user(priv_data.buf, &extra, len + 1))
2728 {
2729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2730 "%s: failed to copy data to user buffer", __func__);
2731 ret = -EFAULT;
2732 goto exit;
2733 }
2734 }
2735 else if (strncmp(command, "REASSOC", 7) == 0)
2736 {
2737 tANI_U8 *value = command;
2738 tANI_U8 channel = 0;
2739 tSirMacAddr targetApBssid;
2740 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07002741#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
2742 tCsrHandoffRequest handoffInfo;
2743#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002744 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002745 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2746
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002747 /* if not associated, no need to proceed with reassoc */
2748 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2749 {
2750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2751 ret = -EINVAL;
2752 goto exit;
2753 }
2754
2755 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
2756 if (eHAL_STATUS_SUCCESS != status)
2757 {
2758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2759 "%s: Failed to parse reassoc command data", __func__);
2760 ret = -EINVAL;
2761 goto exit;
2762 }
2763
2764 /* if the target bssid is same as currently associated AP,
2765 then no need to proceed with reassoc */
2766 if (VOS_TRUE == vos_mem_compare(targetApBssid,
2767 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2768 {
2769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
2770 ret = -EINVAL;
2771 goto exit;
2772 }
2773
2774 /* Check channel number is a valid channel number */
2775 if(VOS_STATUS_SUCCESS !=
2776 wlan_hdd_validate_operation_channel(pAdapter, channel))
2777 {
2778 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002779 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002780 return -EINVAL;
2781 }
2782
2783 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07002784#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
2785 handoffInfo.channel = channel;
2786 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
2787 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2788#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002789 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07002790 else if (strncmp(command, "SETWESMODE", 10) == 0)
2791 {
2792 tANI_U8 *value = command;
2793 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
2794
2795 /* Move pointer to ahead of SETWESMODE<delimiter> */
2796 value = value + 11;
2797 /* Convert the value from ascii to integer */
2798 ret = kstrtou8(value, 10, &wesMode);
2799 if (ret < 0)
2800 {
2801 /* If the input value is greater than max value of datatype, then also
2802 kstrtou8 fails */
2803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2804 "%s: kstrtou8 failed range [%d - %d]", __func__,
2805 CFG_ENABLE_WES_MODE_NAME_MIN,
2806 CFG_ENABLE_WES_MODE_NAME_MAX);
2807 ret = -EINVAL;
2808 goto exit;
2809 }
2810
2811 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
2812 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
2813 {
2814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2815 "WES Mode value %d is out of range"
2816 " (Min: %d Max: %d)", wesMode,
2817 CFG_ENABLE_WES_MODE_NAME_MIN,
2818 CFG_ENABLE_WES_MODE_NAME_MAX);
2819 ret = -EINVAL;
2820 goto exit;
2821 }
2822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2823 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
2824
2825 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
2826 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
2827 }
2828 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
2829 {
2830 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
2831 char extra[32];
2832 tANI_U8 len = 0;
2833
Arif Hussain826d9412013-11-12 16:44:54 -08002834 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07002835 if (copy_to_user(priv_data.buf, &extra, len + 1))
2836 {
2837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2838 "%s: failed to copy data to user buffer", __func__);
2839 ret = -EFAULT;
2840 goto exit;
2841 }
2842 }
2843#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_CCX || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002844#ifdef FEATURE_WLAN_LFR
2845 else if (strncmp(command, "SETFASTROAM", 11) == 0)
2846 {
2847 tANI_U8 *value = command;
2848 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2849
2850 /* Move pointer to ahead of SETFASTROAM<delimiter> */
2851 value = value + 12;
2852 /* Convert the value from ascii to integer */
2853 ret = kstrtou8(value, 10, &lfrMode);
2854 if (ret < 0)
2855 {
2856 /* If the input value is greater than max value of datatype, then also
2857 kstrtou8 fails */
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "%s: kstrtou8 failed range [%d - %d]", __func__,
2860 CFG_LFR_FEATURE_ENABLED_MIN,
2861 CFG_LFR_FEATURE_ENABLED_MAX);
2862 ret = -EINVAL;
2863 goto exit;
2864 }
2865
2866 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2867 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
2868 {
2869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2870 "lfr mode value %d is out of range"
2871 " (Min: %d Max: %d)", lfrMode,
2872 CFG_LFR_FEATURE_ENABLED_MIN,
2873 CFG_LFR_FEATURE_ENABLED_MAX);
2874 ret = -EINVAL;
2875 goto exit;
2876 }
2877
2878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2879 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
2880
2881 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
2882 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
2883 }
2884#endif
2885#ifdef WLAN_FEATURE_VOWIFI_11R
2886 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
2887 {
2888 tANI_U8 *value = command;
2889 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
2890
2891 /* Move pointer to ahead of SETFASTROAM<delimiter> */
2892 value = value + 18;
2893 /* Convert the value from ascii to integer */
2894 ret = kstrtou8(value, 10, &ft);
2895 if (ret < 0)
2896 {
2897 /* If the input value is greater than max value of datatype, then also
2898 kstrtou8 fails */
2899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2900 "%s: kstrtou8 failed range [%d - %d]", __func__,
2901 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
2902 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
2903 ret = -EINVAL;
2904 goto exit;
2905 }
2906
2907 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
2908 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
2909 {
2910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2911 "ft mode value %d is out of range"
2912 " (Min: %d Max: %d)", ft,
2913 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
2914 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
2915 ret = -EINVAL;
2916 goto exit;
2917 }
2918
2919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2920 "%s: Received Command to change ft mode = %d", __func__, ft);
2921
2922 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
2923 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
2924 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05302925
2926 else if (strncmp(command, "FASTREASSOC", 11) == 0)
2927 {
2928 tANI_U8 *value = command;
2929 tSirMacAddr targetApBssid;
2930 tANI_U8 trigger = 0;
2931 eHalStatus status = eHAL_STATUS_SUCCESS;
2932 hdd_station_ctx_t *pHddStaCtx = NULL;
2933 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2934
2935 /* if not associated, no need to proceed with reassoc */
2936 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2937 {
2938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2939 ret = -EINVAL;
2940 goto exit;
2941 }
2942
2943 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
2944 if (eHAL_STATUS_SUCCESS != status)
2945 {
2946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2947 "%s: Failed to parse reassoc command data", __func__);
2948 ret = -EINVAL;
2949 goto exit;
2950 }
2951
2952 /* if the target bssid is same as currently associated AP,
2953 then no need to proceed with reassoc */
2954 if (VOS_TRUE == vos_mem_compare(targetApBssid,
2955 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2956 {
2957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2958 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
2959 __func__);
2960 ret = -EINVAL;
2961 goto exit;
2962 }
2963
2964 /* Proceed with scan/roam */
2965 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
2966 &targetApBssid[0],
2967 (tSmeFastRoamTrigger)(trigger));
2968 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002969#endif
2970#ifdef FEATURE_WLAN_CCX
2971 else if (strncmp(command, "SETCCXMODE", 10) == 0)
2972 {
2973 tANI_U8 *value = command;
2974 tANI_U8 ccxMode = CFG_CCX_FEATURE_ENABLED_DEFAULT;
2975
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002976 /* Check if the features OKC/CCX/11R are supported simultaneously,
2977 then this operation is not permitted (return FAILURE) */
2978 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
2979 hdd_is_okc_mode_enabled(pHddCtx) &&
2980 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2981 {
2982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2983 "%s: OKC/CCX/11R are supported simultaneously"
2984 " hence this operation is not permitted!", __func__);
2985 ret = -EPERM;
2986 goto exit;
2987 }
2988
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002989 /* Move pointer to ahead of SETCCXMODE<delimiter> */
2990 value = value + 11;
2991 /* Convert the value from ascii to integer */
2992 ret = kstrtou8(value, 10, &ccxMode);
2993 if (ret < 0)
2994 {
2995 /* If the input value is greater than max value of datatype, then also
2996 kstrtou8 fails */
2997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2998 "%s: kstrtou8 failed range [%d - %d]", __func__,
2999 CFG_CCX_FEATURE_ENABLED_MIN,
3000 CFG_CCX_FEATURE_ENABLED_MAX);
3001 ret = -EINVAL;
3002 goto exit;
3003 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003004 if ((ccxMode < CFG_CCX_FEATURE_ENABLED_MIN) ||
3005 (ccxMode > CFG_CCX_FEATURE_ENABLED_MAX))
3006 {
3007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3008 "Ccx mode value %d is out of range"
3009 " (Min: %d Max: %d)", ccxMode,
3010 CFG_CCX_FEATURE_ENABLED_MIN,
3011 CFG_CCX_FEATURE_ENABLED_MAX);
3012 ret = -EINVAL;
3013 goto exit;
3014 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3016 "%s: Received Command to change ccx mode = %d", __func__, ccxMode);
3017
3018 pHddCtx->cfg_ini->isCcxIniFeatureEnabled = ccxMode;
3019 sme_UpdateIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal), ccxMode);
3020 }
3021#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003022 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3023 {
3024 tANI_U8 *value = command;
3025 tANI_BOOLEAN roamScanControl = 0;
3026
3027 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3028 value = value + 19;
3029 /* Convert the value from ascii to integer */
3030 ret = kstrtou8(value, 10, &roamScanControl);
3031 if (ret < 0)
3032 {
3033 /* If the input value is greater than max value of datatype, then also
3034 kstrtou8 fails */
3035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3036 "%s: kstrtou8 failed ", __func__);
3037 ret = -EINVAL;
3038 goto exit;
3039 }
3040
3041 if (0 != roamScanControl)
3042 {
3043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3044 "roam scan control invalid value = %d",
3045 roamScanControl);
3046 ret = -EINVAL;
3047 goto exit;
3048 }
3049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3050 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3051
3052 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3053 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003054#ifdef FEATURE_WLAN_OKC
3055 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3056 {
3057 tANI_U8 *value = command;
3058 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3059
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003060 /* Check if the features OKC/CCX/11R are supported simultaneously,
3061 then this operation is not permitted (return FAILURE) */
3062 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3063 hdd_is_okc_mode_enabled(pHddCtx) &&
3064 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3065 {
3066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3067 "%s: OKC/CCX/11R are supported simultaneously"
3068 " hence this operation is not permitted!", __func__);
3069 ret = -EPERM;
3070 goto exit;
3071 }
3072
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003073 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3074 value = value + 11;
3075 /* Convert the value from ascii to integer */
3076 ret = kstrtou8(value, 10, &okcMode);
3077 if (ret < 0)
3078 {
3079 /* If the input value is greater than max value of datatype, then also
3080 kstrtou8 fails */
3081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3082 "%s: kstrtou8 failed range [%d - %d]", __func__,
3083 CFG_OKC_FEATURE_ENABLED_MIN,
3084 CFG_OKC_FEATURE_ENABLED_MAX);
3085 ret = -EINVAL;
3086 goto exit;
3087 }
3088
3089 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3090 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3091 {
3092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3093 "Okc mode value %d is out of range"
3094 " (Min: %d Max: %d)", okcMode,
3095 CFG_OKC_FEATURE_ENABLED_MIN,
3096 CFG_OKC_FEATURE_ENABLED_MAX);
3097 ret = -EINVAL;
3098 goto exit;
3099 }
3100
3101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3102 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3103
3104 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3105 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003106#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003107 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3108 {
3109 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3110 char extra[32];
3111 tANI_U8 len = 0;
3112
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003113 len = scnprintf(extra, sizeof(extra), "%s %d",
3114 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003115 if (copy_to_user(priv_data.buf, &extra, len + 1))
3116 {
3117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3118 "%s: failed to copy data to user buffer", __func__);
3119 ret = -EFAULT;
3120 goto exit;
3121 }
3122 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303123#ifdef WLAN_FEATURE_PACKET_FILTERING
3124 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3125 {
3126 tANI_U8 filterType = 0;
3127 tANI_U8 *value = command;
3128
3129 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3130 value = value + 22;
3131
3132 /* Convert the value from ascii to integer */
3133 ret = kstrtou8(value, 10, &filterType);
3134 if (ret < 0)
3135 {
3136 /* If the input value is greater than max value of datatype,
3137 * then also kstrtou8 fails
3138 */
3139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3140 "%s: kstrtou8 failed range ", __func__);
3141 ret = -EINVAL;
3142 goto exit;
3143 }
3144
3145 if (filterType != 0 && filterType != 1)
3146 {
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3148 "%s: Accepted Values are 0 and 1 ", __func__);
3149 ret = -EINVAL;
3150 goto exit;
3151 }
3152 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3153 pAdapter->sessionId);
3154 }
3155#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303156 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3157 {
3158 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303159 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303160 if ('1' == *dhcpPhase)
3161 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3163 FL("BTCOEXMODE %d"), *dhcpPhase);
3164
3165 pHddCtx->btCoexModeSet = TRUE;
3166
3167 /* Firmware failing to process DHCP START/STOP indications.
3168 * So, for now commentig below code, once issue is resolved,
3169 * follwing will be uncommented.
3170 */
3171 #if 0
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303172 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3173 pAdapter->macAddressCurrent.bytes);
c_hpothu9b781ba2013-12-30 20:57:45 +05303174 #endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303175 }
3176 else if ('2' == *dhcpPhase)
3177 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3179 FL("BTCOEXMODE %d"), *dhcpPhase);
3180
3181 pHddCtx->btCoexModeSet = FALSE;
3182
3183 /* Firmware failing to process DHCP START/STOP indications.
3184 * So, for now commentig below code, once issue is resolved,
3185 * follwing will be uncommented.
3186 */
3187 #if 0
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303188 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3189 pAdapter->macAddressCurrent.bytes);
c_hpothu9b781ba2013-12-30 20:57:45 +05303190 #endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303191 }
3192 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003193 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3194 {
3195 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3196 }
3197 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3198 {
3199 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3200 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303201 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3202 {
3203 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3204 char extra[32];
3205 tANI_U8 len = 0;
3206
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003207 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303208 (int)pCfg->nActiveMaxChnTime);
3209 if (copy_to_user(priv_data.buf, &extra, len + 1))
3210 {
3211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3212 "%s: failed to copy data to user buffer", __func__);
3213 ret = -EFAULT;
3214 goto exit;
3215 }
3216 ret = len;
3217 }
3218 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3219 {
3220 tANI_U8 *value = command;
3221 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3222 int val = 0, temp;
3223
3224 value = value + 13;
3225 temp = kstrtou32(value, 10, &val);
3226 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3227 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3228 {
3229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3230 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3231 ret = -EFAULT;
3232 goto exit;
3233 }
3234 pCfg->nActiveMaxChnTime = val;
3235 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003236 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3237 {
3238 tANI_U8 filterType = 0;
3239 tANI_U8 *value;
3240 value = command + 9;
3241
3242 /* Convert the value from ascii to integer */
3243 ret = kstrtou8(value, 10, &filterType);
3244 if (ret < 0)
3245 {
3246 /* If the input value is greater than max value of datatype,
3247 * then also kstrtou8 fails
3248 */
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "%s: kstrtou8 failed range ", __func__);
3251 ret = -EINVAL;
3252 goto exit;
3253 }
3254 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3255 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3256 {
3257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3258 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3259 " 2-Sink ", __func__);
3260 ret = -EINVAL;
3261 goto exit;
3262 }
3263 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3264 pHddCtx->drvr_miracast = filterType;
3265 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3266 }
Leo Chang614d2072013-08-22 14:59:44 -07003267 else if (strncmp(command, "SETMCRATE", 9) == 0)
3268 {
Leo Chang614d2072013-08-22 14:59:44 -07003269 tANI_U8 *value = command;
3270 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003271 tSirRateUpdateInd *rateUpdate;
3272 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003273
3274 /* Only valid for SAP mode */
3275 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3276 {
3277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3278 "%s: SAP mode is not running", __func__);
3279 ret = -EFAULT;
3280 goto exit;
3281 }
3282
3283 /* Move pointer to ahead of SETMCRATE<delimiter> */
3284 /* input value is in units of hundred kbps */
3285 value = value + 10;
3286 /* Convert the value from ascii to integer, decimal base */
3287 ret = kstrtouint(value, 10, &targetRate);
3288
Leo Chang1f98cbd2013-10-17 15:03:52 -07003289 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3290 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003291 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003292 hddLog(VOS_TRACE_LEVEL_ERROR,
3293 "%s: SETMCRATE indication alloc fail", __func__);
3294 ret = -EFAULT;
3295 goto exit;
3296 }
3297 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3298
3299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3300 "MC Target rate %d", targetRate);
3301 /* Ignore unicast */
3302 rateUpdate->ucastDataRate = -1;
3303 rateUpdate->mcastDataRate24GHz = targetRate;
3304 rateUpdate->mcastDataRate5GHz = targetRate;
3305 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3306 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3307 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3308 if (eHAL_STATUS_SUCCESS != status)
3309 {
3310 hddLog(VOS_TRACE_LEVEL_ERROR,
3311 "%s: SET_MC_RATE failed", __func__);
3312 vos_mem_free(rateUpdate);
3313 ret = -EFAULT;
3314 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003315 }
3316 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303317#ifdef FEATURE_WLAN_BATCH_SCAN
3318 else if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
3319 {
3320 char extra[32];
3321 tANI_U8 len = 0;
3322 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
3323
3324 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
3325 {
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s: Batch scan feature is not supported by FW", __func__);
3328 ret = -EINVAL;
3329 goto exit;
3330 }
3331
Rajeev Kumar30e4da52013-12-27 11:43:45 -08003332 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
3333 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
3334 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
Rajeev79dbe4c2013-10-05 11:03:42 +05303335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar30e4da52013-12-27 11:43:45 -08003337 "Received WLS_BATCHING VERSION command in invalid mode %d "
Rajeev79dbe4c2013-10-05 11:03:42 +05303338 "WLS_BATCHING_VERSION is only allowed in infra STA/P2P client"
3339 " mode",
3340 pAdapter->device_mode);
3341 ret = -EINVAL;
3342 goto exit;
3343 }
3344
Arif Hussain826d9412013-11-12 16:44:54 -08003345 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
Rajeev79dbe4c2013-10-05 11:03:42 +05303346 version);
3347 if (copy_to_user(priv_data.buf, &extra, len + 1))
3348 {
3349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3350 "%s: failed to copy data to user buffer", __func__);
3351 ret = -EFAULT;
3352 goto exit;
3353 }
3354 ret = HDD_BATCH_SCAN_VERSION;
3355 }
3356 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
3357 {
3358 int status;
3359 tANI_U8 *value = (command + 16);
3360 eHalStatus halStatus;
3361 unsigned long rc;
3362 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
3363 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
3364
3365 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
3366 {
3367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3368 "%s: Batch scan feature is not supported by FW", __func__);
3369 ret = -EINVAL;
3370 goto exit;
3371 }
3372
Rajeev Kumar20140c12013-10-21 19:39:02 -07003373
Rajeev79dbe4c2013-10-05 11:03:42 +05303374 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
Rajeev Kumar5286bb92013-12-05 11:52:10 -08003375 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
3376 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
Rajeev79dbe4c2013-10-05 11:03:42 +05303377 {
3378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar20140c12013-10-21 19:39:02 -07003379 "Received WLS_BATCHING SET command in invalid mode %d "
Rajeev79dbe4c2013-10-05 11:03:42 +05303380 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
3381 pAdapter->device_mode);
3382 ret = -EINVAL;
3383 goto exit;
3384 }
3385
Rajeev Kumar20140c12013-10-21 19:39:02 -07003386
Rajeev79dbe4c2013-10-05 11:03:42 +05303387 status = hdd_parse_set_batchscan_command(value, pReq);
3388 if (status)
3389 {
3390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar20140c12013-10-21 19:39:02 -07003391 "Invalid WLS_BATCHING SET command");
Rajeev79dbe4c2013-10-05 11:03:42 +05303392 ret = -EINVAL;
3393 goto exit;
3394 }
Rajeev Kumar20140c12013-10-21 19:39:02 -07003395
3396
Rajeev79dbe4c2013-10-05 11:03:42 +05303397 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
3398 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
3399 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
3400 pAdapter);
3401
3402 if ( eHAL_STATUS_SUCCESS == halStatus )
3403 {
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3405 "sme_SetBatchScanReq returned success halStatus %d",
3406 halStatus);
3407 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
3408 {
3409 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
3410 rc = wait_for_completion_timeout(
3411 &pAdapter->hdd_set_batch_scan_req_var,
3412 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
3413 if (0 == rc)
3414 {
3415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3416 "%s: Timeout waiting for set batch scan to complete",
3417 __func__);
3418 ret = -EINVAL;
3419 goto exit;
3420 }
3421 }
3422 if ( !pRsp->nScansToBatch )
3423 {
3424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3425 "%s: Received set batch scan failure response from FW",
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003426 __func__);
Rajeev79dbe4c2013-10-05 11:03:42 +05303427 ret = -EINVAL;
3428 goto exit;
3429 }
3430 /*As per the Batch Scan Framework API we should return the MIN of
3431 either MSCAN or the max # of scans firmware can cache*/
3432 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
3433
Rajeev Kumar20140c12013-10-21 19:39:02 -07003434 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
3435
Rajeev79dbe4c2013-10-05 11:03:42 +05303436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3437 "%s: request MSCAN %d response MSCAN %d ret %d",
3438 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
3439 }
3440 else
3441 {
3442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3443 "sme_SetBatchScanReq returned failure halStatus %d",
3444 halStatus);
3445 ret = -EINVAL;
3446 goto exit;
3447 }
3448 }
3449 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
3450 {
3451 eHalStatus halStatus;
3452 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
3453 pInd->param = 0;
3454
3455 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
3456 {
3457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3458 "%s: Batch scan feature is not supported by FW", __func__);
3459 ret = -EINVAL;
3460 goto exit;
3461 }
3462
Rajeev Kumar20140c12013-10-21 19:39:02 -07003463 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
Rajeev79dbe4c2013-10-05 11:03:42 +05303464 {
3465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar20140c12013-10-21 19:39:02 -07003466 "Batch scan is not yet enabled batch scan state %d",
3467 pAdapter->batchScanState);
Rajeev79dbe4c2013-10-05 11:03:42 +05303468 ret = -EINVAL;
3469 goto exit;
3470 }
3471
Rajeev Kumar20140c12013-10-21 19:39:02 -07003472 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
3473
Rajeev79dbe4c2013-10-05 11:03:42 +05303474 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
3475 pAdapter->sessionId);
3476 if ( eHAL_STATUS_SUCCESS == halStatus )
3477 {
3478 ret = 0;
3479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3480 "sme_StopBatchScanInd returned success halStatus %d",
3481 halStatus);
3482 }
3483 else
3484 {
3485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3486 "sme_StopBatchScanInd returned failure halStatus %d",
3487 halStatus);
3488 ret = -EINVAL;
3489 goto exit;
3490 }
3491 }
3492 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
3493 {
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07003494 tANI_U32 remain_len;
3495
Rajeev79dbe4c2013-10-05 11:03:42 +05303496 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
3497 {
3498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3499 "%s: Batch scan feature is not supported by FW", __func__);
3500 ret = -EINVAL;
3501 goto exit;
3502 }
3503
Rajeev Kumar20140c12013-10-21 19:39:02 -07003504 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
Rajeev79dbe4c2013-10-05 11:03:42 +05303505 {
3506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar20140c12013-10-21 19:39:02 -07003507 "Batch scan is not yet enabled could not return results"
3508 "Batch Scan state %d",
3509 pAdapter->batchScanState);
Rajeev79dbe4c2013-10-05 11:03:42 +05303510 ret = -EINVAL;
3511 goto exit;
3512 }
3513
3514 priv_data.used_len = 16;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07003515 remain_len = priv_data.total_len - priv_data.used_len;
3516 if (remain_len < priv_data.total_len)
3517 {
3518 /*Clear previous batch scan response data if any*/
3519 vos_mem_zero((tANI_U8 *)(command + priv_data.used_len), remain_len);
3520 }
3521 else
3522 {
3523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3524 "Invalid total length from user space can't fetch batch"
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003525 " scan response total_len %d used_len %d remain len %d",
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07003526 priv_data.total_len, priv_data.used_len, remain_len);
3527 ret = -EINVAL;
3528 goto exit;
3529 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303530 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, &priv_data, command);
3531 }
3532#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003533#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
3534 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3535 {
3536 tANI_U8 *value = command;
3537 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3538 tANI_U8 numChannels = 0;
3539 eHalStatus status = eHAL_STATUS_SUCCESS;
3540
3541 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3542 if (eHAL_STATUS_SUCCESS != status)
3543 {
3544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3545 "%s: Failed to parse channel list information", __func__);
3546 ret = -EINVAL;
3547 goto exit;
3548 }
3549
3550 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3551 {
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3554 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3555 ret = -EINVAL;
3556 goto exit;
3557 }
3558 status = sme_SetCcxRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
3559 ChannelList,
3560 numChannels);
3561 if (eHAL_STATUS_SUCCESS != status)
3562 {
3563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3564 "%s: Failed to update channel list information", __func__);
3565 ret = -EINVAL;
3566 goto exit;
3567 }
3568 }
3569 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3570 {
3571 tANI_U8 *value = command;
3572 char extra[128] = {0};
3573 int len = 0;
3574 tANI_U8 tid = 0;
3575 hdd_station_ctx_t *pHddStaCtx = NULL;
3576 tAniTrafStrmMetrics tsmMetrics;
3577 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3578
3579 /* if not associated, return error */
3580 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3581 {
3582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3583 ret = -EINVAL;
3584 goto exit;
3585 }
3586
3587 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3588 value = value + 12;
3589 /* Convert the value from ascii to integer */
3590 ret = kstrtou8(value, 10, &tid);
3591 if (ret < 0)
3592 {
3593 /* If the input value is greater than max value of datatype, then also
3594 kstrtou8 fails */
3595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3596 "%s: kstrtou8 failed range [%d - %d]", __func__,
3597 TID_MIN_VALUE,
3598 TID_MAX_VALUE);
3599 ret = -EINVAL;
3600 goto exit;
3601 }
3602
3603 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3604 {
3605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3606 "tid value %d is out of range"
3607 " (Min: %d Max: %d)", tid,
3608 TID_MIN_VALUE,
3609 TID_MAX_VALUE);
3610 ret = -EINVAL;
3611 goto exit;
3612 }
3613
3614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3615 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3616
3617 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3618 {
3619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3620 "%s: failed to get tsm stats", __func__);
3621 ret = -EFAULT;
3622 goto exit;
3623 }
3624
3625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3626 "UplinkPktQueueDly(%d)\n"
3627 "UplinkPktQueueDlyHist[0](%d)\n"
3628 "UplinkPktQueueDlyHist[1](%d)\n"
3629 "UplinkPktQueueDlyHist[2](%d)\n"
3630 "UplinkPktQueueDlyHist[3](%d)\n"
3631 "UplinkPktTxDly(%lu)\n"
3632 "UplinkPktLoss(%d)\n"
3633 "UplinkPktCount(%d)\n"
3634 "RoamingCount(%d)\n"
3635 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3636 tsmMetrics.UplinkPktQueueDlyHist[0],
3637 tsmMetrics.UplinkPktQueueDlyHist[1],
3638 tsmMetrics.UplinkPktQueueDlyHist[2],
3639 tsmMetrics.UplinkPktQueueDlyHist[3],
3640 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3641 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3642
3643 /* Output TSM stats is of the format
3644 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3645 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003646 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003647 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3648 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3649 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3650 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3651 tsmMetrics.RoamingDly);
3652
3653 if (copy_to_user(priv_data.buf, &extra, len + 1))
3654 {
3655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3656 "%s: failed to copy data to user buffer", __func__);
3657 ret = -EFAULT;
3658 goto exit;
3659 }
3660 }
3661 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3662 {
3663 tANI_U8 *value = command;
3664 tANI_U8 *cckmIe = NULL;
3665 tANI_U8 cckmIeLen = 0;
3666 eHalStatus status = eHAL_STATUS_SUCCESS;
3667
3668 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3669 if (eHAL_STATUS_SUCCESS != status)
3670 {
3671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3672 "%s: Failed to parse cckm ie data", __func__);
3673 ret = -EINVAL;
3674 goto exit;
3675 }
3676
3677 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3678 {
3679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3680 "%s: CCKM Ie input length is more than max[%d]", __func__,
3681 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003682 vos_mem_free(cckmIe);
3683 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003684 ret = -EINVAL;
3685 goto exit;
3686 }
3687 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003688 vos_mem_free(cckmIe);
3689 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003690 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003691 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3692 {
3693 tANI_U8 *value = command;
3694 tCsrCcxBeaconReq ccxBcnReq;
3695 eHalStatus status = eHAL_STATUS_SUCCESS;
3696 status = hdd_parse_ccx_beacon_req(value, &ccxBcnReq);
3697 if (eHAL_STATUS_SUCCESS != status)
3698 {
3699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3700 "%s: Failed to parse ccx beacon req", __func__);
3701 ret = -EINVAL;
3702 goto exit;
3703 }
3704
3705 sme_SetCcxBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &ccxBcnReq);
3706 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003707#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003708 else {
3709 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3710 __func__, command);
3711 }
3712
Jeff Johnson295189b2012-06-20 16:38:30 -07003713 }
3714exit:
3715 if (command)
3716 {
3717 kfree(command);
3718 }
3719 return ret;
3720}
3721
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003722
3723
3724#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003725/**---------------------------------------------------------------------------
3726
3727 \brief hdd_parse_ccx_beacon_req() - Parse ccx beacon request
3728
3729 This function parses the ccx beacon request passed in the format
3730 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3731 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3732 <space>Scan Mode N<space>Meas Duration N
3733 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3734 then take N.
3735 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3736 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3737 This function does not take care of removing duplicate channels from the list
3738
3739 \param - pValue Pointer to data
3740 \param - pCcxBcnReq output pointer to store parsed ie information
3741
3742 \return - 0 for success non-zero for failure
3743
3744 --------------------------------------------------------------------------*/
3745static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
3746 tCsrCcxBeaconReq *pCcxBcnReq)
3747{
3748 tANI_U8 *inPtr = pValue;
3749 int tempInt = 0;
3750 int j = 0, i = 0, v = 0;
3751 char buf[32];
3752
3753 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3754 /*no argument after the command*/
3755 if (NULL == inPtr)
3756 {
3757 return -EINVAL;
3758 }
3759 /*no space after the command*/
3760 else if (SPACE_ASCII_VALUE != *inPtr)
3761 {
3762 return -EINVAL;
3763 }
3764
3765 /*removing empty spaces*/
3766 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3767
3768 /*no argument followed by spaces*/
3769 if ('\0' == *inPtr) return -EINVAL;
3770
3771 /*getting the first argument ie measurement token*/
3772 v = sscanf(inPtr, "%32s ", buf);
3773 if (1 != v) return -EINVAL;
3774
3775 v = kstrtos32(buf, 10, &tempInt);
3776 if ( v < 0) return -EINVAL;
3777
3778 pCcxBcnReq->numBcnReqIe = tempInt;
3779
3780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
3781 "Number of Bcn Req Ie fields(%d)", pCcxBcnReq->numBcnReqIe);
3782
3783 for (j = 0; j < (pCcxBcnReq->numBcnReqIe); j++)
3784 {
3785 for (i = 0; i < 4; i++)
3786 {
3787 /*inPtr pointing to the beginning of first space after number of ie fields*/
3788 inPtr = strpbrk( inPtr, " " );
3789 /*no ie data after the number of ie fields argument*/
3790 if (NULL == inPtr) return -EINVAL;
3791
3792 /*removing empty space*/
3793 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3794
3795 /*no ie data after the number of ie fields argument and spaces*/
3796 if ( '\0' == *inPtr ) return -EINVAL;
3797
3798 v = sscanf(inPtr, "%32s ", buf);
3799 if (1 != v) return -EINVAL;
3800
3801 v = kstrtos32(buf, 10, &tempInt);
3802 if (v < 0) return -EINVAL;
3803
3804 switch (i)
3805 {
3806 case 0: /* Measurement token */
3807 if (tempInt <= 0)
3808 {
3809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3810 "Invalid Measurement Token(%d)", tempInt);
3811 return -EINVAL;
3812 }
3813 pCcxBcnReq->bcnReq[j].measurementToken = tempInt;
3814 break;
3815
3816 case 1: /* Channel number */
3817 if ((tempInt <= 0) ||
3818 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
3819 {
3820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3821 "Invalid Channel Number(%d)", tempInt);
3822 return -EINVAL;
3823 }
3824 pCcxBcnReq->bcnReq[j].channel = tempInt;
3825 break;
3826
3827 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003828 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003829 {
3830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3831 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
3832 return -EINVAL;
3833 }
3834 pCcxBcnReq->bcnReq[j].scanMode= tempInt;
3835 break;
3836
3837 case 3: /* Measurement duration */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003838 if (((tempInt <= 0) && (pCcxBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
3839 ((tempInt < 0) && (pCcxBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003840 {
3841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3842 "Invalid Measurement Duration(%d)", tempInt);
3843 return -EINVAL;
3844 }
3845 pCcxBcnReq->bcnReq[j].measurementDuration = tempInt;
3846 break;
3847 }
3848 }
3849 }
3850
3851 for (j = 0; j < pCcxBcnReq->numBcnReqIe; j++)
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3854 "Index(%d) Measurement Token(%lu)Channel(%lu) Scan Mode(%lu) Measurement Duration(%lu)\n",
3855 j,
3856 pCcxBcnReq->bcnReq[j].measurementToken,
3857 pCcxBcnReq->bcnReq[j].channel,
3858 pCcxBcnReq->bcnReq[j].scanMode,
3859 pCcxBcnReq->bcnReq[j].measurementDuration);
3860 }
3861
3862 return VOS_STATUS_SUCCESS;
3863}
3864
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003865static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
3866{
3867 struct statsContext *pStatsContext = NULL;
3868 hdd_adapter_t *pAdapter = NULL;
3869
3870 if (NULL == pContext)
3871 {
3872 hddLog(VOS_TRACE_LEVEL_ERROR,
3873 "%s: Bad param, pContext [%p]",
3874 __func__, pContext);
3875 return;
3876 }
3877
Jeff Johnson72a40512013-12-19 10:14:15 -08003878 /* there is a race condition that exists between this callback
3879 function and the caller since the caller could time out either
3880 before or while this code is executing. we use a spinlock to
3881 serialize these actions */
3882 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003883
3884 pStatsContext = pContext;
3885 pAdapter = pStatsContext->pAdapter;
3886 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
3887 {
3888 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08003889 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003890 hddLog(VOS_TRACE_LEVEL_WARN,
3891 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3892 __func__, pAdapter, pStatsContext->magic);
3893 return;
3894 }
3895
Jeff Johnson72a40512013-12-19 10:14:15 -08003896 /* context is valid so caller is still waiting */
3897
3898 /* paranoia: invalidate the magic */
3899 pStatsContext->magic = 0;
3900
3901 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003902 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
3903 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
3904 tsmMetrics.UplinkPktQueueDlyHist,
3905 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
3906 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
3907 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
3908 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
3909 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
3910 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
3911 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
3912
Jeff Johnson72a40512013-12-19 10:14:15 -08003913 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003914 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08003915
3916 /* serialization is complete */
3917 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003918}
3919
3920
3921
3922static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
3923 tAniTrafStrmMetrics* pTsmMetrics)
3924{
3925 hdd_station_ctx_t *pHddStaCtx = NULL;
3926 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08003927 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003928 long lrc;
3929 struct statsContext context;
3930 hdd_context_t *pHddCtx = NULL;
3931
3932 if (NULL == pAdapter)
3933 {
3934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
3935 return VOS_STATUS_E_FAULT;
3936 }
3937
3938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3939 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3940
3941 /* we are connected prepare our callback context */
3942 init_completion(&context.completion);
3943 context.pAdapter = pAdapter;
3944 context.magic = STATS_CONTEXT_MAGIC;
3945
3946 /* query tsm stats */
3947 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
3948 pHddStaCtx->conn_info.staId[ 0 ],
3949 pHddStaCtx->conn_info.bssId,
3950 &context, pHddCtx->pvosContext, tid);
3951
3952 if (eHAL_STATUS_SUCCESS != hstatus)
3953 {
Jeff Johnson72a40512013-12-19 10:14:15 -08003954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
3955 __func__);
3956 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003957 }
3958 else
3959 {
3960 /* request was sent -- wait for the response */
3961 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3962 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003963 if (lrc <= 0)
3964 {
3965 hddLog(VOS_TRACE_LEVEL_ERROR,
3966 "%s: SME %s while retrieving statistics",
3967 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08003968 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003969 }
3970 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003971
Jeff Johnson72a40512013-12-19 10:14:15 -08003972 /* either we never sent a request, we sent a request and received a
3973 response or we sent a request and timed out. if we never sent a
3974 request or if we sent a request and got a response, we want to
3975 clear the magic out of paranoia. if we timed out there is a
3976 race condition such that the callback function could be
3977 executing at the same time we are. of primary concern is if the
3978 callback function had already verified the "magic" but had not
3979 yet set the completion variable when a timeout occurred. we
3980 serialize these activities by invalidating the magic while
3981 holding a shared spinlock which will cause us to block if the
3982 callback is currently executing */
3983 spin_lock(&hdd_context_lock);
3984 context.magic = 0;
3985 spin_unlock(&hdd_context_lock);
3986
3987 if (VOS_STATUS_SUCCESS == vstatus)
3988 {
3989 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
3990 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
3991 pAdapter->tsmStats.UplinkPktQueueDlyHist,
3992 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
3993 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
3994 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
3995 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
3996 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
3997 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
3998 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
3999 }
4000 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004001}
4002#endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4003
Srinivas Girigowdade697412013-02-14 16:31:48 -08004004#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
4005void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4006{
4007 eCsrBand band = -1;
4008 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4009 switch (band)
4010 {
4011 case eCSR_BAND_ALL:
4012 *pBand = WLAN_HDD_UI_BAND_AUTO;
4013 break;
4014
4015 case eCSR_BAND_24:
4016 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4017 break;
4018
4019 case eCSR_BAND_5G:
4020 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4021 break;
4022
4023 default:
4024 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4025 *pBand = -1;
4026 break;
4027 }
4028}
4029
4030/**---------------------------------------------------------------------------
4031
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004032 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4033
4034 This function parses the send action frame data passed in the format
4035 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4036
Srinivas Girigowda56076852013-08-20 14:00:50 -07004037 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004038 \param - pTargetApBssid Pointer to target Ap bssid
4039 \param - pChannel Pointer to the Target AP channel
4040 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4041 \param - pBuf Pointer to data
4042 \param - pBufLen Pointer to data length
4043
4044 \return - 0 for success non-zero for failure
4045
4046 --------------------------------------------------------------------------*/
4047VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4048 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4049{
4050 tANI_U8 *inPtr = pValue;
4051 tANI_U8 *dataEnd;
4052 int tempInt;
4053 int j = 0;
4054 int i = 0;
4055 int v = 0;
4056 tANI_U8 tempBuf[32];
4057 tANI_U8 tempByte = 0;
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004058 /* 12 hexa decimal digits and 5 ':' */
4059 tANI_U8 macAddress[17];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004060
4061 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4062 /*no argument after the command*/
4063 if (NULL == inPtr)
4064 {
4065 return -EINVAL;
4066 }
4067
4068 /*no space after the command*/
4069 else if (SPACE_ASCII_VALUE != *inPtr)
4070 {
4071 return -EINVAL;
4072 }
4073
4074 /*removing empty spaces*/
4075 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4076
4077 /*no argument followed by spaces*/
4078 if ('\0' == *inPtr)
4079 {
4080 return -EINVAL;
4081 }
4082
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004083 v = sscanf(inPtr, "%17s", macAddress);
4084 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004085 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4087 "Invalid MAC address or All hex inputs are not read (%d)", v);
4088 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004089 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004090
4091 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4092 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4093 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4094 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4095 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4096 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004097
4098 /* point to the next argument */
4099 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4100 /*no argument after the command*/
4101 if (NULL == inPtr) return -EINVAL;
4102
4103 /*removing empty spaces*/
4104 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4105
4106 /*no argument followed by spaces*/
4107 if ('\0' == *inPtr)
4108 {
4109 return -EINVAL;
4110 }
4111
4112 /*getting the next argument ie the channel number */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004113 v = sscanf(inPtr, "%32s ", tempBuf);
4114 if (1 != v) return -EINVAL;
4115
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004116 v = kstrtos32(tempBuf, 10, &tempInt);
Kiet Lambe150c22013-11-21 16:30:32 +05304117 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
4118 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004119
4120 *pChannel = tempInt;
4121
4122 /* point to the next argument */
4123 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4124 /*no argument after the command*/
4125 if (NULL == inPtr) return -EINVAL;
4126 /*removing empty spaces*/
4127 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4128
4129 /*no argument followed by spaces*/
4130 if ('\0' == *inPtr)
4131 {
4132 return -EINVAL;
4133 }
4134
4135 /*getting the next argument ie the dwell time */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004136 v = sscanf(inPtr, "%32s ", tempBuf);
4137 if (1 != v) return -EINVAL;
4138
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004139 v = kstrtos32(tempBuf, 10, &tempInt);
Kiet Lambe150c22013-11-21 16:30:32 +05304140 if ( v < 0 || tempInt <= 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004141
4142 *pDwellTime = tempInt;
4143
4144 /* point to the next argument */
4145 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4146 /*no argument after the command*/
4147 if (NULL == inPtr) return -EINVAL;
4148 /*removing empty spaces*/
4149 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4150
4151 /*no argument followed by spaces*/
4152 if ('\0' == *inPtr)
4153 {
4154 return -EINVAL;
4155 }
4156
4157 /* find the length of data */
4158 dataEnd = inPtr;
4159 while(('\0' != *dataEnd) )
4160 {
4161 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004162 }
Kiet Lambe150c22013-11-21 16:30:32 +05304163 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004164 if ( *pBufLen <= 0) return -EINVAL;
4165
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004166 /* Allocate the number of bytes based on the number of input characters
4167 whether it is even or odd.
4168 if the number of input characters are even, then we need N/2 byte.
4169 if the number of input characters are odd, then we need do (N+1)/2 to
4170 compensate rounding off.
4171 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4172 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4173 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004174 if (NULL == *pBuf)
4175 {
4176 hddLog(VOS_TRACE_LEVEL_FATAL,
4177 "%s: vos_mem_alloc failed ", __func__);
4178 return -EINVAL;
4179 }
4180
4181 /* the buffer received from the upper layer is character buffer,
4182 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4183 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4184 and f0 in 3rd location */
4185 for (i = 0, j = 0; j < *pBufLen; j += 2)
4186 {
Kiet Lambe150c22013-11-21 16:30:32 +05304187 if( j+1 == *pBufLen)
4188 {
4189 tempByte = hdd_parse_hex(inPtr[j]);
4190 }
4191 else
4192 {
4193 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4194 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004195 (*pBuf)[i++] = tempByte;
4196 }
4197 *pBufLen = i;
4198 return VOS_STATUS_SUCCESS;
4199}
4200
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004201/**---------------------------------------------------------------------------
4202
Srinivas Girigowdade697412013-02-14 16:31:48 -08004203 \brief hdd_parse_channellist() - HDD Parse channel list
4204
4205 This function parses the channel list passed in the format
4206 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004207 if the Number of channels (N) does not match with the actual number of channels passed
4208 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4209 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4210 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4211 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004212
4213 \param - pValue Pointer to input channel list
4214 \param - ChannelList Pointer to local output array to record channel list
4215 \param - pNumChannels Pointer to number of roam scan channels
4216
4217 \return - 0 for success non-zero for failure
4218
4219 --------------------------------------------------------------------------*/
4220VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4221{
4222 tANI_U8 *inPtr = pValue;
4223 int tempInt;
4224 int j = 0;
4225 int v = 0;
4226 char buf[32];
4227
4228 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4229 /*no argument after the command*/
4230 if (NULL == inPtr)
4231 {
4232 return -EINVAL;
4233 }
4234
4235 /*no space after the command*/
4236 else if (SPACE_ASCII_VALUE != *inPtr)
4237 {
4238 return -EINVAL;
4239 }
4240
4241 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004242 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004243
4244 /*no argument followed by spaces*/
4245 if ('\0' == *inPtr)
4246 {
4247 return -EINVAL;
4248 }
4249
4250 /*getting the first argument ie the number of channels*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004251 v = sscanf(inPtr, "%32s ", buf);
4252 if (1 != v) return -EINVAL;
4253
Srinivas Girigowdade697412013-02-14 16:31:48 -08004254 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004255 if ((v < 0) ||
4256 (tempInt <= 0) ||
4257 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4258 {
4259 return -EINVAL;
4260 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004261
4262 *pNumChannels = tempInt;
4263
4264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4265 "Number of channels are: %d", *pNumChannels);
4266
4267 for (j = 0; j < (*pNumChannels); j++)
4268 {
4269 /*inPtr pointing to the beginning of first space after number of channels*/
4270 inPtr = strpbrk( inPtr, " " );
4271 /*no channel list after the number of channels argument*/
4272 if (NULL == inPtr)
4273 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004274 if (0 != j)
4275 {
4276 *pNumChannels = j;
4277 return VOS_STATUS_SUCCESS;
4278 }
4279 else
4280 {
4281 return -EINVAL;
4282 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004283 }
4284
4285 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004286 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004287
4288 /*no channel list after the number of channels argument and spaces*/
4289 if ( '\0' == *inPtr )
4290 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004291 if (0 != j)
4292 {
4293 *pNumChannels = j;
4294 return VOS_STATUS_SUCCESS;
4295 }
4296 else
4297 {
4298 return -EINVAL;
4299 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004300 }
4301
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004302 v = sscanf(inPtr, "%32s ", buf);
4303 if (1 != v) return -EINVAL;
4304
Srinivas Girigowdade697412013-02-14 16:31:48 -08004305 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004306 if ((v < 0) ||
4307 (tempInt <= 0) ||
4308 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4309 {
4310 return -EINVAL;
4311 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004312 pChannelList[j] = tempInt;
4313
4314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4315 "Channel %d added to preferred channel list",
4316 pChannelList[j] );
4317 }
4318
Srinivas Girigowdade697412013-02-14 16:31:48 -08004319 return VOS_STATUS_SUCCESS;
4320}
4321
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004322
4323/**---------------------------------------------------------------------------
4324
4325 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4326
4327 This function parses the reasoc command data passed in the format
4328 REASSOC<space><bssid><space><channel>
4329
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004330 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004331 \param - pTargetApBssid Pointer to target Ap bssid
4332 \param - pChannel Pointer to the Target AP channel
4333
4334 \return - 0 for success non-zero for failure
4335
4336 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004337VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4338 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004339{
4340 tANI_U8 *inPtr = pValue;
4341 int tempInt;
4342 int v = 0;
4343 tANI_U8 tempBuf[32];
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004344 /* 12 hexa decimal digits and 5 ':' */
4345 tANI_U8 macAddress[17];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004346
4347 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4348 /*no argument after the command*/
4349 if (NULL == inPtr)
4350 {
4351 return -EINVAL;
4352 }
4353
4354 /*no space after the command*/
4355 else if (SPACE_ASCII_VALUE != *inPtr)
4356 {
4357 return -EINVAL;
4358 }
4359
4360 /*removing empty spaces*/
4361 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4362
4363 /*no argument followed by spaces*/
4364 if ('\0' == *inPtr)
4365 {
4366 return -EINVAL;
4367 }
4368
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004369 v = sscanf(inPtr, "%17s", macAddress);
4370 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004371 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4373 "Invalid MAC address or All hex inputs are not read (%d)", v);
4374 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004375 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004376
4377 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4378 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4379 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4380 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4381 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4382 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004383
4384 /* point to the next argument */
4385 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4386 /*no argument after the command*/
4387 if (NULL == inPtr) return -EINVAL;
4388
4389 /*removing empty spaces*/
4390 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4391
4392 /*no argument followed by spaces*/
4393 if ('\0' == *inPtr)
4394 {
4395 return -EINVAL;
4396 }
4397
4398 /*getting the next argument ie the channel number */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004399 v = sscanf(inPtr, "%32s ", tempBuf);
4400 if (1 != v) return -EINVAL;
4401
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004402 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004403 if ((v < 0) ||
4404 (tempInt <= 0) ||
4405 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4406 {
4407 return -EINVAL;
4408 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004409
4410 *pChannel = tempInt;
4411 return VOS_STATUS_SUCCESS;
4412}
4413
4414#endif
4415
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004416#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
4417/**---------------------------------------------------------------------------
4418
4419 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4420
4421 This function parses the SETCCKM IE command
4422 SETCCKMIE<space><ie data>
4423
4424 \param - pValue Pointer to input data
4425 \param - pCckmIe Pointer to output cckm Ie
4426 \param - pCckmIeLen Pointer to output cckm ie length
4427
4428 \return - 0 for success non-zero for failure
4429
4430 --------------------------------------------------------------------------*/
4431VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4432 tANI_U8 *pCckmIeLen)
4433{
4434 tANI_U8 *inPtr = pValue;
4435 tANI_U8 *dataEnd;
4436 int j = 0;
4437 int i = 0;
4438 tANI_U8 tempByte = 0;
4439
4440 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4441 /*no argument after the command*/
4442 if (NULL == inPtr)
4443 {
4444 return -EINVAL;
4445 }
4446
4447 /*no space after the command*/
4448 else if (SPACE_ASCII_VALUE != *inPtr)
4449 {
4450 return -EINVAL;
4451 }
4452
4453 /*removing empty spaces*/
4454 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4455
4456 /*no argument followed by spaces*/
4457 if ('\0' == *inPtr)
4458 {
4459 return -EINVAL;
4460 }
4461
4462 /* find the length of data */
4463 dataEnd = inPtr;
4464 while(('\0' != *dataEnd) )
4465 {
4466 dataEnd++;
4467 ++(*pCckmIeLen);
4468 }
4469 if ( *pCckmIeLen <= 0) return -EINVAL;
4470
4471 /* Allocate the number of bytes based on the number of input characters
4472 whether it is even or odd.
4473 if the number of input characters are even, then we need N/2 byte.
4474 if the number of input characters are odd, then we need do (N+1)/2 to
4475 compensate rounding off.
4476 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4477 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4478 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4479 if (NULL == *pCckmIe)
4480 {
4481 hddLog(VOS_TRACE_LEVEL_FATAL,
4482 "%s: vos_mem_alloc failed ", __func__);
4483 return -EINVAL;
4484 }
4485 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4486 /* the buffer received from the upper layer is character buffer,
4487 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4488 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4489 and f0 in 3rd location */
4490 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4491 {
4492 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4493 (*pCckmIe)[i++] = tempByte;
4494 }
4495 *pCckmIeLen = i;
4496
4497 return VOS_STATUS_SUCCESS;
4498}
4499#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4500
Jeff Johnson295189b2012-06-20 16:38:30 -07004501/**---------------------------------------------------------------------------
4502
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004503 \brief hdd_is_valid_mac_address() - Validate MAC address
4504
4505 This function validates whether the given MAC address is valid or not
4506 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4507 where X is the hexa decimal digit character and separated by ':'
4508 This algorithm works even if MAC address is not separated by ':'
4509
4510 This code checks given input string mac contains exactly 12 hexadecimal digits.
4511 and a separator colon : appears in the input string only after
4512 an even number of hex digits.
4513
4514 \param - pMacAddr pointer to the input MAC address
4515 \return - 1 for valid and 0 for invalid
4516
4517 --------------------------------------------------------------------------*/
4518
4519v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4520{
4521 int xdigit = 0;
4522 int separator = 0;
4523 while (*pMacAddr)
4524 {
4525 if (isxdigit(*pMacAddr))
4526 {
4527 xdigit++;
4528 }
4529 else if (':' == *pMacAddr)
4530 {
4531 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4532 break;
4533
4534 ++separator;
4535 }
4536 else
4537 {
4538 separator = -1;
4539 /* Invalid MAC found */
4540 return 0;
4541 }
4542 ++pMacAddr;
4543 }
4544 return (xdigit == 12 && (separator == 5 || separator == 0));
4545}
4546
4547/**---------------------------------------------------------------------------
4548
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 \brief hdd_open() - HDD Open function
4550
4551 This is called in response to ifconfig up
4552
4553 \param - dev Pointer to net_device structure
4554
4555 \return - 0 for success non-zero for failure
4556
4557 --------------------------------------------------------------------------*/
4558int hdd_open (struct net_device *dev)
4559{
4560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4561 hdd_context_t *pHddCtx;
4562 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4563 VOS_STATUS status;
4564 v_BOOL_t in_standby = TRUE;
4565
4566 if (NULL == pAdapter)
4567 {
4568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004569 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 return -ENODEV;
4571 }
4572
4573 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4574 if (NULL == pHddCtx)
4575 {
4576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004577 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004578 return -ENODEV;
4579 }
4580
4581 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4582 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4583 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004584 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4585 {
4586 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304587 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004588 in_standby = FALSE;
4589 break;
4590 }
4591 else
4592 {
4593 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4594 pAdapterNode = pNext;
4595 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004596 }
4597
4598 if (TRUE == in_standby)
4599 {
4600 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4601 {
4602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4603 "wlan out of power save", __func__);
4604 return -EINVAL;
4605 }
4606 }
4607
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004608 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004609 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4610 {
4611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004612 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 /* Enable TX queues only when we are connected */
4614 netif_tx_start_all_queues(dev);
4615 }
4616
4617 return 0;
4618}
4619
4620int hdd_mon_open (struct net_device *dev)
4621{
4622 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4623
4624 if(pAdapter == NULL) {
4625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004626 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004627 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004628 }
4629
4630 netif_start_queue(dev);
4631
4632 return 0;
4633}
4634/**---------------------------------------------------------------------------
4635
4636 \brief hdd_stop() - HDD stop function
4637
4638 This is called in response to ifconfig down
4639
4640 \param - dev Pointer to net_device structure
4641
4642 \return - 0 for success non-zero for failure
4643
4644 --------------------------------------------------------------------------*/
4645
4646int hdd_stop (struct net_device *dev)
4647{
4648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4649 hdd_context_t *pHddCtx;
4650 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4651 VOS_STATUS status;
4652 v_BOOL_t enter_standby = TRUE;
4653
4654 ENTER();
4655
4656 if (NULL == pAdapter)
4657 {
4658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004659 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 return -ENODEV;
4661 }
4662
4663 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4664 if (NULL == pHddCtx)
4665 {
4666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004667 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004668 return -ENODEV;
4669 }
4670
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004671 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4673 netif_tx_disable(pAdapter->dev);
4674 netif_carrier_off(pAdapter->dev);
4675
4676
4677 /* SoftAP ifaces should never go in power save mode
4678 making sure same here. */
4679 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4680 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004681 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004682 )
4683 {
4684 /* SoftAP mode, so return from here */
4685 EXIT();
4686 return 0;
4687 }
4688
4689 /* Find if any iface is up then
4690 if any iface is up then can't put device to sleep/ power save mode. */
4691 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4692 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4693 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004694 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4695 {
4696 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304697 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004698 enter_standby = FALSE;
4699 break;
4700 }
4701 else
4702 {
4703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4704 pAdapterNode = pNext;
4705 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004706 }
4707
4708 if (TRUE == enter_standby)
4709 {
4710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4711 "entering standby", __func__);
4712 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4713 {
4714 /*log and return success*/
4715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4716 "wlan in power save", __func__);
4717 }
4718 }
4719
4720 EXIT();
4721 return 0;
4722}
4723
4724/**---------------------------------------------------------------------------
4725
4726 \brief hdd_uninit() - HDD uninit function
4727
4728 This is called during the netdev unregister to uninitialize all data
4729associated with the device
4730
4731 \param - dev Pointer to net_device structure
4732
4733 \return - void
4734
4735 --------------------------------------------------------------------------*/
4736static void hdd_uninit (struct net_device *dev)
4737{
4738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4739
4740 ENTER();
4741
4742 do
4743 {
4744 if (NULL == pAdapter)
4745 {
4746 hddLog(VOS_TRACE_LEVEL_FATAL,
4747 "%s: NULL pAdapter", __func__);
4748 break;
4749 }
4750
4751 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4752 {
4753 hddLog(VOS_TRACE_LEVEL_FATAL,
4754 "%s: Invalid magic", __func__);
4755 break;
4756 }
4757
4758 if (NULL == pAdapter->pHddCtx)
4759 {
4760 hddLog(VOS_TRACE_LEVEL_FATAL,
4761 "%s: NULL pHddCtx", __func__);
4762 break;
4763 }
4764
4765 if (dev != pAdapter->dev)
4766 {
4767 hddLog(VOS_TRACE_LEVEL_FATAL,
4768 "%s: Invalid device reference", __func__);
4769 /* we haven't validated all cases so let this go for now */
4770 }
4771
4772 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4773
4774 /* after uninit our adapter structure will no longer be valid */
4775 pAdapter->dev = NULL;
4776 pAdapter->magic = 0;
4777 } while (0);
4778
4779 EXIT();
4780}
4781
4782/**---------------------------------------------------------------------------
4783
4784 \brief hdd_release_firmware() -
4785
4786 This function calls the release firmware API to free the firmware buffer.
4787
4788 \param - pFileName Pointer to the File Name.
4789 pCtx - Pointer to the adapter .
4790
4791
4792 \return - 0 for success, non zero for failure
4793
4794 --------------------------------------------------------------------------*/
4795
4796VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4797{
4798 VOS_STATUS status = VOS_STATUS_SUCCESS;
4799 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4800 ENTER();
4801
4802
4803 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4804
4805 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4806
4807 if(pHddCtx->fw) {
4808 release_firmware(pHddCtx->fw);
4809 pHddCtx->fw = NULL;
4810 }
4811 else
4812 status = VOS_STATUS_E_FAILURE;
4813 }
4814 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
4815 if(pHddCtx->nv) {
4816 release_firmware(pHddCtx->nv);
4817 pHddCtx->nv = NULL;
4818 }
4819 else
4820 status = VOS_STATUS_E_FAILURE;
4821
4822 }
4823
4824 EXIT();
4825 return status;
4826}
4827
4828/**---------------------------------------------------------------------------
4829
4830 \brief hdd_request_firmware() -
4831
4832 This function reads the firmware file using the request firmware
4833 API and returns the the firmware data and the firmware file size.
4834
4835 \param - pfileName - Pointer to the file name.
4836 - pCtx - Pointer to the adapter .
4837 - ppfw_data - Pointer to the pointer of the firmware data.
4838 - pSize - Pointer to the file size.
4839
4840 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
4841
4842 --------------------------------------------------------------------------*/
4843
4844
4845VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
4846{
4847 int status;
4848 VOS_STATUS retval = VOS_STATUS_SUCCESS;
4849 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4850 ENTER();
4851
4852 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
4853
4854 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
4855
4856 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4857 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
4858 __func__, pfileName);
4859 retval = VOS_STATUS_E_FAILURE;
4860 }
4861
4862 else {
4863 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
4864 *pSize = pHddCtx->fw->size;
4865 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
4866 __func__, *pSize);
4867 }
4868 }
4869 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
4870
4871 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
4872
4873 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
4874 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
4875 __func__, pfileName);
4876 retval = VOS_STATUS_E_FAILURE;
4877 }
4878
4879 else {
4880 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
4881 *pSize = pHddCtx->nv->size;
4882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
4883 __func__, *pSize);
4884 }
4885 }
4886
4887 EXIT();
4888 return retval;
4889}
4890/**---------------------------------------------------------------------------
4891 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
4892
4893 This is the function invoked by SME to inform the result of a full power
4894 request issued by HDD
4895
4896 \param - callbackcontext - Pointer to cookie
4897 status - result of request
4898
4899 \return - None
4900
4901--------------------------------------------------------------------------*/
4902void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
4903{
4904 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
4905
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004906 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004907 if(&pHddCtx->full_pwr_comp_var)
4908 {
4909 complete(&pHddCtx->full_pwr_comp_var);
4910 }
4911}
4912
4913/**---------------------------------------------------------------------------
4914
4915 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
4916
4917 This is the function invoked by SME to inform the result of BMPS
4918 request issued by HDD
4919
4920 \param - callbackcontext - Pointer to cookie
4921 status - result of request
4922
4923 \return - None
4924
4925--------------------------------------------------------------------------*/
4926void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
4927{
4928
4929 struct completion *completion_var = (struct completion*) callbackContext;
4930
Arif Hussain6d2a3322013-11-17 19:50:10 -08004931 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 if(completion_var != NULL)
4933 {
4934 complete(completion_var);
4935 }
4936}
4937
4938/**---------------------------------------------------------------------------
4939
4940 \brief hdd_get_cfg_file_size() -
4941
4942 This function reads the configuration file using the request firmware
4943 API and returns the configuration file size.
4944
4945 \param - pCtx - Pointer to the adapter .
4946 - pFileName - Pointer to the file name.
4947 - pBufSize - Pointer to the buffer size.
4948
4949 \return - 0 for success, non zero for failure
4950
4951 --------------------------------------------------------------------------*/
4952
4953VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
4954{
4955 int status;
4956 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4957
4958 ENTER();
4959
4960 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
4961
4962 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4963 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
4964 status = VOS_STATUS_E_FAILURE;
4965 }
4966 else {
4967 *pBufSize = pHddCtx->fw->size;
4968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
4969 release_firmware(pHddCtx->fw);
4970 pHddCtx->fw = NULL;
4971 }
4972
4973 EXIT();
4974 return VOS_STATUS_SUCCESS;
4975}
4976
4977/**---------------------------------------------------------------------------
4978
4979 \brief hdd_read_cfg_file() -
4980
4981 This function reads the configuration file using the request firmware
4982 API and returns the cfg data and the buffer size of the configuration file.
4983
4984 \param - pCtx - Pointer to the adapter .
4985 - pFileName - Pointer to the file name.
4986 - pBuffer - Pointer to the data buffer.
4987 - pBufSize - Pointer to the buffer size.
4988
4989 \return - 0 for success, non zero for failure
4990
4991 --------------------------------------------------------------------------*/
4992
4993VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
4994 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
4995{
4996 int status;
4997 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4998
4999 ENTER();
5000
5001 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5002
5003 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5004 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5005 return VOS_STATUS_E_FAILURE;
5006 }
5007 else {
5008 if(*pBufSize != pHddCtx->fw->size) {
5009 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5010 "file size", __func__);
5011 release_firmware(pHddCtx->fw);
5012 pHddCtx->fw = NULL;
5013 return VOS_STATUS_E_FAILURE;
5014 }
5015 else {
5016 if(pBuffer) {
5017 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5018 }
5019 release_firmware(pHddCtx->fw);
5020 pHddCtx->fw = NULL;
5021 }
5022 }
5023
5024 EXIT();
5025
5026 return VOS_STATUS_SUCCESS;
5027}
5028
5029/**---------------------------------------------------------------------------
5030
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 \brief hdd_set_mac_address() -
5032
5033 This function sets the user specified mac address using
5034 the command ifconfig wlanX hw ether <mac adress>.
5035
5036 \param - dev - Pointer to the net device.
5037 - addr - Pointer to the sockaddr.
5038 \return - 0 for success, non zero for failure
5039
5040 --------------------------------------------------------------------------*/
5041
5042static int hdd_set_mac_address(struct net_device *dev, void *addr)
5043{
5044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5045 struct sockaddr *psta_mac_addr = addr;
5046 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5047
5048 ENTER();
5049
5050 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5051
5052#ifdef HDD_SESSIONIZE
5053 // set the MAC address though the STA ID CFG.
5054 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5055 (v_U8_t *)&pAdapter->macAddressCurrent,
5056 sizeof( pAdapter->macAddressCurrent ),
5057 hdd_set_mac_addr_cb, VOS_FALSE );
5058#endif
5059
5060 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5061
5062 EXIT();
5063 return halStatus;
5064}
5065
5066tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5067{
5068 int i;
5069 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5070 {
5071 if( 0 == (pHddCtx->cfg_ini->intfAddrMask >> i))
5072 break;
5073 }
5074
5075 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5076 return NULL;
5077
5078 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5079 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5080}
5081
5082void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5083{
5084 int i;
5085 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5086 {
5087 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5088 {
5089 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5090 break;
5091 }
5092 }
5093 return;
5094}
5095
5096#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5097 static struct net_device_ops wlan_drv_ops = {
5098 .ndo_open = hdd_open,
5099 .ndo_stop = hdd_stop,
5100 .ndo_uninit = hdd_uninit,
5101 .ndo_start_xmit = hdd_hard_start_xmit,
5102 .ndo_tx_timeout = hdd_tx_timeout,
5103 .ndo_get_stats = hdd_stats,
5104 .ndo_do_ioctl = hdd_ioctl,
5105 .ndo_set_mac_address = hdd_set_mac_address,
5106 .ndo_select_queue = hdd_select_queue,
5107#ifdef WLAN_FEATURE_PACKET_FILTERING
5108#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5109 .ndo_set_rx_mode = hdd_set_multicast_list,
5110#else
5111 .ndo_set_multicast_list = hdd_set_multicast_list,
5112#endif //LINUX_VERSION_CODE
5113#endif
5114 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005115 static struct net_device_ops wlan_mon_drv_ops = {
5116 .ndo_open = hdd_mon_open,
5117 .ndo_stop = hdd_stop,
5118 .ndo_uninit = hdd_uninit,
5119 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5120 .ndo_tx_timeout = hdd_tx_timeout,
5121 .ndo_get_stats = hdd_stats,
5122 .ndo_do_ioctl = hdd_ioctl,
5123 .ndo_set_mac_address = hdd_set_mac_address,
5124 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005125
5126#endif
5127
5128void hdd_set_station_ops( struct net_device *pWlanDev )
5129{
5130#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005131 pWlanDev->netdev_ops = &wlan_drv_ops;
5132#else
5133 pWlanDev->open = hdd_open;
5134 pWlanDev->stop = hdd_stop;
5135 pWlanDev->uninit = hdd_uninit;
5136 pWlanDev->hard_start_xmit = NULL;
5137 pWlanDev->tx_timeout = hdd_tx_timeout;
5138 pWlanDev->get_stats = hdd_stats;
5139 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 pWlanDev->set_mac_address = hdd_set_mac_address;
5141#endif
5142}
5143
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005144static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005145{
5146 struct net_device *pWlanDev = NULL;
5147 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005148 /*
5149 * cfg80211 initialization and registration....
5150 */
5151 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5152
Jeff Johnson295189b2012-06-20 16:38:30 -07005153 if(pWlanDev != NULL)
5154 {
5155
5156 //Save the pointer to the net_device in the HDD adapter
5157 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5158
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5160
5161 pAdapter->dev = pWlanDev;
5162 pAdapter->pHddCtx = pHddCtx;
5163 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5164
5165 init_completion(&pAdapter->session_open_comp_var);
5166 init_completion(&pAdapter->session_close_comp_var);
5167 init_completion(&pAdapter->disconnect_comp_var);
5168 init_completion(&pAdapter->linkup_event_var);
5169 init_completion(&pAdapter->cancel_rem_on_chan_var);
5170 init_completion(&pAdapter->rem_on_chan_ready_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07005171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5172 init_completion(&pAdapter->offchannel_tx_event);
5173#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005174 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005175#ifdef FEATURE_WLAN_TDLS
5176 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005177 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005178 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305179 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005180#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 init_completion(&pHddCtx->mc_sus_event_var);
5182 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305183 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005184 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005185 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005186
Rajeev79dbe4c2013-10-05 11:03:42 +05305187#ifdef FEATURE_WLAN_BATCH_SCAN
5188 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5189 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5190 pAdapter->pBatchScanRsp = NULL;
5191 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005192 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Rajeev Kumarb20d8c82013-11-18 20:04:20 -08005193 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305194 mutex_init(&pAdapter->hdd_batch_scan_lock);
5195#endif
5196
Jeff Johnson295189b2012-06-20 16:38:30 -07005197 pAdapter->isLinkUpSvcNeeded = FALSE;
5198 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5199 //Init the net_device structure
5200 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5201
5202 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5203 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5204 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5205 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5206
5207 hdd_set_station_ops( pAdapter->dev );
5208
5209 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5211 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5212 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 /* set pWlanDev's parent to underlying device */
5214 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5215 }
5216
5217 return pAdapter;
5218}
5219
5220VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5221{
5222 struct net_device *pWlanDev = pAdapter->dev;
5223 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5224 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5225 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5226
5227 if( rtnl_lock_held )
5228 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005229 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5231 {
5232 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5233 return VOS_STATUS_E_FAILURE;
5234 }
5235 }
5236 if (register_netdevice(pWlanDev))
5237 {
5238 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5239 return VOS_STATUS_E_FAILURE;
5240 }
5241 }
5242 else
5243 {
5244 if(register_netdev(pWlanDev))
5245 {
5246 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5247 return VOS_STATUS_E_FAILURE;
5248 }
5249 }
5250 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5251
5252 return VOS_STATUS_SUCCESS;
5253}
5254
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005255static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005256{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005257 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005258
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005259 if (NULL == pAdapter)
5260 {
5261 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5262 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005264
5265 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5266 {
5267 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5268 return eHAL_STATUS_NOT_INITIALIZED;
5269 }
5270
5271 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5272
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005273#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005274 /* need to make sure all of our scheduled work has completed.
5275 * This callback is called from MC thread context, so it is safe to
5276 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005277 *
5278 * Even though this is called from MC thread context, if there is a faulty
5279 * work item in the system, that can hang this call forever. So flushing
5280 * this global work queue is not safe; and now we make sure that
5281 * individual work queues are stopped correctly. But the cancel work queue
5282 * is a GPL only API, so the proprietary version of the driver would still
5283 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005284 */
5285 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005286#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005287
5288 /* We can be blocked while waiting for scheduled work to be
5289 * flushed, and the adapter structure can potentially be freed, in
5290 * which case the magic will have been reset. So make sure the
5291 * magic is still good, and hence the adapter structure is still
5292 * valid, before signaling completion */
5293 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5294 {
5295 complete(&pAdapter->session_close_comp_var);
5296 }
5297
Jeff Johnson295189b2012-06-20 16:38:30 -07005298 return eHAL_STATUS_SUCCESS;
5299}
5300
5301VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5302{
5303 struct net_device *pWlanDev = pAdapter->dev;
5304 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5305 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5306 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5307 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5308 int rc = 0;
5309
5310 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005311 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005312 //Open a SME session for future operation
5313 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005314 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005315 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5316 {
5317 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005318 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 halStatus, halStatus );
5320 status = VOS_STATUS_E_FAILURE;
5321 goto error_sme_open;
5322 }
5323
5324 //Block on a completion variable. Can't wait forever though.
5325 rc = wait_for_completion_interruptible_timeout(
5326 &pAdapter->session_open_comp_var,
5327 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
5328 if (!rc)
5329 {
5330 hddLog(VOS_TRACE_LEVEL_FATAL,
5331 "Session is not opened within timeout period code %08d", rc );
5332 status = VOS_STATUS_E_FAILURE;
5333 goto error_sme_open;
5334 }
5335
5336 // Register wireless extensions
5337 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5338 {
5339 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005340 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005341 halStatus, halStatus );
5342 status = VOS_STATUS_E_FAILURE;
5343 goto error_register_wext;
5344 }
5345 //Safe to register the hard_start_xmit function again
5346#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5347 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5348#else
5349 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5350#endif
5351
5352 //Set the Connection State to Not Connected
5353 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5354
5355 //Set the default operation channel
5356 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5357
5358 /* Make the default Auth Type as OPEN*/
5359 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5360
5361 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5362 {
5363 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005364 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 status, status );
5366 goto error_init_txrx;
5367 }
5368
5369 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5370
5371 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5372 {
5373 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005374 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 status, status );
5376 goto error_wmm_init;
5377 }
5378
5379 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5380
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005381#ifdef FEATURE_WLAN_TDLS
5382 if(0 != wlan_hdd_tdls_init(pAdapter))
5383 {
5384 status = VOS_STATUS_E_FAILURE;
5385 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5386 goto error_tdls_init;
5387 }
5388 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5389#endif
5390
Jeff Johnson295189b2012-06-20 16:38:30 -07005391 return VOS_STATUS_SUCCESS;
5392
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005393#ifdef FEATURE_WLAN_TDLS
5394error_tdls_init:
5395 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5396 hdd_wmm_adapter_close(pAdapter);
5397#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005398error_wmm_init:
5399 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5400 hdd_deinit_tx_rx(pAdapter);
5401error_init_txrx:
5402 hdd_UnregisterWext(pWlanDev);
5403error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005404 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005405 {
5406 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005407 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005408 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005409 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005410 {
5411 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005412 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005413 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005414 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 }
5416}
5417error_sme_open:
5418 return status;
5419}
5420
Jeff Johnson295189b2012-06-20 16:38:30 -07005421void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5422{
5423 hdd_cfg80211_state_t *cfgState;
5424
5425 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5426
5427 if( NULL != cfgState->buf )
5428 {
5429 int rc;
5430 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5431 rc = wait_for_completion_interruptible_timeout(
5432 &pAdapter->tx_action_cnf_event,
5433 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
5434 if(!rc)
5435 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005437 ("ERROR: HDD Wait for Action Confirmation Failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 }
5439 }
5440 return;
5441}
Jeff Johnson295189b2012-06-20 16:38:30 -07005442
5443void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5444{
5445 ENTER();
5446 switch ( pAdapter->device_mode )
5447 {
5448 case WLAN_HDD_INFRA_STATION:
5449 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005450 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 {
5452 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5453 {
5454 hdd_deinit_tx_rx( pAdapter );
5455 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5456 }
5457
5458 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5459 {
5460 hdd_wmm_adapter_close( pAdapter );
5461 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5462 }
5463
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005465#ifdef FEATURE_WLAN_TDLS
5466 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5467 {
5468 wlan_hdd_tdls_exit(pAdapter);
5469 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5470 }
5471#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005472
5473 break;
5474 }
5475
5476 case WLAN_HDD_SOFTAP:
5477 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305479
5480 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5481 {
5482 hdd_wmm_adapter_close( pAdapter );
5483 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5484 }
5485
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005487
5488 hdd_unregister_hostapd(pAdapter);
5489 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 break;
5492 }
5493
5494 case WLAN_HDD_MONITOR:
5495 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5498 {
5499 hdd_deinit_tx_rx( pAdapter );
5500 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 if(NULL != pAdapterforTx)
5503 {
5504 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 break;
5507 }
5508
5509
5510 default:
5511 break;
5512 }
5513
5514 EXIT();
5515}
5516
5517void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5518{
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305519 struct net_device *pWlanDev;
5520
5521 ENTER();
5522 if (NULL == pAdapter)
5523 {
5524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5525 "%s: HDD adapter is Null", __func__);
5526 return;
5527 }
5528
5529 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005530
Rajeev79dbe4c2013-10-05 11:03:42 +05305531#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305532 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5533 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
5534 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5535 )
5536 {
Rajeev79dbe4c2013-10-05 11:03:42 +05305537 tHddBatchScanRsp *pNode;
5538 tHddBatchScanRsp *pPrev;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305539 pNode = pAdapter->pBatchScanRsp;
5540 while (pNode)
Rajeev79dbe4c2013-10-05 11:03:42 +05305541 {
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305542 pPrev = pNode;
5543 pNode = pNode->pNext;
5544 vos_mem_free((v_VOID_t * )pPrev);
5545 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05305546 }
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305547 pAdapter->pBatchScanRsp = NULL;
5548 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305549#endif
5550
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5552 if( rtnl_held )
5553 {
5554 unregister_netdevice(pWlanDev);
5555 }
5556 else
5557 {
5558 unregister_netdev(pWlanDev);
5559 }
5560 // note that the pAdapter is no longer valid at this point
5561 // since the memory has been reclaimed
5562 }
5563
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305564 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005565}
5566
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005567void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5568{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305569 VOS_STATUS status;
5570 hdd_adapter_t *pAdapter = NULL;
5571 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005572
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305573 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005574
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305575 /*loop through all adapters.*/
5576 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005577 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305578 pAdapter = pAdapterNode->pAdapter;
5579 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5580 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005581
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305582 { // we skip this registration for modes other than STA and P2P client modes.
5583 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5584 pAdapterNode = pNext;
5585 continue;
5586 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005587
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305588 //Apply Dynamic DTIM For P2P
5589 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5590 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5591 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5592 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5593 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5594 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5595 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5596 (eConnectionState_Associated ==
5597 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5598 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5599 {
5600 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005601
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305602 powerRequest.uIgnoreDTIM = 1;
5603 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5604
5605 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5606 {
5607 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5608 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5609 }
5610 else
5611 {
5612 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5613 }
5614
5615 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5616 * specified during Enter/Exit BMPS when LCD off*/
5617 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5618 NULL, eANI_BOOLEAN_FALSE);
5619 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5620 NULL, eANI_BOOLEAN_FALSE);
5621
5622 /* switch to the DTIM specified in cfg.ini */
5623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5624 "Switch to DTIM %d", powerRequest.uListenInterval);
5625 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5626 break;
5627
5628 }
5629
5630 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5631 pAdapterNode = pNext;
5632 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005633}
5634
5635void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5636{
5637 /*Switch back to DTIM 1*/
5638 tSirSetPowerParamsReq powerRequest = { 0 };
5639
5640 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5641 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005642 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005643
5644 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5645 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5646 NULL, eANI_BOOLEAN_FALSE);
5647 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5648 NULL, eANI_BOOLEAN_FALSE);
5649
5650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5651 "Switch to DTIM%d",powerRequest.uListenInterval);
5652 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5653
5654}
5655
Jeff Johnson295189b2012-06-20 16:38:30 -07005656VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5657{
5658 VOS_STATUS status = VOS_STATUS_SUCCESS;
5659
5660 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5661 {
5662 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5663 }
5664
5665 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5666 {
5667 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5668 }
5669
5670 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5671 {
5672 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5673 }
5674
5675 return status;
5676}
5677
5678VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5679{
5680 hdd_adapter_t *pAdapter = NULL;
5681 eHalStatus halStatus;
5682 VOS_STATUS status = VOS_STATUS_E_INVAL;
5683 v_BOOL_t disableBmps = FALSE;
5684 v_BOOL_t disableImps = FALSE;
5685
5686 switch(session_type)
5687 {
5688 case WLAN_HDD_INFRA_STATION:
5689 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 case WLAN_HDD_P2P_CLIENT:
5691 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 //Exit BMPS -> Is Sta/P2P Client is already connected
5693 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5694 if((NULL != pAdapter)&&
5695 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5696 {
5697 disableBmps = TRUE;
5698 }
5699
5700 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5701 if((NULL != pAdapter)&&
5702 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5703 {
5704 disableBmps = TRUE;
5705 }
5706
5707 //Exit both Bmps and Imps incase of Go/SAP Mode
5708 if((WLAN_HDD_SOFTAP == session_type) ||
5709 (WLAN_HDD_P2P_GO == session_type))
5710 {
5711 disableBmps = TRUE;
5712 disableImps = TRUE;
5713 }
5714
5715 if(TRUE == disableImps)
5716 {
5717 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5718 {
5719 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5720 }
5721 }
5722
5723 if(TRUE == disableBmps)
5724 {
5725 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5726 {
5727 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5728
5729 if(eHAL_STATUS_SUCCESS != halStatus)
5730 {
5731 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005732 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 VOS_ASSERT(0);
5734 return status;
5735 }
5736 }
5737
5738 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5739 {
5740 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5741
5742 if(eHAL_STATUS_SUCCESS != halStatus)
5743 {
5744 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005745 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 VOS_ASSERT(0);
5747 return status;
5748 }
5749 }
5750 }
5751
5752 if((TRUE == disableBmps) ||
5753 (TRUE == disableImps))
5754 {
5755 /* Now, get the chip into Full Power now */
5756 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5757 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5758 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5759
5760 if(halStatus != eHAL_STATUS_SUCCESS)
5761 {
5762 if(halStatus == eHAL_STATUS_PMC_PENDING)
5763 {
5764 //Block on a completion variable. Can't wait forever though
5765 wait_for_completion_interruptible_timeout(
5766 &pHddCtx->full_pwr_comp_var, msecs_to_jiffies(1000));
5767 }
5768 else
5769 {
5770 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005771 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 VOS_ASSERT(0);
5773 return status;
5774 }
5775 }
5776
5777 status = VOS_STATUS_SUCCESS;
5778 }
5779
5780 break;
5781 }
5782 return status;
5783}
5784
5785hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005786 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 tANI_U8 rtnl_held )
5788{
5789 hdd_adapter_t *pAdapter = NULL;
5790 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5791 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5792 VOS_STATUS exitbmpsStatus;
5793
Arif Hussain6d2a3322013-11-17 19:50:10 -08005794 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005795
5796 //Disable BMPS incase of Concurrency
5797 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
5798
5799 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
5800 {
5801 //Fail to Exit BMPS
5802 VOS_ASSERT(0);
5803 return NULL;
5804 }
5805
5806 switch(session_type)
5807 {
5808 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005810 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 {
5812 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5813
5814 if( NULL == pAdapter )
5815 return NULL;
5816
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305817#ifdef FEATURE_WLAN_TDLS
5818 /* A Mutex Lock is introduced while changing/initializing the mode to
5819 * protect the concurrent access for the Adapters by TDLS module.
5820 */
5821 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
5822 {
5823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5824 "%s: unable to lock list", __func__);
5825 return NULL;
5826 }
5827#endif
5828
Jeff Johnsone7245742012-09-05 17:12:55 -07005829 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
5830 NL80211_IFTYPE_P2P_CLIENT:
5831 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07005832
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305834#ifdef FEATURE_WLAN_TDLS
5835 mutex_unlock(&pHddCtx->tdls_lock);
5836#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05305837
5838 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005839 if( VOS_STATUS_SUCCESS != status )
5840 goto err_free_netdev;
5841
5842 status = hdd_register_interface( pAdapter, rtnl_held );
5843 if( VOS_STATUS_SUCCESS != status )
5844 {
5845 hdd_deinit_adapter(pHddCtx, pAdapter);
5846 goto err_free_netdev;
5847 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305848
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05305849 // Workqueue which gets scheduled in IPv4 notification callback.
5850 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
5851
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305852#ifdef WLAN_NS_OFFLOAD
5853 // Workqueue which gets scheduled in IPv6 notification callback.
5854 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
5855#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 //Stop the Interface TX queue.
5857 netif_tx_disable(pAdapter->dev);
5858 //netif_tx_disable(pWlanDev);
5859 netif_carrier_off(pAdapter->dev);
5860
5861 break;
5862 }
5863
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 case WLAN_HDD_SOFTAP:
5866 {
5867 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
5868 if( NULL == pAdapter )
5869 return NULL;
5870
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
5872 NL80211_IFTYPE_AP:
5873 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 pAdapter->device_mode = session_type;
5875
5876 status = hdd_init_ap_mode(pAdapter);
5877 if( VOS_STATUS_SUCCESS != status )
5878 goto err_free_netdev;
5879
5880 status = hdd_register_hostapd( pAdapter, rtnl_held );
5881 if( VOS_STATUS_SUCCESS != status )
5882 {
5883 hdd_deinit_adapter(pHddCtx, pAdapter);
5884 goto err_free_netdev;
5885 }
5886
5887 netif_tx_disable(pAdapter->dev);
5888 netif_carrier_off(pAdapter->dev);
5889
5890 hdd_set_conparam( 1 );
5891 break;
5892 }
5893 case WLAN_HDD_MONITOR:
5894 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5896 if( NULL == pAdapter )
5897 return NULL;
5898
5899 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
5900 pAdapter->device_mode = session_type;
5901 status = hdd_register_interface( pAdapter, rtnl_held );
5902#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
5903 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
5904#else
5905 pAdapter->dev->open = hdd_mon_open;
5906 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
5907#endif
5908 hdd_init_tx_rx( pAdapter );
5909 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5910 //Set adapter to be used for data tx. It will use either GO or softap.
5911 pAdapter->sessionCtx.monitor.pAdapterForTx =
5912 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
5914 {
5915 pAdapter->sessionCtx.monitor.pAdapterForTx =
5916 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
5917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 /* This workqueue will be used to transmit management packet over
5919 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005920 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
5921 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
5922 return NULL;
5923 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07005924
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
5926 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 }
5928 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 case WLAN_HDD_FTM:
5930 {
5931 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5932
5933 if( NULL == pAdapter )
5934 return NULL;
5935 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
5936 * message while loading driver in FTM mode. */
5937 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
5938 pAdapter->device_mode = session_type;
5939 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05305940
5941 hdd_init_tx_rx( pAdapter );
5942
5943 //Stop the Interface TX queue.
5944 netif_tx_disable(pAdapter->dev);
5945 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 }
5947 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 default:
5949 {
5950 VOS_ASSERT(0);
5951 return NULL;
5952 }
5953 }
5954
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 if( VOS_STATUS_SUCCESS == status )
5956 {
5957 //Add it to the hdd's session list.
5958 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
5959 if( NULL == pHddAdapterNode )
5960 {
5961 status = VOS_STATUS_E_NOMEM;
5962 }
5963 else
5964 {
5965 pHddAdapterNode->pAdapter = pAdapter;
5966 status = hdd_add_adapter_back ( pHddCtx,
5967 pHddAdapterNode );
5968 }
5969 }
5970
5971 if( VOS_STATUS_SUCCESS != status )
5972 {
5973 if( NULL != pAdapter )
5974 {
5975 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
5976 pAdapter = NULL;
5977 }
5978 if( NULL != pHddAdapterNode )
5979 {
5980 vos_mem_free( pHddAdapterNode );
5981 }
5982
5983 goto resume_bmps;
5984 }
5985
5986 if(VOS_STATUS_SUCCESS == status)
5987 {
5988 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
5989
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07005990 //Initialize the WoWL service
5991 if(!hdd_init_wowl(pAdapter))
5992 {
5993 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
5994 goto err_free_netdev;
5995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 return pAdapter;
5998
5999err_free_netdev:
6000 free_netdev(pAdapter->dev);
6001 wlan_hdd_release_intf_addr( pHddCtx,
6002 pAdapter->macAddressCurrent.bytes );
6003
6004resume_bmps:
6005 //If bmps disabled enable it
6006 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6007 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306008 if (pHddCtx->hdd_wlan_suspended)
6009 {
6010 hdd_set_pwrparams(pHddCtx);
6011 }
6012 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 }
6014 return NULL;
6015}
6016
6017VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6018 tANI_U8 rtnl_held )
6019{
6020 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6021 VOS_STATUS status;
6022
6023 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6024 if( VOS_STATUS_SUCCESS != status )
6025 return status;
6026
6027 while ( pCurrent->pAdapter != pAdapter )
6028 {
6029 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6030 if( VOS_STATUS_SUCCESS != status )
6031 break;
6032
6033 pCurrent = pNext;
6034 }
6035 pAdapterNode = pCurrent;
6036 if( VOS_STATUS_SUCCESS == status )
6037 {
6038 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6039 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306040
6041#ifdef FEATURE_WLAN_TDLS
6042
6043 /* A Mutex Lock is introduced while changing/initializing the mode to
6044 * protect the concurrent access for the Adapters by TDLS module.
6045 */
6046 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
6047 {
6048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6049 "%s: unable to lock list", __func__);
6050 return VOS_STATUS_E_FAILURE;
6051 }
6052#endif
6053
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 hdd_remove_adapter( pHddCtx, pAdapterNode );
6055 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006056 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006057
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306058#ifdef FEATURE_WLAN_TDLS
6059 mutex_unlock(&pHddCtx->tdls_lock);
6060#endif
6061
Jeff Johnson295189b2012-06-20 16:38:30 -07006062
6063 /* If there is a single session of STA/P2P client, re-enable BMPS */
6064 if ((!vos_concurrent_sessions_running()) &&
6065 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6066 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6067 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306068 if (pHddCtx->hdd_wlan_suspended)
6069 {
6070 hdd_set_pwrparams(pHddCtx);
6071 }
6072 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 }
6074
6075 return VOS_STATUS_SUCCESS;
6076 }
6077
6078 return VOS_STATUS_E_FAILURE;
6079}
6080
6081VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6082{
6083 hdd_adapter_list_node_t *pHddAdapterNode;
6084 VOS_STATUS status;
6085
6086 ENTER();
6087
6088 do
6089 {
6090 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6091 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6092 {
6093 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6094 vos_mem_free( pHddAdapterNode );
6095 }
6096 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6097
6098 EXIT();
6099
6100 return VOS_STATUS_SUCCESS;
6101}
6102
6103void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6104{
6105 v_U8_t addIE[1] = {0};
6106
6107 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6108 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6109 eANI_BOOLEAN_FALSE) )
6110 {
6111 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006112 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 }
6114
6115 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6116 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6117 eANI_BOOLEAN_FALSE) )
6118 {
6119 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006120 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006121 }
6122
6123 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6124 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6125 eANI_BOOLEAN_FALSE) )
6126 {
6127 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006128 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 }
6130}
6131
6132VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6133{
6134 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6135 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6136 union iwreq_data wrqu;
6137
6138 ENTER();
6139
6140 switch(pAdapter->device_mode)
6141 {
6142 case WLAN_HDD_INFRA_STATION:
6143 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006144 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6146 {
6147 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6148 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6149 pAdapter->sessionId,
6150 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6151 else
6152 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6153 pAdapter->sessionId,
6154 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6155 //success implies disconnect command got queued up successfully
6156 if(halStatus == eHAL_STATUS_SUCCESS)
6157 {
6158 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
6159 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6160 }
6161 memset(&wrqu, '\0', sizeof(wrqu));
6162 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6163 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6164 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6165 }
6166 else
6167 {
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05306168 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306170#ifdef WLAN_OPEN_SOURCE
6171#ifdef WLAN_NS_OFFLOAD
6172 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6173#endif
6174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006175
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306176#ifdef WLAN_OPEN_SOURCE
6177 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6178#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6180 {
6181 INIT_COMPLETION(pAdapter->session_close_comp_var);
6182 if (eHAL_STATUS_SUCCESS ==
6183 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6184 hdd_smeCloseSessionCallback, pAdapter))
6185 {
6186 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006187 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006188 &pAdapter->session_close_comp_var,
6189 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
6190 }
6191 }
6192
6193 break;
6194
6195 case WLAN_HDD_SOFTAP:
6196 case WLAN_HDD_P2P_GO:
6197 //Any softap specific cleanup here...
6198 mutex_lock(&pHddCtx->sap_lock);
6199 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6200 {
6201 VOS_STATUS status;
6202 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6203
6204 //Stop Bss.
6205 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6206 if (VOS_IS_STATUS_SUCCESS(status))
6207 {
6208 hdd_hostapd_state_t *pHostapdState =
6209 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6210
6211 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6212
6213 if (!VOS_IS_STATUS_SUCCESS(status))
6214 {
6215 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006216 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 }
6218 }
6219 else
6220 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006221 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 }
6223 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6224
6225 if (eHAL_STATUS_FAILURE ==
6226 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6227 0, NULL, eANI_BOOLEAN_FALSE))
6228 {
6229 hddLog(LOGE,
6230 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006231 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 }
6233
6234 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6235 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6236 eANI_BOOLEAN_FALSE) )
6237 {
6238 hddLog(LOGE,
6239 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6240 }
6241
6242 // Reset WNI_CFG_PROBE_RSP Flags
6243 wlan_hdd_reset_prob_rspies(pAdapter);
6244 kfree(pAdapter->sessionCtx.ap.beacon);
6245 pAdapter->sessionCtx.ap.beacon = NULL;
6246 }
6247 mutex_unlock(&pHddCtx->sap_lock);
6248 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006249
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006251#ifdef WLAN_OPEN_SOURCE
6252 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006255
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 default:
6257 break;
6258 }
6259
6260 EXIT();
6261 return VOS_STATUS_SUCCESS;
6262}
6263
6264VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6265{
6266 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6267 VOS_STATUS status;
6268 hdd_adapter_t *pAdapter;
6269
6270 ENTER();
6271
6272 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6273
6274 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6275 {
6276 pAdapter = pAdapterNode->pAdapter;
6277 netif_tx_disable(pAdapter->dev);
6278 netif_carrier_off(pAdapter->dev);
6279
6280 hdd_stop_adapter( pHddCtx, pAdapter );
6281
6282 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6283 pAdapterNode = pNext;
6284 }
6285
6286 EXIT();
6287
6288 return VOS_STATUS_SUCCESS;
6289}
6290
6291VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6292{
6293 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6294 VOS_STATUS status;
6295 hdd_adapter_t *pAdapter;
6296
6297 ENTER();
6298
6299 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6300
6301 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6302 {
6303 pAdapter = pAdapterNode->pAdapter;
6304 netif_tx_disable(pAdapter->dev);
6305 netif_carrier_off(pAdapter->dev);
6306
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006307 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6308
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306310 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6311 {
6312 hdd_wmm_adapter_close( pAdapter );
6313 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6314 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006315
6316 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6317 pAdapterNode = pNext;
6318 }
6319
6320 EXIT();
6321
6322 return VOS_STATUS_SUCCESS;
6323}
6324
6325VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6326{
6327 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6328 VOS_STATUS status;
6329 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306330 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006331
6332 ENTER();
6333
6334 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6335
6336 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6337 {
6338 pAdapter = pAdapterNode->pAdapter;
6339
6340 switch(pAdapter->device_mode)
6341 {
6342 case WLAN_HDD_INFRA_STATION:
6343 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006344 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306345
6346 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6347
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 hdd_init_station_mode(pAdapter);
6349 /* Open the gates for HDD to receive Wext commands */
6350 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006351 pHddCtx->scan_info.mScanPending = FALSE;
6352 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006353
6354 //Trigger the initial scan
6355 hdd_wlan_initial_scan(pAdapter);
6356
6357 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306358 if (eConnectionState_Associated == connState ||
6359 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 {
6361 union iwreq_data wrqu;
6362 memset(&wrqu, '\0', sizeof(wrqu));
6363 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6364 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6365 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006366 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006367
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 /* indicate disconnected event to nl80211 */
6369 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6370 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306372 else if (eConnectionState_Connecting == connState)
6373 {
6374 /*
6375 * Indicate connect failure to supplicant if we were in the
6376 * process of connecting
6377 */
6378 cfg80211_connect_result(pAdapter->dev, NULL,
6379 NULL, 0, NULL, 0,
6380 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6381 GFP_KERNEL);
6382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 break;
6384
6385 case WLAN_HDD_SOFTAP:
6386 /* softAP can handle SSR */
6387 break;
6388
6389 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006392 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 break;
6394
6395 case WLAN_HDD_MONITOR:
6396 /* monitor interface start */
6397 break;
6398 default:
6399 break;
6400 }
6401
6402 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6403 pAdapterNode = pNext;
6404 }
6405
6406 EXIT();
6407
6408 return VOS_STATUS_SUCCESS;
6409}
6410
6411VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6412{
6413 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6414 hdd_adapter_t *pAdapter;
6415 VOS_STATUS status;
6416 v_U32_t roamId;
6417
6418 ENTER();
6419
6420 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6421
6422 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6423 {
6424 pAdapter = pAdapterNode->pAdapter;
6425
6426 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6427 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6428 {
6429 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6430 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6431
6432 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6433 init_completion(&pAdapter->disconnect_comp_var);
6434 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6435 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6436
6437 wait_for_completion_interruptible_timeout(
6438 &pAdapter->disconnect_comp_var,
6439 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6440
6441 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6442 pHddCtx->isAmpAllowed = VOS_FALSE;
6443 sme_RoamConnect(pHddCtx->hHal,
6444 pAdapter->sessionId, &(pWextState->roamProfile),
6445 &roamId);
6446 }
6447
6448 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6449 pAdapterNode = pNext;
6450 }
6451
6452 EXIT();
6453
6454 return VOS_STATUS_SUCCESS;
6455}
6456
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006457void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6458{
6459 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6460 VOS_STATUS status;
6461 hdd_adapter_t *pAdapter;
6462 hdd_station_ctx_t *pHddStaCtx;
6463 hdd_ap_ctx_t *pHddApCtx;
6464 hdd_hostapd_state_t * pHostapdState;
6465 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6466 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6467 const char *p2pMode = "DEV";
6468 const char *ccMode = "Standalone";
6469 int n;
6470
6471 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6472 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6473 {
6474 pAdapter = pAdapterNode->pAdapter;
6475 switch (pAdapter->device_mode) {
6476 case WLAN_HDD_INFRA_STATION:
6477 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6478 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6479 staChannel = pHddStaCtx->conn_info.operationChannel;
6480 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6481 }
6482 break;
6483 case WLAN_HDD_P2P_CLIENT:
6484 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6485 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6486 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6487 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6488 p2pMode = "CLI";
6489 }
6490 break;
6491 case WLAN_HDD_P2P_GO:
6492 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6493 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6494 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6495 p2pChannel = pHddApCtx->operatingChannel;
6496 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6497 }
6498 p2pMode = "GO";
6499 break;
6500 case WLAN_HDD_SOFTAP:
6501 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6502 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6503 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6504 apChannel = pHddApCtx->operatingChannel;
6505 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6506 }
6507 break;
6508 default:
6509 break;
6510 }
6511 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6512 pAdapterNode = pNext;
6513 }
6514 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6515 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6516 }
6517 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6518 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6519 if (p2pChannel > 0) {
6520 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6521 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6522 }
6523 if (apChannel > 0) {
6524 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6525 apChannel, MAC_ADDR_ARRAY(apBssid));
6526 }
6527
6528 if (p2pChannel > 0 && apChannel > 0) {
6529 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6530 }
6531}
6532
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006533bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006534{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006535 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006536}
6537
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006538/* Once SSR is disabled then it cannot be set. */
6539void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006540{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006541 if (HDD_SSR_DISABLED == isSsrRequired)
6542 return;
6543
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 isSsrRequired = value;
6545}
6546
6547VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6548 hdd_adapter_list_node_t** ppAdapterNode)
6549{
6550 VOS_STATUS status;
6551 spin_lock(&pHddCtx->hddAdapters.lock);
6552 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6553 (hdd_list_node_t**) ppAdapterNode );
6554 spin_unlock(&pHddCtx->hddAdapters.lock);
6555 return status;
6556}
6557
6558VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6559 hdd_adapter_list_node_t* pAdapterNode,
6560 hdd_adapter_list_node_t** pNextAdapterNode)
6561{
6562 VOS_STATUS status;
6563 spin_lock(&pHddCtx->hddAdapters.lock);
6564 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6565 (hdd_list_node_t*) pAdapterNode,
6566 (hdd_list_node_t**)pNextAdapterNode );
6567
6568 spin_unlock(&pHddCtx->hddAdapters.lock);
6569 return status;
6570}
6571
6572VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6573 hdd_adapter_list_node_t* pAdapterNode)
6574{
6575 VOS_STATUS status;
6576 spin_lock(&pHddCtx->hddAdapters.lock);
6577 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6578 &pAdapterNode->node );
6579 spin_unlock(&pHddCtx->hddAdapters.lock);
6580 return status;
6581}
6582
6583VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6584 hdd_adapter_list_node_t** ppAdapterNode)
6585{
6586 VOS_STATUS status;
6587 spin_lock(&pHddCtx->hddAdapters.lock);
6588 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6589 (hdd_list_node_t**) ppAdapterNode );
6590 spin_unlock(&pHddCtx->hddAdapters.lock);
6591 return status;
6592}
6593
6594VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6595 hdd_adapter_list_node_t* pAdapterNode)
6596{
6597 VOS_STATUS status;
6598 spin_lock(&pHddCtx->hddAdapters.lock);
6599 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6600 (hdd_list_node_t*) pAdapterNode );
6601 spin_unlock(&pHddCtx->hddAdapters.lock);
6602 return status;
6603}
6604
6605VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6606 hdd_adapter_list_node_t* pAdapterNode)
6607{
6608 VOS_STATUS status;
6609 spin_lock(&pHddCtx->hddAdapters.lock);
6610 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6611 (hdd_list_node_t*) pAdapterNode );
6612 spin_unlock(&pHddCtx->hddAdapters.lock);
6613 return status;
6614}
6615
6616hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6617 tSirMacAddr macAddr )
6618{
6619 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6620 hdd_adapter_t *pAdapter;
6621 VOS_STATUS status;
6622
6623 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6624
6625 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6626 {
6627 pAdapter = pAdapterNode->pAdapter;
6628
6629 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
6630 macAddr, sizeof(tSirMacAddr) ) )
6631 {
6632 return pAdapter;
6633 }
6634 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6635 pAdapterNode = pNext;
6636 }
6637
6638 return NULL;
6639
6640}
6641
6642hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
6643{
6644 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6645 hdd_adapter_t *pAdapter;
6646 VOS_STATUS status;
6647
6648 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6649
6650 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6651 {
6652 pAdapter = pAdapterNode->pAdapter;
6653
6654 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
6655 IFNAMSIZ ) )
6656 {
6657 return pAdapter;
6658 }
6659 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6660 pAdapterNode = pNext;
6661 }
6662
6663 return NULL;
6664
6665}
6666
6667hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
6668{
6669 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6670 hdd_adapter_t *pAdapter;
6671 VOS_STATUS status;
6672
6673 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6674
6675 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6676 {
6677 pAdapter = pAdapterNode->pAdapter;
6678
6679 if( pAdapter && (mode == pAdapter->device_mode) )
6680 {
6681 return pAdapter;
6682 }
6683 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6684 pAdapterNode = pNext;
6685 }
6686
6687 return NULL;
6688
6689}
6690
6691//Remove this function later
6692hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
6693{
6694 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6695 hdd_adapter_t *pAdapter;
6696 VOS_STATUS status;
6697
6698 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6699
6700 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6701 {
6702 pAdapter = pAdapterNode->pAdapter;
6703
6704 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
6705 {
6706 return pAdapter;
6707 }
6708
6709 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6710 pAdapterNode = pNext;
6711 }
6712
6713 return NULL;
6714
6715}
6716
Jeff Johnson295189b2012-06-20 16:38:30 -07006717/**---------------------------------------------------------------------------
6718
6719 \brief hdd_set_monitor_tx_adapter() -
6720
6721 This API initializes the adapter to be used while transmitting on monitor
6722 adapter.
6723
6724 \param - pHddCtx - Pointer to the HDD context.
6725 pAdapter - Adapter that will used for TX. This can be NULL.
6726 \return - None.
6727 --------------------------------------------------------------------------*/
6728void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6729{
6730 hdd_adapter_t *pMonAdapter;
6731
6732 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
6733
6734 if( NULL != pMonAdapter )
6735 {
6736 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
6737 }
6738}
Jeff Johnson295189b2012-06-20 16:38:30 -07006739/**---------------------------------------------------------------------------
6740
6741 \brief hdd_select_queue() -
6742
6743 This API returns the operating channel of the requested device mode
6744
6745 \param - pHddCtx - Pointer to the HDD context.
6746 - mode - Device mode for which operating channel is required
6747 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
6748 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
6749 \return - channel number. "0" id the requested device is not found OR it is not connected.
6750 --------------------------------------------------------------------------*/
6751v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
6752{
6753 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6754 VOS_STATUS status;
6755 hdd_adapter_t *pAdapter;
6756 v_U8_t operatingChannel = 0;
6757
6758 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6759
6760 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6761 {
6762 pAdapter = pAdapterNode->pAdapter;
6763
6764 if( mode == pAdapter->device_mode )
6765 {
6766 switch(pAdapter->device_mode)
6767 {
6768 case WLAN_HDD_INFRA_STATION:
6769 case WLAN_HDD_P2P_CLIENT:
6770 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6771 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
6772 break;
6773 case WLAN_HDD_SOFTAP:
6774 case WLAN_HDD_P2P_GO:
6775 /*softap connection info */
6776 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6777 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
6778 break;
6779 default:
6780 break;
6781 }
6782
6783 break; //Found the device of interest. break the loop
6784 }
6785
6786 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6787 pAdapterNode = pNext;
6788 }
6789 return operatingChannel;
6790}
6791
6792#ifdef WLAN_FEATURE_PACKET_FILTERING
6793/**---------------------------------------------------------------------------
6794
6795 \brief hdd_set_multicast_list() -
6796
6797 This used to set the multicast address list.
6798
6799 \param - dev - Pointer to the WLAN device.
6800 - skb - Pointer to OS packet (sk_buff).
6801 \return - success/fail
6802
6803 --------------------------------------------------------------------------*/
6804static void hdd_set_multicast_list(struct net_device *dev)
6805{
6806 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 int mc_count;
6808 int i = 0;
6809 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306810
6811 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 {
6813 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306814 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 return;
6816 }
6817
6818 if (dev->flags & IFF_ALLMULTI)
6819 {
6820 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006821 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306822 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006823 }
6824 else
6825 {
6826 mc_count = netdev_mc_count(dev);
6827 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006828 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
6830 {
6831 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006832 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306833 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 return;
6835 }
6836
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306837 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07006838
6839 netdev_for_each_mc_addr(ha, dev) {
6840 if (i == mc_count)
6841 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306842 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
6843 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08006844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306846 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 i++;
6848 }
6849 }
6850 return;
6851}
6852#endif
6853
6854/**---------------------------------------------------------------------------
6855
6856 \brief hdd_select_queue() -
6857
6858 This function is registered with the Linux OS for network
6859 core to decide which queue to use first.
6860
6861 \param - dev - Pointer to the WLAN device.
6862 - skb - Pointer to OS packet (sk_buff).
6863 \return - ac, Queue Index/access category corresponding to UP in IP header
6864
6865 --------------------------------------------------------------------------*/
6866v_U16_t hdd_select_queue(struct net_device *dev,
6867 struct sk_buff *skb)
6868{
6869 return hdd_wmm_select_queue(dev, skb);
6870}
6871
6872
6873/**---------------------------------------------------------------------------
6874
6875 \brief hdd_wlan_initial_scan() -
6876
6877 This function triggers the initial scan
6878
6879 \param - pAdapter - Pointer to the HDD adapter.
6880
6881 --------------------------------------------------------------------------*/
6882void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
6883{
6884 tCsrScanRequest scanReq;
6885 tCsrChannelInfo channelInfo;
6886 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07006887 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6889
6890 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
6891 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
6892 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
6893
6894 if(sme_Is11dSupported(pHddCtx->hHal))
6895 {
6896 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
6897 if ( HAL_STATUS_SUCCESS( halStatus ) )
6898 {
6899 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
6900 if( !scanReq.ChannelInfo.ChannelList )
6901 {
6902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
6903 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006904 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 return;
6906 }
6907 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
6908 channelInfo.numOfChannels);
6909 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
6910 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006911 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 }
6913
6914 scanReq.scanType = eSIR_PASSIVE_SCAN;
6915 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
6916 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
6917 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
6918 }
6919 else
6920 {
6921 scanReq.scanType = eSIR_ACTIVE_SCAN;
6922 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
6923 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
6924 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
6925 }
6926
6927 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
6928 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6929 {
6930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
6931 __func__, halStatus );
6932 }
6933
6934 if(sme_Is11dSupported(pHddCtx->hHal))
6935 vos_mem_free(scanReq.ChannelInfo.ChannelList);
6936}
6937
Jeff Johnson295189b2012-06-20 16:38:30 -07006938/**---------------------------------------------------------------------------
6939
6940 \brief hdd_full_power_callback() - HDD full power callback function
6941
6942 This is the function invoked by SME to inform the result of a full power
6943 request issued by HDD
6944
6945 \param - callbackcontext - Pointer to cookie
6946 \param - status - result of request
6947
6948 \return - None
6949
6950 --------------------------------------------------------------------------*/
6951static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
6952{
Jeff Johnson72a40512013-12-19 10:14:15 -08006953 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006954
6955 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306956 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006957
6958 if (NULL == callbackContext)
6959 {
6960 hddLog(VOS_TRACE_LEVEL_ERROR,
6961 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006962 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 return;
6964 }
6965
Jeff Johnson72a40512013-12-19 10:14:15 -08006966 /* there is a race condition that exists between this callback
6967 function and the caller since the caller could time out either
6968 before or while this code is executing. we use a spinlock to
6969 serialize these actions */
6970 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07006971
6972 if (POWER_CONTEXT_MAGIC != pContext->magic)
6973 {
6974 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006975 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 hddLog(VOS_TRACE_LEVEL_WARN,
6977 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006978 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 return;
6980 }
6981
Jeff Johnson72a40512013-12-19 10:14:15 -08006982 /* context is valid so caller is still waiting */
6983
6984 /* paranoia: invalidate the magic */
6985 pContext->magic = 0;
6986
6987 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006989
6990 /* serialization is complete */
6991 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07006992}
6993
6994/**---------------------------------------------------------------------------
6995
6996 \brief hdd_wlan_exit() - HDD WLAN exit function
6997
6998 This is the driver exit point (invoked during rmmod)
6999
7000 \param - pHddCtx - Pointer to the HDD Context
7001
7002 \return - None
7003
7004 --------------------------------------------------------------------------*/
7005void hdd_wlan_exit(hdd_context_t *pHddCtx)
7006{
7007 eHalStatus halStatus;
7008 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7009 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307010 struct wiphy *wiphy = pHddCtx->wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 hdd_adapter_t* pAdapter;
Jeff Johnson72a40512013-12-19 10:14:15 -08007012 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 long lrc;
7014
7015 ENTER();
7016
Jeff Johnson88ba7742013-02-27 14:36:02 -08007017 if (VOS_FTM_MODE != hdd_get_conparam())
7018 {
7019 // Unloading, restart logic is no more required.
7020 wlan_hdd_restart_deinit(pHddCtx);
7021 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007022
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 {
7027 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7028 WLAN_HDD_INFRA_STATION);
7029 if (pAdapter == NULL)
7030 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7031
7032 if (pAdapter != NULL)
7033 {
7034 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7035 hdd_UnregisterWext(pAdapter->dev);
7036 }
7037 }
7038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007039
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007041 {
7042 wlan_hdd_ftm_close(pHddCtx);
7043 goto free_hdd_ctx;
7044 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 //Stop the Interface TX queue.
7046 //netif_tx_disable(pWlanDev);
7047 //netif_carrier_off(pWlanDev);
7048
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7050 {
7051 pAdapter = hdd_get_adapter(pHddCtx,
7052 WLAN_HDD_SOFTAP);
7053 }
7054 else
7055 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 {
7058 pAdapter = hdd_get_adapter(pHddCtx,
7059 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007060 if (pAdapter == NULL)
7061 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 /* DeRegister with platform driver as client for Suspend/Resume */
7065 vosStatus = hddDeregisterPmOps(pHddCtx);
7066 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7067 {
7068 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7069 VOS_ASSERT(0);
7070 }
7071
7072 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7073 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7074 {
7075 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007077
7078 // Cancel any outstanding scan requests. We are about to close all
7079 // of our adapters, but an adapter structure is what SME passes back
7080 // to our callback function. Hence if there are any outstanding scan
7081 // requests then there is a race condition between when the adapter
7082 // is closed and when the callback is invoked. We try to resolve that
7083 // race condition here by canceling any outstanding scans before we
7084 // close the adapters.
7085 // Note that the scans may be cancelled in an asynchronous manner, so
7086 // ideally there needs to be some kind of synchronization. Rather than
7087 // introduce a new synchronization here, we will utilize the fact that
7088 // we are about to Request Full Power, and since that is synchronized,
7089 // the expectation is that by the time Request Full Power has completed,
7090 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007091 if (NULL != pAdapter)
7092 hdd_abort_mac_scan( pHddCtx, pAdapter->sessionId);
7093 else
7094 hddLog(VOS_TRACE_LEVEL_ERROR,
7095 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007096
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007097 //Stop the traffic monitor timer
7098 if ( VOS_TIMER_STATE_RUNNING ==
7099 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7100 {
7101 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7102 }
7103
7104 // Destroy the traffic monitor timer
7105 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7106 &pHddCtx->tx_rx_trafficTmr)))
7107 {
7108 hddLog(VOS_TRACE_LEVEL_ERROR,
7109 "%s: Cannot deallocate Traffic monitor timer", __func__);
7110 }
7111
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 //Disable IMPS/BMPS as we do not want the device to enter any power
7113 //save mode during shutdown
7114 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7115 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7116 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7117
7118 //Ensure that device is in full power as we will touch H/W during vos_Stop
7119 init_completion(&powerContext.completion);
7120 powerContext.magic = POWER_CONTEXT_MAGIC;
7121
7122 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7123 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7124
7125 if (eHAL_STATUS_SUCCESS != halStatus)
7126 {
7127 if (eHAL_STATUS_PMC_PENDING == halStatus)
7128 {
7129 /* request was sent -- wait for the response */
7130 lrc = wait_for_completion_interruptible_timeout(
7131 &powerContext.completion,
7132 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 if (lrc <= 0)
7134 {
7135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007136 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 }
7138 }
7139 else
7140 {
7141 hddLog(VOS_TRACE_LEVEL_ERROR,
7142 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007143 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 /* continue -- need to clean up as much as possible */
7145 }
7146 }
7147
Jeff Johnson72a40512013-12-19 10:14:15 -08007148 /* either we never sent a request, we sent a request and received a
7149 response or we sent a request and timed out. if we never sent a
7150 request or if we sent a request and got a response, we want to
7151 clear the magic out of paranoia. if we timed out there is a
7152 race condition such that the callback function could be
7153 executing at the same time we are. of primary concern is if the
7154 callback function had already verified the "magic" but had not
7155 yet set the completion variable when a timeout occurred. we
7156 serialize these activities by invalidating the magic while
7157 holding a shared spinlock which will cause us to block if the
7158 callback is currently executing */
7159 spin_lock(&hdd_context_lock);
7160 powerContext.magic = 0;
7161 spin_unlock(&hdd_context_lock);
7162
Yue Ma0d4891e2013-08-06 17:01:45 -07007163 hdd_debugfs_exit(pHddCtx);
7164
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 // Unregister the Net Device Notifier
7166 unregister_netdevice_notifier(&hdd_netdev_notifier);
7167
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 hdd_stop_all_adapters( pHddCtx );
7169
Jeff Johnson295189b2012-06-20 16:38:30 -07007170#ifdef WLAN_BTAMP_FEATURE
7171 vosStatus = WLANBAP_Stop(pVosContext);
7172 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7173 {
7174 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7175 "%s: Failed to stop BAP",__func__);
7176 }
7177#endif //WLAN_BTAMP_FEATURE
7178
7179 //Stop all the modules
7180 vosStatus = vos_stop( pVosContext );
7181 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7182 {
7183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7184 "%s: Failed to stop VOSS",__func__);
7185 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7186 }
7187
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 //Assert Deep sleep signal now to put Libra HW in lowest power state
7189 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7190 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7191
7192 //Vote off any PMIC voltage supplies
7193 vos_chipPowerDown(NULL, NULL, NULL);
7194
7195 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7196
Leo Chang59cdc7e2013-07-10 10:08:21 -07007197
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007200
7201 //Close the scheduler before calling vos_close to make sure no thread is
7202 // scheduled after the each module close is called i.e after all the data
7203 // structures are freed.
7204 vosStatus = vos_sched_close( pVosContext );
7205 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7206 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7207 "%s: Failed to close VOSS Scheduler",__func__);
7208 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7209 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007210#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007211#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7212 /* Destroy the wake lock */
7213 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7214#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007215 /* Destroy the wake lock */
7216 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007217#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007218
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307219#ifdef CONFIG_ENABLE_LINUX_REG
7220 vosStatus = vos_nv_close();
7221 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7222 {
7223 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7224 "%s: Failed to close NV", __func__);
7225 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7226 }
7227#endif
7228
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 //Close VOSS
7230 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7231 vos_close(pVosContext);
7232
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 //Close Watchdog
7234 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7235 vos_watchdog_close(pVosContext);
7236
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307237 //Clean up HDD Nlink Service
7238 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007239#ifdef WLAN_KD_READY_NOTIFIER
7240 nl_srv_exit(pHddCtx->ptt_pid);
7241#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307242 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007243#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307244
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 /* Cancel the vote for XO Core ON.
7246 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7247 * exited at this point
7248 */
7249 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007250 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7252 {
7253 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7254 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007255 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 }
7257
7258 hdd_close_all_adapters( pHddCtx );
7259
7260
7261 //Free up dynamically allocated members inside HDD Adapter
7262 kfree(pHddCtx->cfg_ini);
7263 pHddCtx->cfg_ini= NULL;
7264
7265 /* free the power on lock from platform driver */
7266 if (free_riva_power_on_lock("wlan"))
7267 {
7268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7269 __func__);
7270 }
7271
Jeff Johnson88ba7742013-02-27 14:36:02 -08007272free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007273 /* FTM mode, WIPHY did not registered
7274 If un-register here, system crash will happen */
7275 if (VOS_FTM_MODE != hdd_get_conparam())
7276 {
7277 wiphy_unregister(wiphy) ;
7278 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007279 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 if (hdd_is_ssr_required())
7281 {
7282 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007283 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 msleep(5000);
7285 }
7286 hdd_set_ssr_required (VOS_FALSE);
7287}
7288
7289
7290/**---------------------------------------------------------------------------
7291
7292 \brief hdd_update_config_from_nv() - Function to update the contents of
7293 the running configuration with parameters taken from NV storage
7294
7295 \param - pHddCtx - Pointer to the HDD global context
7296
7297 \return - VOS_STATUS_SUCCESS if successful
7298
7299 --------------------------------------------------------------------------*/
7300static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7301{
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 v_BOOL_t itemIsValid = VOS_FALSE;
7303 VOS_STATUS status;
7304 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7305 v_U8_t macLoop;
7306
7307 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7308 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7309 if(status != VOS_STATUS_SUCCESS)
7310 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007311 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 return VOS_STATUS_E_FAILURE;
7313 }
7314
7315 if (itemIsValid == VOS_TRUE)
7316 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007317 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007318 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7319 VOS_MAX_CONCURRENCY_PERSONA);
7320 if(status != VOS_STATUS_SUCCESS)
7321 {
7322 /* Get MAC from NV fail, not update CFG info
7323 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007324 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 return VOS_STATUS_E_FAILURE;
7326 }
7327
7328 /* If first MAC is not valid, treat all others are not valid
7329 * Then all MACs will be got from ini file */
7330 if(vos_is_macaddr_zero(&macFromNV[0]))
7331 {
7332 /* MAC address in NV file is not configured yet */
7333 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7334 return VOS_STATUS_E_INVAL;
7335 }
7336
7337 /* Get MAC address from NV, update CFG info */
7338 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7339 {
7340 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7341 {
7342 printk(KERN_ERR "not valid MAC from NV for %d", macLoop);
7343 /* This MAC is not valid, skip it
7344 * This MAC will be got from ini file */
7345 }
7346 else
7347 {
7348 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7349 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7350 VOS_MAC_ADDR_SIZE);
7351 }
7352 }
7353 }
7354 else
7355 {
7356 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7357 return VOS_STATUS_E_FAILURE;
7358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007359
Jeff Johnson295189b2012-06-20 16:38:30 -07007360
7361 return VOS_STATUS_SUCCESS;
7362}
7363
7364/**---------------------------------------------------------------------------
7365
7366 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7367
7368 \param - pAdapter - Pointer to the HDD
7369
7370 \return - None
7371
7372 --------------------------------------------------------------------------*/
7373VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7374{
7375 eHalStatus halStatus;
7376 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307377 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007378
Jeff Johnson295189b2012-06-20 16:38:30 -07007379
7380 // Send ready indication to the HDD. This will kick off the MAC
7381 // into a 'running' state and should kick off an initial scan.
7382 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7383 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7384 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307385 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007386 "code %08d [x%08x]",__func__, halStatus, halStatus );
7387 return VOS_STATUS_E_FAILURE;
7388 }
7389
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307390 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7392 // And RIVA will crash
7393 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7394 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307395 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7396 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7397
7398
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 return VOS_STATUS_SUCCESS;
7400}
7401
Jeff Johnson295189b2012-06-20 16:38:30 -07007402/* wake lock APIs for HDD */
7403void hdd_prevent_suspend(void)
7404{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007405#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007407#else
7408 wcnss_prevent_suspend();
7409#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007410}
7411
7412void hdd_allow_suspend(void)
7413{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007414#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007416#else
7417 wcnss_allow_suspend();
7418#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007419}
7420
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007421void hdd_allow_suspend_timeout(v_U32_t timeout)
7422{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007423#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007424 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007425#else
7426 /* Do nothing as there is no API in wcnss for timeout*/
7427#endif
7428}
7429
Jeff Johnson295189b2012-06-20 16:38:30 -07007430/**---------------------------------------------------------------------------
7431
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007432 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7433 information between Host and Riva
7434
7435 This function gets reported version of FW
7436 It also finds the version of Riva headers used to compile the host
7437 It compares the above two and prints a warning if they are different
7438 It gets the SW and HW version string
7439 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7440 indicating the features they support through a bitmap
7441
7442 \param - pHddCtx - Pointer to HDD context
7443
7444 \return - void
7445
7446 --------------------------------------------------------------------------*/
7447
7448void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7449{
7450
7451 tSirVersionType versionCompiled;
7452 tSirVersionType versionReported;
7453 tSirVersionString versionString;
7454 tANI_U8 fwFeatCapsMsgSupported = 0;
7455 VOS_STATUS vstatus;
7456
7457 /* retrieve and display WCNSS version information */
7458 do {
7459
7460 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7461 &versionCompiled);
7462 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7463 {
7464 hddLog(VOS_TRACE_LEVEL_FATAL,
7465 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007466 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007467 break;
7468 }
7469
7470 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7471 &versionReported);
7472 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7473 {
7474 hddLog(VOS_TRACE_LEVEL_FATAL,
7475 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007476 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007477 break;
7478 }
7479
7480 if ((versionCompiled.major != versionReported.major) ||
7481 (versionCompiled.minor != versionReported.minor) ||
7482 (versionCompiled.version != versionReported.version) ||
7483 (versionCompiled.revision != versionReported.revision))
7484 {
7485 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7486 "Host expected %u.%u.%u.%u\n",
7487 WLAN_MODULE_NAME,
7488 (int)versionReported.major,
7489 (int)versionReported.minor,
7490 (int)versionReported.version,
7491 (int)versionReported.revision,
7492 (int)versionCompiled.major,
7493 (int)versionCompiled.minor,
7494 (int)versionCompiled.version,
7495 (int)versionCompiled.revision);
7496 }
7497 else
7498 {
7499 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7500 WLAN_MODULE_NAME,
7501 (int)versionReported.major,
7502 (int)versionReported.minor,
7503 (int)versionReported.version,
7504 (int)versionReported.revision);
7505 }
7506
7507 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7508 versionString,
7509 sizeof(versionString));
7510 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7511 {
7512 hddLog(VOS_TRACE_LEVEL_FATAL,
7513 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007514 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007515 break;
7516 }
7517
7518 pr_info("%s: WCNSS software version %s\n",
7519 WLAN_MODULE_NAME, versionString);
7520
7521 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7522 versionString,
7523 sizeof(versionString));
7524 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7525 {
7526 hddLog(VOS_TRACE_LEVEL_FATAL,
7527 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007528 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007529 break;
7530 }
7531
7532 pr_info("%s: WCNSS hardware version %s\n",
7533 WLAN_MODULE_NAME, versionString);
7534
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007535 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7536 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007537 send the message only if it the riva is 1.1
7538 minor numbers for different riva branches:
7539 0 -> (1.0)Mainline Build
7540 1 -> (1.1)Mainline Build
7541 2->(1.04) Stability Build
7542 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007543 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007544 ((versionReported.minor>=1) && (versionReported.version>=1)))
7545 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7546 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007547
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007548 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007549 {
7550#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7551 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7552 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7553#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007554 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7555 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7556 {
7557 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7558 }
7559
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007560 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007561 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007562
7563 } while (0);
7564
7565}
7566
7567/**---------------------------------------------------------------------------
7568
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307569 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7570
7571 \param - pHddCtx - Pointer to the hdd context
7572
7573 \return - true if hardware supports 5GHz
7574
7575 --------------------------------------------------------------------------*/
7576static boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
7577{
7578 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7579 * then hardware support 5Ghz.
7580 */
7581 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7582 {
7583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
7584 return true;
7585 }
7586 else
7587 {
7588 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
7589 __func__);
7590 return false;
7591 }
7592}
7593
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307594/**---------------------------------------------------------------------------
7595
7596 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7597 generate function
7598
7599 This is generate the random mac address for WLAN interface
7600
7601 \param - pHddCtx - Pointer to HDD context
7602 idx - Start interface index to get auto
7603 generated mac addr.
7604 mac_addr - Mac address
7605
7606 \return - 0 for success, < 0 for failure
7607
7608 --------------------------------------------------------------------------*/
7609
7610static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
7611 int idx, v_MACADDR_t mac_addr)
7612{
7613 int i;
7614 unsigned int serialno;
7615 serialno = wcnss_get_serial_number();
7616
7617 if (0 != serialno)
7618 {
7619 /* MAC address has 3 bytes of OUI so we have a maximum of 3
7620 bytes of the serial number that can be used to generate
7621 the other 3 bytes of the MAC address. Mask off all but
7622 the lower 3 bytes (this will also make sure we don't
7623 overflow in the next step) */
7624 serialno &= 0x00FFFFFF;
7625
7626 /* we need a unique address for each session */
7627 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
7628
7629 /* autogen other Mac addresses */
7630 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7631 {
7632 /* start with the entire default address */
7633 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
7634 /* then replace the lower 3 bytes */
7635 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
7636 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
7637 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
7638
7639 serialno++;
7640 hddLog(VOS_TRACE_LEVEL_ERROR,
7641 "%s: Derived Mac Addr: "
7642 MAC_ADDRESS_STR, __func__,
7643 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
7644 }
7645
7646 }
7647 else
7648 {
7649 hddLog(LOGE, FL("Failed to Get Serial NO"));
7650 return -1;
7651 }
7652 return 0;
7653}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307654
7655/**---------------------------------------------------------------------------
7656
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 \brief hdd_wlan_startup() - HDD init function
7658
7659 This is the driver startup code executed once a WLAN device has been detected
7660
7661 \param - dev - Pointer to the underlying device
7662
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007663 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07007664
7665 --------------------------------------------------------------------------*/
7666
7667int hdd_wlan_startup(struct device *dev )
7668{
7669 VOS_STATUS status;
7670 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07007671 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 hdd_context_t *pHddCtx = NULL;
7673 v_CONTEXT_t pVosContext= NULL;
7674#ifdef WLAN_BTAMP_FEATURE
7675 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
7676 WLANBAP_ConfigType btAmpConfig;
7677 hdd_config_t *pConfig;
7678#endif
7679 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007680 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307681 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07007682
7683 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 /*
7685 * cfg80211: wiphy allocation
7686 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307687 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007688
7689 if(wiphy == NULL)
7690 {
7691 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007692 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 }
7694
7695 pHddCtx = wiphy_priv(wiphy);
7696
Jeff Johnson295189b2012-06-20 16:38:30 -07007697 //Initialize the adapter context to zeros.
7698 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
7699
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 hdd_prevent_suspend();
7702 pHddCtx->isLoadUnloadInProgress = TRUE;
7703
7704 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
7705
7706 /*Get vos context here bcoz vos_open requires it*/
7707 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
7708
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08007709 if(pVosContext == NULL)
7710 {
7711 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
7712 goto err_free_hdd_context;
7713 }
7714
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 //Save the Global VOSS context in adapter context for future.
7716 pHddCtx->pvosContext = pVosContext;
7717
7718 //Save the adapter context in global context for future.
7719 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
7720
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 pHddCtx->parent_dev = dev;
7722
7723 init_completion(&pHddCtx->full_pwr_comp_var);
7724 init_completion(&pHddCtx->standby_comp_var);
7725 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007726 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08007727 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307728 init_completion(&pHddCtx->wiphy_channel_update_event);
Amar Singhala49cbc52013-10-08 18:37:44 -07007729
7730#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07007731 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07007732#else
7733 init_completion(&pHddCtx->driver_crda_req);
7734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007735
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05307736 spin_lock_init(&pHddCtx->schedScan_lock);
7737
Jeff Johnson295189b2012-06-20 16:38:30 -07007738 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
7739
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307740#ifdef FEATURE_WLAN_TDLS
7741 /* tdls_lock is initialized before an hdd_open_adapter ( which is
7742 * invoked by other instances also) to protect the concurrent
7743 * access for the Adapters by TDLS module.
7744 */
7745 mutex_init(&pHddCtx->tdls_lock);
7746#endif
7747
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307748 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007749 // Load all config first as TL config is needed during vos_open
7750 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
7751 if(pHddCtx->cfg_ini == NULL)
7752 {
7753 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
7754 goto err_free_hdd_context;
7755 }
7756
7757 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
7758
7759 // Read and parse the qcom_cfg.ini file
7760 status = hdd_parse_config_ini( pHddCtx );
7761 if ( VOS_STATUS_SUCCESS != status )
7762 {
7763 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
7764 __func__, WLAN_INI_FILE);
7765 goto err_config;
7766 }
Arif Hussaind5218912013-12-05 01:10:55 -08007767#ifdef MEMORY_DEBUG
7768 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
7769 vos_mem_init();
7770
7771 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
7772 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
7773#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007774
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05307775 /* INI has been read, initialise the configuredMcastBcastFilter with
7776 * INI value as this will serve as the default value
7777 */
7778 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
7779 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
7780 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307781
7782 if (false == hdd_is_5g_supported(pHddCtx))
7783 {
7784 //5Ghz is not supported.
7785 if (1 != pHddCtx->cfg_ini->nBandCapability)
7786 {
7787 hddLog(VOS_TRACE_LEVEL_INFO,
7788 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
7789 pHddCtx->cfg_ini->nBandCapability = 1;
7790 }
7791 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05307792
7793 /* If SNR Monitoring is enabled, FW has to parse all beacons
7794 * for calcaluting and storing the average SNR, so set Nth beacon
7795 * filter to 1 to enable FW to parse all the beaocons
7796 */
7797 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
7798 {
7799 /* The log level is deliberately set to WARN as overriding
7800 * nthBeaconFilter to 1 will increase power cosumption and this
7801 * might just prove helpful to detect the power issue.
7802 */
7803 hddLog(VOS_TRACE_LEVEL_WARN,
7804 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
7805 pHddCtx->cfg_ini->nthBeaconFilter = 1;
7806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307808 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307810 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 {
7812 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307813 "%s: wlan_hdd_cfg80211_init return failure", __func__);
7814 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007816
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007817 // Update VOS trace levels based upon the cfg.ini
7818 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
7819 pHddCtx->cfg_ini->vosTraceEnableBAP);
7820 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
7821 pHddCtx->cfg_ini->vosTraceEnableTL);
7822 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
7823 pHddCtx->cfg_ini->vosTraceEnableWDI);
7824 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
7825 pHddCtx->cfg_ini->vosTraceEnableHDD);
7826 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
7827 pHddCtx->cfg_ini->vosTraceEnableSME);
7828 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
7829 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05307830 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
7831 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007832 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
7833 pHddCtx->cfg_ini->vosTraceEnableWDA);
7834 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
7835 pHddCtx->cfg_ini->vosTraceEnableSYS);
7836 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
7837 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007838 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
7839 pHddCtx->cfg_ini->vosTraceEnableSAP);
7840 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
7841 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007842
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 // Update WDI trace levels based upon the cfg.ini
7844 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
7845 pHddCtx->cfg_ini->wdiTraceEnableDAL);
7846 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
7847 pHddCtx->cfg_ini->wdiTraceEnableCTL);
7848 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
7849 pHddCtx->cfg_ini->wdiTraceEnableDAT);
7850 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
7851 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007852
Jeff Johnson88ba7742013-02-27 14:36:02 -08007853 if (VOS_FTM_MODE == hdd_get_conparam())
7854 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
7856 {
7857 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
7858 goto err_free_hdd_context;
7859 }
7860 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
7861 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08007862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007863
Jeff Johnson88ba7742013-02-27 14:36:02 -08007864 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7866 {
7867 status = vos_watchdog_open(pVosContext,
7868 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
7869
7870 if(!VOS_IS_STATUS_SUCCESS( status ))
7871 {
7872 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307873 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 }
7875 }
7876
7877 pHddCtx->isLogpInProgress = FALSE;
7878 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
7879
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
7881 if(!VOS_IS_STATUS_SUCCESS(status))
7882 {
7883 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 }
7886
Amar Singhala49cbc52013-10-08 18:37:44 -07007887#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007888 /* initialize the NV module. This is required so that
7889 we can initialize the channel information in wiphy
7890 from the NV.bin data. The channel information in
7891 wiphy needs to be initialized before wiphy registration */
7892
7893 status = vos_nv_open();
7894 if (!VOS_IS_STATUS_SUCCESS(status))
7895 {
7896 /* NV module cannot be initialized */
7897 hddLog( VOS_TRACE_LEVEL_FATAL,
7898 "%s: vos_nv_open failed", __func__);
7899 goto err_clkvote;
7900 }
7901
7902 status = vos_init_wiphy_from_nv_bin();
7903 if (!VOS_IS_STATUS_SUCCESS(status))
7904 {
7905 /* NV module cannot be initialized */
7906 hddLog( VOS_TRACE_LEVEL_FATAL,
7907 "%s: vos_init_wiphy failed", __func__);
7908 goto err_vos_nv_close;
7909 }
7910
Amar Singhala49cbc52013-10-08 18:37:44 -07007911 /* registration of wiphy dev with cfg80211 */
7912 if (0 > wlan_hdd_cfg80211_register(wiphy))
7913 {
7914 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
Amar Singhal0a402232013-10-11 20:57:16 -07007915 goto err_vos_nv_close;
Amar Singhala49cbc52013-10-08 18:37:44 -07007916 }
7917#endif
7918
Jeff Johnson295189b2012-06-20 16:38:30 -07007919 status = vos_open( &pVosContext, 0);
7920 if ( !VOS_IS_STATUS_SUCCESS( status ))
7921 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08007922 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Amar Singhala49cbc52013-10-08 18:37:44 -07007923 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 }
7925
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
7927
7928 if ( NULL == pHddCtx->hHal )
7929 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08007930 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007931 goto err_vosclose;
7932 }
7933
Jeff Johnsonbc676b42013-02-14 16:04:08 -08007934 status = vos_preStart( pHddCtx->pvosContext );
7935 if ( !VOS_IS_STATUS_SUCCESS( status ) )
7936 {
7937 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
7938 goto err_vosclose;
7939 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007940
Jeff Johnsonbc676b42013-02-14 16:04:08 -08007941 /* Note that the vos_preStart() sequence triggers the cfg download.
7942 The cfg download must occur before we update the SME config
7943 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 status = hdd_set_sme_config( pHddCtx );
7945
7946 if ( VOS_STATUS_SUCCESS != status )
7947 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08007948 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
7949 goto err_vosclose;
7950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007951
7952 //Initialize the WMM module
7953 status = hdd_wmm_init(pHddCtx);
7954 if (!VOS_IS_STATUS_SUCCESS(status))
7955 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007956 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 goto err_vosclose;
7958 }
7959
Jeff Johnson295189b2012-06-20 16:38:30 -07007960 /* In the integrated architecture we update the configuration from
7961 the INI file and from NV before vOSS has been started so that
7962 the final contents are available to send down to the cCPU */
7963
Arif Hussain66559122013-11-21 10:11:40 -08007964 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
7965 {
7966 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
7967 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
7968 __func__, enable_dfs_chan_scan);
7969 }
7970 if (0 == enable_11d || 1 == enable_11d)
7971 {
7972 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
7973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
7974 __func__, enable_11d);
7975 }
7976
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 // Apply the cfg.ini to cfg.dat
7978 if (FALSE == hdd_update_config_dat(pHddCtx))
7979 {
7980 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
7981 goto err_vosclose;
7982 }
7983
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307984 // Get mac addr from platform driver
7985 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
7986
7987 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307989 /* Store the mac addr for first interface */
7990 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
7991
7992 hddLog(VOS_TRACE_LEVEL_ERROR,
7993 "%s: WLAN Mac Addr: "
7994 MAC_ADDRESS_STR, __func__,
7995 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
7996
7997 /* Here, passing Arg2 as 1 because we do not want to change the
7998 last 3 bytes (means non OUI bytes) of first interface mac
7999 addr.
8000 */
8001 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8002 {
8003 hddLog(VOS_TRACE_LEVEL_ERROR,
8004 "%s: Failed to generate wlan interface mac addr "
8005 "using MAC from ini file ", __func__);
8006 }
8007 }
8008 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8009 {
8010 // Apply the NV to cfg.dat
8011 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008012#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8013 /* There was not a valid set of MAC Addresses in NV. See if the
8014 default addresses were modified by the cfg.ini settings. If so,
8015 we'll use them, but if not, we'll autogenerate a set of MAC
8016 addresses based upon the device serial number */
8017
8018 static const v_MACADDR_t default_address =
8019 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008020
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308021 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8022 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 {
8024 /* cfg.ini has the default address, invoke autogen logic */
8025
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308026 /* Here, passing Arg2 as 0 because we want to change the
8027 last 3 bytes (means non OUI bytes) of all the interfaces
8028 mac addr.
8029 */
8030 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8031 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008032 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308033 hddLog(VOS_TRACE_LEVEL_ERROR,
8034 "%s: Failed to generate wlan interface mac addr "
8035 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8036 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 }
8039 else
8040#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8041 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008042 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 "%s: Invalid MAC address in NV, using MAC from ini file "
8044 MAC_ADDRESS_STR, __func__,
8045 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8046 }
8047 }
8048 {
8049 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308050
8051 /* Set the MAC Address Currently this is used by HAL to
8052 * add self sta. Remove this once self sta is added as
8053 * part of session open.
8054 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8056 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8057 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308058
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 if (!HAL_STATUS_SUCCESS( halStatus ))
8060 {
8061 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8062 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Madan Mohan Koyyalamudib8b126b2012-11-15 17:37:30 -08008063 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 }
8065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008066
8067 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8068 Note: Firmware image will be read and downloaded inside vos_start API */
8069 status = vos_start( pHddCtx->pvosContext );
8070 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8071 {
8072 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
8073 goto err_vosclose;
8074 }
8075
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008076 /* Exchange capability info between Host and FW and also get versioning info from FW */
8077 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008078
8079 status = hdd_post_voss_start_config( pHddCtx );
8080 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8081 {
8082 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8083 __func__);
8084 goto err_vosstop;
8085 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008086
8087#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308088 wlan_hdd_cfg80211_update_reg_info( wiphy );
8089
8090 /* registration of wiphy dev with cfg80211 */
8091 if (0 > wlan_hdd_cfg80211_register(wiphy))
8092 {
8093 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8094 goto err_vosstop;
8095 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008096#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008097
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8099 {
8100 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8101 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8102 }
8103 else
8104 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8106 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8107 if (pAdapter != NULL)
8108 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308109 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008110 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308111 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8112 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8113 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008114
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308115 /* Generate the P2P Device Address. This consists of the device's
8116 * primary MAC address with the locally administered bit set.
8117 */
8118 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008119 }
8120 else
8121 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308122 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8123 if (p2p_dev_addr != NULL)
8124 {
8125 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8126 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8127 }
8128 else
8129 {
8130 hddLog(VOS_TRACE_LEVEL_FATAL,
8131 "%s: Failed to allocate mac_address for p2p_device",
8132 __func__);
8133 goto err_close_adapter;
8134 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008136
8137 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8138 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8139 if ( NULL == pP2pAdapter )
8140 {
8141 hddLog(VOS_TRACE_LEVEL_FATAL,
8142 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008143 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008144 goto err_close_adapter;
8145 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008146 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008148
8149 if( pAdapter == NULL )
8150 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8152 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008154
Arif Hussain66559122013-11-21 10:11:40 -08008155 if (country_code)
8156 {
8157 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008158 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008159 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8160#ifndef CONFIG_ENABLE_LINUX_REG
8161 hdd_checkandupdate_phymode(pAdapter, country_code);
8162#endif
8163 ret = sme_ChangeCountryCode(pHddCtx->hHal, NULL,
8164 country_code,
8165 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308166 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008167 if (eHAL_STATUS_SUCCESS == ret)
8168 {
Arif Hussaincb607082013-12-20 11:57:42 -08008169 ret = wait_for_completion_interruptible_timeout(
8170 &pAdapter->change_country_code,
8171 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8172
8173 if (0 >= ret)
8174 {
8175 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8176 "%s: SME while setting country code timed out", __func__);
8177 }
Arif Hussain66559122013-11-21 10:11:40 -08008178 }
8179 else
8180 {
Arif Hussaincb607082013-12-20 11:57:42 -08008181 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8182 "%s: SME Change Country code from module param fail ret=%d",
8183 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008184 }
8185 }
8186
Jeff Johnson295189b2012-06-20 16:38:30 -07008187#ifdef WLAN_BTAMP_FEATURE
8188 vStatus = WLANBAP_Open(pVosContext);
8189 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8190 {
8191 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8192 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008193 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 }
8195
8196 vStatus = BSL_Init(pVosContext);
8197 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8198 {
8199 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8200 "%s: Failed to Init BSL",__func__);
8201 goto err_bap_close;
8202 }
8203 vStatus = WLANBAP_Start(pVosContext);
8204 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8205 {
8206 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8207 "%s: Failed to start TL",__func__);
8208 goto err_bap_close;
8209 }
8210
8211 pConfig = pHddCtx->cfg_ini;
8212 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8213 status = WLANBAP_SetConfig(&btAmpConfig);
8214
8215#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008216
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008217#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8218 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8219 {
8220 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8221 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8222 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8223 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8224 }
8225#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008226#ifdef FEATURE_WLAN_SCAN_PNO
8227 /*SME must send channel update configuration to RIVA*/
8228 sme_UpdateChannelConfig(pHddCtx->hHal);
8229#endif
8230
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 /* Register with platform driver as client for Suspend/Resume */
8232 status = hddRegisterPmOps(pHddCtx);
8233 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8234 {
8235 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8236#ifdef WLAN_BTAMP_FEATURE
8237 goto err_bap_stop;
8238#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008239 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008240#endif //WLAN_BTAMP_FEATURE
8241 }
8242
Yue Ma0d4891e2013-08-06 17:01:45 -07008243 /* Open debugfs interface */
8244 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8245 {
8246 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8247 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008248 }
8249
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 /* Register TM level change handler function to the platform */
8251 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8252 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8253 {
8254 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8255 goto err_unregister_pmops;
8256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008257
8258 /* register for riva power on lock to platform driver */
8259 if (req_riva_power_on_lock("wlan"))
8260 {
8261 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8262 __func__);
8263 goto err_unregister_pmops;
8264 }
8265
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 // register net device notifier for device change notification
8267 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8268
8269 if(ret < 0)
8270 {
8271 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8272 goto err_free_power_on_lock;
8273 }
8274
8275 //Initialize the nlink service
8276 if(nl_srv_init() != 0)
8277 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308278 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 goto err_reg_netdev;
8280 }
8281
Leo Chang4ce1cc52013-10-21 18:27:15 -07008282#ifdef WLAN_KD_READY_NOTIFIER
8283 pHddCtx->kd_nl_init = 1;
8284#endif /* WLAN_KD_READY_NOTIFIER */
8285
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 //Initialize the BTC service
8287 if(btc_activate_service(pHddCtx) != 0)
8288 {
8289 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8290 goto err_nl_srv;
8291 }
8292
8293#ifdef PTT_SOCK_SVC_ENABLE
8294 //Initialize the PTT service
8295 if(ptt_sock_activate_svc(pHddCtx) != 0)
8296 {
8297 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8298 goto err_nl_srv;
8299 }
8300#endif
8301
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008305 /* Action frame registered in one adapter which will
8306 * applicable to all interfaces
8307 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008308 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008309 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008310
8311 mutex_init(&pHddCtx->sap_lock);
8312
8313 pHddCtx->isLoadUnloadInProgress = FALSE;
8314
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008315#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008316#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8317 /* Initialize the wake lcok */
8318 wake_lock_init(&pHddCtx->rx_wake_lock,
8319 WAKE_LOCK_SUSPEND,
8320 "qcom_rx_wakelock");
8321#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008322 /* Initialize the wake lcok */
8323 wake_lock_init(&pHddCtx->sap_wake_lock,
8324 WAKE_LOCK_SUSPEND,
8325 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008326#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008327
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008328 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8329 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008330
8331 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8332 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308333#ifndef CONFIG_ENABLE_LINUX_REG
8334 /*updating wiphy so that regulatory user hints can be processed*/
8335 if (wiphy)
8336 {
8337 regulatory_hint(wiphy, "00");
8338 }
8339#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008340 // Initialize the restart logic
8341 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308342
Leo Chang0b0e45a2013-12-15 15:18:55 -08008343#ifdef FEATURE_WLAN_CH_AVOID
8344 /* Plug in avoid channel notification callback */
8345 sme_AddChAvoidCallback(pHddCtx->hHal,
8346 hdd_hostapd_ch_avoid_cb);
8347#endif /* FEATURE_WLAN_CH_AVOID */
8348
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008349 //Register the traffic monitor timer now
8350 if ( pHddCtx->cfg_ini->dynSplitscan)
8351 {
8352 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8353 VOS_TIMER_TYPE_SW,
8354 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8355 (void *)pHddCtx);
8356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 goto success;
8358
8359err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008360#ifdef WLAN_KD_READY_NOTIFIER
8361 nl_srv_exit(pHddCtx->ptt_pid);
8362#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008364#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008365err_reg_netdev:
8366 unregister_netdevice_notifier(&hdd_netdev_notifier);
8367
8368err_free_power_on_lock:
8369 free_riva_power_on_lock("wlan");
8370
8371err_unregister_pmops:
8372 hddDevTmUnregisterNotifyCallback(pHddCtx);
8373 hddDeregisterPmOps(pHddCtx);
8374
Yue Ma0d4891e2013-08-06 17:01:45 -07008375 hdd_debugfs_exit(pHddCtx);
8376
Jeff Johnson295189b2012-06-20 16:38:30 -07008377#ifdef WLAN_BTAMP_FEATURE
8378err_bap_stop:
8379 WLANBAP_Stop(pVosContext);
8380#endif
8381
8382#ifdef WLAN_BTAMP_FEATURE
8383err_bap_close:
8384 WLANBAP_Close(pVosContext);
8385#endif
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387err_close_adapter:
8388 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008389
8390#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308391 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008392#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008393
8394err_vosstop:
8395 vos_stop(pVosContext);
8396
Amar Singhala49cbc52013-10-08 18:37:44 -07008397err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 status = vos_sched_close( pVosContext );
8399 if (!VOS_IS_STATUS_SUCCESS(status)) {
8400 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8401 "%s: Failed to close VOSS Scheduler", __func__);
8402 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8403 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008404 vos_close(pVosContext );
8405
8406err_wiphy_unregister:
8407
8408#ifdef CONFIG_ENABLE_LINUX_REG
8409 wiphy_unregister(wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07008410
Amar Singhal0a402232013-10-11 20:57:16 -07008411err_vos_nv_close:
8412
8413 vos_nv_close();
8414
Jeff Johnson295189b2012-06-20 16:38:30 -07008415err_clkvote:
Amar Singhala49cbc52013-10-08 18:37:44 -07008416#endif
8417
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008418 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008419
8420err_wdclose:
8421 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8422 vos_watchdog_close(pVosContext);
8423
Jeff Johnson295189b2012-06-20 16:38:30 -07008424err_config:
8425 kfree(pHddCtx->cfg_ini);
8426 pHddCtx->cfg_ini= NULL;
8427
8428err_free_hdd_context:
8429 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 wiphy_free(wiphy) ;
8431 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 VOS_BUG(1);
8433
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008434 if (hdd_is_ssr_required())
8435 {
8436 /* WDI timeout had happened during load, so SSR is needed here */
8437 subsystem_restart("wcnss");
8438 msleep(5000);
8439 }
8440 hdd_set_ssr_required (VOS_FALSE);
8441
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008442 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008443
8444success:
8445 EXIT();
8446 return 0;
8447}
8448
8449/**---------------------------------------------------------------------------
8450
Jeff Johnson32d95a32012-09-10 13:15:23 -07008451 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008452
Jeff Johnson32d95a32012-09-10 13:15:23 -07008453 This is the driver entry point - called in different timeline depending
8454 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008455
8456 \param - None
8457
8458 \return - 0 for success, non zero for failure
8459
8460 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008461static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008462{
8463 VOS_STATUS status;
8464 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 struct device *dev = NULL;
8466 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008467#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8468 int max_retries = 0;
8469#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008470
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308471#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8472 vos_wconn_trace_init();
8473#endif
8474
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 ENTER();
8476
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008477#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008479#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008480
8481 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8482 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8483
8484 //Power Up Libra WLAN card first if not already powered up
8485 status = vos_chipPowerUp(NULL,NULL,NULL);
8486 if (!VOS_IS_STATUS_SUCCESS(status))
8487 {
8488 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8489 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308490#ifdef WLAN_OPEN_SOURCE
8491 wake_lock_destroy(&wlan_wake_lock);
8492#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008493 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 }
8495
Jeff Johnson295189b2012-06-20 16:38:30 -07008496#ifdef ANI_BUS_TYPE_PCI
8497
8498 dev = wcnss_wlan_get_device();
8499
8500#endif // ANI_BUS_TYPE_PCI
8501
8502#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008503
8504#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8505 /* wait until WCNSS driver downloads NV */
8506 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8507 msleep(1000);
8508 }
8509 if (max_retries >= 5) {
8510 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308511#ifdef WLAN_OPEN_SOURCE
8512 wake_lock_destroy(&wlan_wake_lock);
8513#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008514 return -ENODEV;
8515 }
8516#endif
8517
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 dev = wcnss_wlan_get_device();
8519#endif // ANI_BUS_TYPE_PLATFORM
8520
8521
8522 do {
8523 if (NULL == dev) {
8524 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8525 ret_status = -1;
8526 break;
8527 }
8528
Jeff Johnson295189b2012-06-20 16:38:30 -07008529#ifdef TIMER_MANAGER
8530 vos_timer_manager_init();
8531#endif
8532
8533 /* Preopen VOSS so that it is ready to start at least SAL */
8534 status = vos_preOpen(&pVosContext);
8535
8536 if (!VOS_IS_STATUS_SUCCESS(status))
8537 {
8538 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8539 ret_status = -1;
8540 break;
8541 }
8542
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008543#ifndef MODULE
8544 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
8545 */
8546 hdd_set_conparam((v_UINT_t)con_mode);
8547#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008548
8549 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008550 if (hdd_wlan_startup(dev))
8551 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008552 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008553 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 vos_preClose( &pVosContext );
8555 ret_status = -1;
8556 break;
8557 }
8558
8559 /* Cancel the vote for XO Core ON
8560 * This is done here for safety purposes in case we re-initialize without turning
8561 * it OFF in any error scenario.
8562 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008563 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008565 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8567 {
8568 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008569 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 }
8571 } while (0);
8572
8573 if (0 != ret_status)
8574 {
8575 //Assert Deep sleep signal now to put Libra HW in lowest power state
8576 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
8577 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
8578
8579 //Vote off any PMIC voltage supplies
8580 vos_chipPowerDown(NULL, NULL, NULL);
8581#ifdef TIMER_MANAGER
8582 vos_timer_exit();
8583#endif
8584#ifdef MEMORY_DEBUG
8585 vos_mem_exit();
8586#endif
8587
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008588#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008590#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
8592 }
8593 else
8594 {
8595 //Send WLAN UP indication to Nlink Service
8596 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
8597
8598 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 }
8600
8601 EXIT();
8602
8603 return ret_status;
8604}
8605
Jeff Johnson32d95a32012-09-10 13:15:23 -07008606/**---------------------------------------------------------------------------
8607
8608 \brief hdd_module_init() - Init Function
8609
8610 This is the driver entry point (invoked when module is loaded using insmod)
8611
8612 \param - None
8613
8614 \return - 0 for success, non zero for failure
8615
8616 --------------------------------------------------------------------------*/
8617#ifdef MODULE
8618static int __init hdd_module_init ( void)
8619{
8620 return hdd_driver_init();
8621}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008622#else /* #ifdef MODULE */
8623static int __init hdd_module_init ( void)
8624{
8625 /* Driver initialization is delayed to fwpath_changed_handler */
8626 return 0;
8627}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008628#endif /* #ifdef MODULE */
8629
Jeff Johnson295189b2012-06-20 16:38:30 -07008630
8631/**---------------------------------------------------------------------------
8632
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008633 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008634
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008635 This is the driver exit point (invoked when module is unloaded using rmmod
8636 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07008637
8638 \param - None
8639
8640 \return - None
8641
8642 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008643static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008644{
8645 hdd_context_t *pHddCtx = NULL;
8646 v_CONTEXT_t pVosContext = NULL;
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008647 int retry = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008648
8649 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
8650
8651 //Get the global vos context
8652 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8653
8654 if(!pVosContext)
8655 {
8656 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
8657 goto done;
8658 }
8659
8660 //Get the HDD context.
8661 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
8662
8663 if(!pHddCtx)
8664 {
8665 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
8666 }
8667 else
8668 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008669 while(isWDresetInProgress()) {
8670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8671 "%s:SSR in Progress; block rmmod for 1 second!!!", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008672 msleep(1000);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008673
8674 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
8675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8676 "%s:SSR never completed, fatal error", __func__);
8677 VOS_BUG(0);
8678 }
8679 }
8680
Jeff Johnson295189b2012-06-20 16:38:30 -07008681
8682 pHddCtx->isLoadUnloadInProgress = TRUE;
8683 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8684
8685 //Do all the cleanup before deregistering the driver
8686 hdd_wlan_exit(pHddCtx);
8687 }
8688
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 vos_preClose( &pVosContext );
8690
8691#ifdef TIMER_MANAGER
8692 vos_timer_exit();
8693#endif
8694#ifdef MEMORY_DEBUG
8695 vos_mem_exit();
8696#endif
8697
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308698#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8699 vos_wconn_trace_exit();
8700#endif
8701
Jeff Johnson295189b2012-06-20 16:38:30 -07008702done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008703#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008705#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
8707}
8708
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008709/**---------------------------------------------------------------------------
8710
8711 \brief hdd_module_exit() - Exit function
8712
8713 This is the driver exit point (invoked when module is unloaded using rmmod)
8714
8715 \param - None
8716
8717 \return - None
8718
8719 --------------------------------------------------------------------------*/
8720static void __exit hdd_module_exit(void)
8721{
8722 hdd_driver_exit();
8723}
8724
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008725#ifdef MODULE
8726static int fwpath_changed_handler(const char *kmessage,
8727 struct kernel_param *kp)
8728{
Jeff Johnson76052702013-04-16 13:55:05 -07008729 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008730}
8731
8732static int con_mode_handler(const char *kmessage,
8733 struct kernel_param *kp)
8734{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07008735 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008736}
8737#else /* #ifdef MODULE */
8738/**---------------------------------------------------------------------------
8739
Jeff Johnson76052702013-04-16 13:55:05 -07008740 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008741
Jeff Johnson76052702013-04-16 13:55:05 -07008742 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008743 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07008744 - invoked when module parameter fwpath is modified from userspace to signal
8745 initializing the WLAN driver or when con_mode is modified from userspace
8746 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008747
8748 \return - 0 for success, non zero for failure
8749
8750 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07008751static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008752{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008753 int ret_status;
8754
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008755 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008756 ret_status = hdd_driver_init();
8757 wlan_hdd_inited = ret_status ? 0 : 1;
8758 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008759 }
8760
8761 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07008762
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008763 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07008764
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008765 ret_status = hdd_driver_init();
8766 wlan_hdd_inited = ret_status ? 0 : 1;
8767 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008768}
8769
Jeff Johnson295189b2012-06-20 16:38:30 -07008770/**---------------------------------------------------------------------------
8771
Jeff Johnson76052702013-04-16 13:55:05 -07008772 \brief fwpath_changed_handler() - Handler Function
8773
8774 Handle changes to the fwpath parameter
8775
8776 \return - 0 for success, non zero for failure
8777
8778 --------------------------------------------------------------------------*/
8779static int fwpath_changed_handler(const char *kmessage,
8780 struct kernel_param *kp)
8781{
8782 int ret;
8783
8784 ret = param_set_copystring(kmessage, kp);
8785 if (0 == ret)
8786 ret = kickstart_driver();
8787 return ret;
8788}
8789
8790/**---------------------------------------------------------------------------
8791
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008792 \brief con_mode_handler() -
8793
8794 Handler function for module param con_mode when it is changed by userspace
8795 Dynamically linked - do nothing
8796 Statically linked - exit and init driver, as in rmmod and insmod
8797
Jeff Johnson76052702013-04-16 13:55:05 -07008798 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008799
Jeff Johnson76052702013-04-16 13:55:05 -07008800 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008801
8802 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07008803static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008804{
Jeff Johnson76052702013-04-16 13:55:05 -07008805 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008806
Jeff Johnson76052702013-04-16 13:55:05 -07008807 ret = param_set_int(kmessage, kp);
8808 if (0 == ret)
8809 ret = kickstart_driver();
8810 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008811}
8812#endif /* #ifdef MODULE */
8813
8814/**---------------------------------------------------------------------------
8815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 \brief hdd_get_conparam() -
8817
8818 This is the driver exit point (invoked when module is unloaded using rmmod)
8819
8820 \param - None
8821
8822 \return - tVOS_CON_MODE
8823
8824 --------------------------------------------------------------------------*/
8825tVOS_CON_MODE hdd_get_conparam ( void )
8826{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008827#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008829#else
8830 return (tVOS_CON_MODE)curr_con_mode;
8831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008832}
8833void hdd_set_conparam ( v_UINT_t newParam )
8834{
8835 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008836#ifndef MODULE
8837 curr_con_mode = con_mode;
8838#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008839}
8840/**---------------------------------------------------------------------------
8841
8842 \brief hdd_softap_sta_deauth() - function
8843
8844 This to take counter measure to handle deauth req from HDD
8845
8846 \param - pAdapter - Pointer to the HDD
8847
8848 \param - enable - boolean value
8849
8850 \return - None
8851
8852 --------------------------------------------------------------------------*/
8853
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008854VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008855{
Jeff Johnson295189b2012-06-20 16:38:30 -07008856 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008857 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07008858
8859 ENTER();
8860
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008861 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
8862 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008863
8864 //Ignore request to deauth bcmc station
8865 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008866 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07008867
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008868 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07008869
8870 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008871 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07008872}
8873
8874/**---------------------------------------------------------------------------
8875
8876 \brief hdd_softap_sta_disassoc() - function
8877
8878 This to take counter measure to handle deauth req from HDD
8879
8880 \param - pAdapter - Pointer to the HDD
8881
8882 \param - enable - boolean value
8883
8884 \return - None
8885
8886 --------------------------------------------------------------------------*/
8887
8888void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
8889{
8890 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
8891
8892 ENTER();
8893
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308894 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008895
8896 //Ignore request to disassoc bcmc station
8897 if( pDestMacAddress[0] & 0x1 )
8898 return;
8899
8900 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
8901}
8902
8903void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
8904{
8905 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
8906
8907 ENTER();
8908
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308909 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008910
8911 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
8912}
8913
Jeff Johnson295189b2012-06-20 16:38:30 -07008914/**---------------------------------------------------------------------------
8915 *
8916 * \brief hdd_get__concurrency_mode() -
8917 *
8918 *
8919 * \param - None
8920 *
8921 * \return - CONCURRENCY MODE
8922 *
8923 * --------------------------------------------------------------------------*/
8924tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
8925{
8926 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
8927 hdd_context_t *pHddCtx;
8928
8929 if (NULL != pVosContext)
8930 {
8931 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
8932 if (NULL != pHddCtx)
8933 {
8934 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
8935 }
8936 }
8937
8938 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008939 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 return VOS_STA;
8941}
8942
8943/* Decide whether to allow/not the apps power collapse.
8944 * Allow apps power collapse if we are in connected state.
8945 * if not, allow only if we are in IMPS */
8946v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
8947{
8948 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08008949 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08008950 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 hdd_config_t *pConfig = pHddCtx->cfg_ini;
8952 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8953 hdd_adapter_t *pAdapter = NULL;
8954 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08008955 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
Jeff Johnson295189b2012-06-20 16:38:30 -07008957 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8958 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008959
Yathish9f22e662012-12-10 14:21:35 -08008960 concurrent_state = hdd_get_concurrency_mode();
8961
8962#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8963 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
8964 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
8965 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
8966 return TRUE;
8967#endif
8968
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 /*loop through all adapters. TBD fix for Concurrency */
8970 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8971 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8972 {
8973 pAdapter = pAdapterNode->pAdapter;
8974 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
8975 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
8976 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08008977 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08008979 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08008980 (eANI_BOOLEAN_TRUE == scanRspPending) ||
8981 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08008983 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08008984 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
8985 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 return FALSE;
8987 }
8988 }
8989 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8990 pAdapterNode = pNext;
8991 }
8992 return TRUE;
8993}
8994
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08008995/* Decides whether to send suspend notification to Riva
8996 * if any adapter is in BMPS; then it is required */
8997v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
8998{
8999 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9000 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9001
9002 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9003 {
9004 return TRUE;
9005 }
9006 return FALSE;
9007}
9008
Jeff Johnson295189b2012-06-20 16:38:30 -07009009void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9010{
9011 switch(mode)
9012 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009013 case VOS_STA_MODE:
9014 case VOS_P2P_CLIENT_MODE:
9015 case VOS_P2P_GO_MODE:
9016 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009017 pHddCtx->concurrency_mode |= (1 << mode);
9018 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 break;
9020 default:
9021 break;
9022
9023 }
9024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9025 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9026}
9027
9028
9029void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9030{
9031 switch(mode)
9032 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009033 case VOS_STA_MODE:
9034 case VOS_P2P_CLIENT_MODE:
9035 case VOS_P2P_GO_MODE:
9036 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 pHddCtx->no_of_sessions[mode]--;
9038 if (!(pHddCtx->no_of_sessions[mode]))
9039 pHddCtx->concurrency_mode &= (~(1 << mode));
9040 break;
9041 default:
9042 break;
9043 }
9044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9045 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9046}
9047
Jeff Johnsone7245742012-09-05 17:12:55 -07009048/**---------------------------------------------------------------------------
9049 *
9050 * \brief wlan_hdd_restart_init
9051 *
9052 * This function initalizes restart timer/flag. An internal function.
9053 *
9054 * \param - pHddCtx
9055 *
9056 * \return - None
9057 *
9058 * --------------------------------------------------------------------------*/
9059
9060static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9061{
9062 /* Initialize */
9063 pHddCtx->hdd_restart_retries = 0;
9064 atomic_set(&pHddCtx->isRestartInProgress, 0);
9065 vos_timer_init(&pHddCtx->hdd_restart_timer,
9066 VOS_TIMER_TYPE_SW,
9067 wlan_hdd_restart_timer_cb,
9068 pHddCtx);
9069}
9070/**---------------------------------------------------------------------------
9071 *
9072 * \brief wlan_hdd_restart_deinit
9073 *
9074 * This function cleans up the resources used. An internal function.
9075 *
9076 * \param - pHddCtx
9077 *
9078 * \return - None
9079 *
9080 * --------------------------------------------------------------------------*/
9081
9082static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9083{
9084
9085 VOS_STATUS vos_status;
9086 /* Block any further calls */
9087 atomic_set(&pHddCtx->isRestartInProgress, 1);
9088 /* Cleanup */
9089 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9090 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009091 hddLog(LOGW, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009092 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9093 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009094 hddLog(LOGW, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009095
9096}
9097
9098/**---------------------------------------------------------------------------
9099 *
9100 * \brief wlan_hdd_framework_restart
9101 *
9102 * This function uses a cfg80211 API to start a framework initiated WLAN
9103 * driver module unload/load.
9104 *
9105 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9106 *
9107 *
9108 * \param - pHddCtx
9109 *
9110 * \return - VOS_STATUS_SUCCESS: Success
9111 * VOS_STATUS_E_EMPTY: Adapter is Empty
9112 * VOS_STATUS_E_NOMEM: No memory
9113
9114 * --------------------------------------------------------------------------*/
9115
9116static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9117{
9118 VOS_STATUS status = VOS_STATUS_SUCCESS;
9119 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009120 int len = (sizeof (struct ieee80211_mgmt));
9121 struct ieee80211_mgmt *mgmt = NULL;
9122
9123 /* Prepare the DEAUTH managment frame with reason code */
9124 mgmt = kzalloc(len, GFP_KERNEL);
9125 if(mgmt == NULL)
9126 {
9127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9128 "%s: memory allocation failed (%d bytes)", __func__, len);
9129 return VOS_STATUS_E_NOMEM;
9130 }
9131 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009132
9133 /* Iterate over all adapters/devices */
9134 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9135 do
9136 {
9137 if( (status == VOS_STATUS_SUCCESS) &&
9138 pAdapterNode &&
9139 pAdapterNode->pAdapter)
9140 {
9141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9142 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9143 pAdapterNode->pAdapter->dev->name,
9144 pAdapterNode->pAdapter->device_mode,
9145 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009146 /*
9147 * CFG80211 event to restart the driver
9148 *
9149 * 'cfg80211_send_unprot_deauth' sends a
9150 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9151 * of SME(Linux Kernel) state machine.
9152 *
9153 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9154 * the driver.
9155 *
9156 */
9157
9158 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009159 }
9160 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9161 pAdapterNode = pNext;
9162 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9163
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009164
9165 /* Free the allocated management frame */
9166 kfree(mgmt);
9167
Jeff Johnsone7245742012-09-05 17:12:55 -07009168 /* Retry until we unload or reach max count */
9169 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9170 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9171
9172 return status;
9173
9174}
9175/**---------------------------------------------------------------------------
9176 *
9177 * \brief wlan_hdd_restart_timer_cb
9178 *
9179 * Restart timer callback. An internal function.
9180 *
9181 * \param - User data:
9182 *
9183 * \return - None
9184 *
9185 * --------------------------------------------------------------------------*/
9186
9187void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9188{
9189 hdd_context_t *pHddCtx = usrDataForCallback;
9190 wlan_hdd_framework_restart(pHddCtx);
9191 return;
9192
9193}
9194
9195
9196/**---------------------------------------------------------------------------
9197 *
9198 * \brief wlan_hdd_restart_driver
9199 *
9200 * This function sends an event to supplicant to restart the WLAN driver.
9201 *
9202 * This function is called from vos_wlanRestart.
9203 *
9204 * \param - pHddCtx
9205 *
9206 * \return - VOS_STATUS_SUCCESS: Success
9207 * VOS_STATUS_E_EMPTY: Adapter is Empty
9208 * VOS_STATUS_E_ALREADY: Request already in progress
9209
9210 * --------------------------------------------------------------------------*/
9211VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9212{
9213 VOS_STATUS status = VOS_STATUS_SUCCESS;
9214
9215 /* A tight check to make sure reentrancy */
9216 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9217 {
9218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9219 "%s: WLAN restart is already in progress", __func__);
9220
9221 return VOS_STATUS_E_ALREADY;
9222 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009223 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009224#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009225 wcnss_reset_intr();
9226#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009227
Jeff Johnsone7245742012-09-05 17:12:55 -07009228 return status;
9229}
9230
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009231/*
9232 * API to find if there is any STA or P2P-Client is connected
9233 */
9234VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9235{
9236 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9237}
Jeff Johnsone7245742012-09-05 17:12:55 -07009238
Jeff Johnson295189b2012-06-20 16:38:30 -07009239//Register the module init/exit functions
9240module_init(hdd_module_init);
9241module_exit(hdd_module_exit);
9242
9243MODULE_LICENSE("Dual BSD/GPL");
9244MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9245MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9246
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009247module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9248 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009249
Jeff Johnson76052702013-04-16 13:55:05 -07009250module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009251 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009252
9253module_param(enable_dfs_chan_scan, int,
9254 S_IRUSR | S_IRGRP | S_IROTH);
9255
9256module_param(enable_11d, int,
9257 S_IRUSR | S_IRGRP | S_IROTH);
9258
9259module_param(country_code, charp,
9260 S_IRUSR | S_IRGRP | S_IROTH);