blob: f442f4f6b93d660e9399380417a1389c3fe738bd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/*========================================================================
31
32 \file wlan_hdd_main.c
33
34 \brief WLAN Host Device Driver implementation
35
36 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
37
38 Qualcomm Confidential and Proprietary.
39
40 ========================================================================*/
41
42/**=========================================================================
43
44 EDIT HISTORY FOR FILE
45
46
47 This section contains comments describing changes made to the module.
48 Notice that changes are listed in reverse chronological order.
49
50
51 $Header:$ $DateTime: $ $Author: $
52
53
54 when who what, where, why
55 -------- --- --------------------------------------------------------
56 04/5/09 Shailender Created module.
57 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
58 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
59 ==========================================================================*/
60
61/*--------------------------------------------------------------------------
62 Include Files
63 ------------------------------------------------------------------------*/
64//#include <wlan_qct_driver.h>
65#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_api.h>
67#include <vos_sched.h>
68#include <vos_power.h>
69#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
84#include <wlan_hdd_wowl.h>
85#include <wlan_hdd_misc.h>
86#include <wlan_hdd_wext.h>
87#ifdef WLAN_BTAMP_FEATURE
88#include <bap_hdd_main.h>
89#include <bapInternal.h>
90#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053091#include "wlan_hdd_trace.h"
92#include "vos_types.h"
93#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070094#include <linux/wireless.h>
95#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053096#include <linux/inetdevice.h>
97#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include "wlan_hdd_cfg80211.h"
99#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700101int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#include "sapApi.h"
103#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700104#include <linux/ctype.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#include <mach/subsystem_restart.h>
106#include <wlan_hdd_hostapd.h>
107#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include "wlan_hdd_dev_pwr.h"
110#ifdef WLAN_BTAMP_FEATURE
111#include "bap_hdd_misc.h"
112#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800115#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530116#ifdef FEATURE_WLAN_TDLS
117#include "wlan_hdd_tdls.h"
118#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700119#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700120
121#ifdef MODULE
122#define WLAN_MODULE_NAME module_name(THIS_MODULE)
123#else
124#define WLAN_MODULE_NAME "wlan"
125#endif
126
127#ifdef TIMER_MANAGER
128#define TIMER_MANAGER_STR " +TIMER_MANAGER"
129#else
130#define TIMER_MANAGER_STR ""
131#endif
132
133#ifdef MEMORY_DEBUG
134#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
135#else
136#define MEMORY_DEBUG_STR ""
137#endif
138
139/* the Android framework expects this param even though we don't use it */
140#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700141static char fwpath_buffer[BUF_LEN];
142static struct kparam_string fwpath = {
143 .string = fwpath_buffer,
144 .maxlen = BUF_LEN,
145};
Arif Hussain66559122013-11-21 10:11:40 -0800146
147static char *country_code;
148static int enable_11d = -1;
149static int enable_dfs_chan_scan = -1;
150
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700151#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700152static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700153#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700154
Jeff Johnsone7245742012-09-05 17:12:55 -0700155/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800156 * spinlock for synchronizing asynchronous request/response
157 * (full description of use in wlan_hdd_main.h)
158 */
159DEFINE_SPINLOCK(hdd_context_lock);
160
161/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700162 * The rate at which the driver sends RESTART event to supplicant
163 * once the function 'vos_wlanRestart()' is called
164 *
165 */
166#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
167#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700168
169/*
170 * Size of Driver command strings from upper layer
171 */
172#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
173#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
174
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700175#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
176#define TID_MIN_VALUE 0
177#define TID_MAX_VALUE 15
178static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
179 tAniTrafStrmMetrics* pTsmMetrics);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -0800180static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
181 tCsrCcxBeaconReq *pCcxBcnReq);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700182#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
183
Srinivas Girigowda4081bb12014-01-06 17:12:58 -0800184#define WLAN_PRIV_DATA_MAX_LEN 4096
185
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700186/*
187 * Driver miracast parameters 0-Disabled
188 * 1-Source, 2-Sink
189 */
190#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
191#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
192
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800193#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700194static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700195#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700196/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700197static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700198
199//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700200static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
201static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
202static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
203void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800204void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700205
Jeff Johnson295189b2012-06-20 16:38:30 -0700206v_U16_t hdd_select_queue(struct net_device *dev,
207 struct sk_buff *skb);
208
209#ifdef WLAN_FEATURE_PACKET_FILTERING
210static void hdd_set_multicast_list(struct net_device *dev);
211#endif
212
213void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
214
215extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Amar Singhal0a402232013-10-11 20:57:16 -0700216
Srinivas Girigowdade697412013-02-14 16:31:48 -0800217#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
218void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
219static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700220static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
221 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
222 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700223static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
224 tANI_U8 *pTargetApBssid,
225 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800226#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700227#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
228VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
229#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
230
Mihir Shetee1093ba2014-01-21 20:13:32 +0530231static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
232
Jeff Johnson295189b2012-06-20 16:38:30 -0700233static int hdd_netdev_notifier_call(struct notifier_block * nb,
234 unsigned long state,
235 void *ndev)
236{
237 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700239 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700240#ifdef WLAN_BTAMP_FEATURE
241 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700242#endif
243
244 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700245 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700246 (strncmp(dev->name, "p2p", 3)))
247 return NOTIFY_DONE;
248
Jeff Johnson295189b2012-06-20 16:38:30 -0700249 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700250 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700251
Jeff Johnson27cee452013-03-27 11:10:24 -0700252 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700253 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800254 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 VOS_ASSERT(0);
256 return NOTIFY_DONE;
257 }
258
Jeff Johnson27cee452013-03-27 11:10:24 -0700259 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
260 if (NULL == pHddCtx)
261 {
262 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
263 VOS_ASSERT(0);
264 return NOTIFY_DONE;
265 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800266 if (pHddCtx->isLogpInProgress)
267 return NOTIFY_DONE;
268
Jeff Johnson27cee452013-03-27 11:10:24 -0700269
270 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
271 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273 switch (state) {
274 case NETDEV_REGISTER:
275 break;
276
277 case NETDEV_UNREGISTER:
278 break;
279
280 case NETDEV_UP:
281 break;
282
283 case NETDEV_DOWN:
284 break;
285
286 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700287 if(TRUE == pAdapter->isLinkUpSvcNeeded)
288 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700289 break;
290
291 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700292 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530294 long result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800295 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530296 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId,
297 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800299 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530301 if (result <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700302 {
303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530304 "%s: Timeout occurred while waiting for abortscan %ld",
305 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 }
307 }
308 else
309 {
310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700311 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 }
313#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700315 status = WLANBAP_StopAmp();
316 if(VOS_STATUS_SUCCESS != status )
317 {
318 pHddCtx->isAmpAllowed = VOS_TRUE;
319 hddLog(VOS_TRACE_LEVEL_FATAL,
320 "%s: Failed to stop AMP", __func__);
321 }
322 else
323 {
324 //a state m/c implementation in PAL is TBD to avoid this delay
325 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700326 if ( pHddCtx->isAmpAllowed )
327 {
328 WLANBAP_DeregisterFromHCI();
329 pHddCtx->isAmpAllowed = VOS_FALSE;
330 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 }
332#endif //WLAN_BTAMP_FEATURE
333 break;
334
335 default:
336 break;
337 }
338
339 return NOTIFY_DONE;
340}
341
342struct notifier_block hdd_netdev_notifier = {
343 .notifier_call = hdd_netdev_notifier_call,
344};
345
346/*---------------------------------------------------------------------------
347 * Function definitions
348 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700349void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
350void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700352static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700353#ifndef MODULE
354/* current con_mode - used only for statically linked driver
355 * con_mode is changed by userspace to indicate a mode change which will
356 * result in calling the module exit and init functions. The module
357 * exit function will clean up based on the value of con_mode prior to it
358 * being changed by userspace. So curr_con_mode records the current con_mode
359 * for exit when con_mode becomes the next mode for init
360 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700361static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700362#endif
363
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800364/**---------------------------------------------------------------------------
365
366 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
367
368 Called immediately after the cfg.ini is read in order to configure
369 the desired trace levels.
370
371 \param - moduleId - module whose trace level is being configured
372 \param - bitmask - bitmask of log levels to be enabled
373
374 \return - void
375
376 --------------------------------------------------------------------------*/
377static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
378{
379 wpt_tracelevel level;
380
381 /* if the bitmask is the default value, then a bitmask was not
382 specified in cfg.ini, so leave the logging level alone (it
383 will remain at the "compiled in" default value) */
384 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
385 {
386 return;
387 }
388
389 /* a mask was specified. start by disabling all logging */
390 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
391
392 /* now cycle through the bitmask until all "set" bits are serviced */
393 level = VOS_TRACE_LEVEL_FATAL;
394 while (0 != bitmask)
395 {
396 if (bitmask & 1)
397 {
398 vos_trace_setValue(moduleId, level, 1);
399 }
400 level++;
401 bitmask >>= 1;
402 }
403}
404
405
Jeff Johnson295189b2012-06-20 16:38:30 -0700406/**---------------------------------------------------------------------------
407
408 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
409
410 Called immediately after the cfg.ini is read in order to configure
411 the desired trace levels in the WDI.
412
413 \param - moduleId - module whose trace level is being configured
414 \param - bitmask - bitmask of log levels to be enabled
415
416 \return - void
417
418 --------------------------------------------------------------------------*/
419static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
420{
421 wpt_tracelevel level;
422
423 /* if the bitmask is the default value, then a bitmask was not
424 specified in cfg.ini, so leave the logging level alone (it
425 will remain at the "compiled in" default value) */
426 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
427 {
428 return;
429 }
430
431 /* a mask was specified. start by disabling all logging */
432 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
433
434 /* now cycle through the bitmask until all "set" bits are serviced */
435 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
436 while (0 != bitmask)
437 {
438 if (bitmask & 1)
439 {
440 wpalTraceSetLevel(moduleId, level, 1);
441 }
442 level++;
443 bitmask >>= 1;
444 }
445}
Jeff Johnson295189b2012-06-20 16:38:30 -0700446
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530447/*
448 * FUNCTION: wlan_hdd_validate_context
449 * This function is used to check the HDD context
450 */
451int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
452{
453 ENTER();
454
455 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
456 {
457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
458 "%s: HDD context is Null", __func__);
459 return -ENODEV;
460 }
461
462 if (pHddCtx->isLogpInProgress)
463 {
464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
465 "%s: LOGP in Progress. Ignore!!!", __func__);
466 return -EAGAIN;
467 }
468
469 if (pHddCtx->isLoadUnloadInProgress)
470 {
471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
472 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
473 return -EAGAIN;
474 }
475 return 0;
476}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700477#ifdef CONFIG_ENABLE_LINUX_REG
478void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
479{
480 hdd_adapter_t *pAdapter = NULL;
481 hdd_station_ctx_t *pHddStaCtx = NULL;
482 eCsrPhyMode phyMode;
483 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530484
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700485 if (NULL == pHddCtx)
486 {
487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
488 "HDD Context is null !!");
489 return ;
490 }
491
492 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
493 if (NULL == pAdapter)
494 {
495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
496 "pAdapter is null !!");
497 return ;
498 }
499
500 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
501 if (NULL == pHddStaCtx)
502 {
503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
504 "pHddStaCtx is null !!");
505 return ;
506 }
507
508 cfg_param = pHddCtx->cfg_ini;
509 if (NULL == cfg_param)
510 {
511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
512 "cfg_params not available !!");
513 return ;
514 }
515
516 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
517
518 if (!pHddCtx->isVHT80Allowed)
519 {
520 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
521 (eCSR_DOT11_MODE_11ac == phyMode) ||
522 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
523 {
524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
525 "Setting phymode to 11n!!");
526 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
527 }
528 }
529 else
530 {
531 /*New country Supports 11ac as well resetting value back from .ini*/
532 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
533 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
534 return ;
535 }
536
537 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
538 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
539 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
540 {
541 VOS_STATUS vosStatus;
542
543 // need to issue a disconnect to CSR.
544 INIT_COMPLETION(pAdapter->disconnect_comp_var);
545 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
546 pAdapter->sessionId,
547 eCSR_DISCONNECT_REASON_UNSPECIFIED );
548
549 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530550 {
551 long ret;
552
553 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700554 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530555 if (0 >= ret)
556 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
557 ret);
558 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700559
560 }
561}
562#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530563void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
564{
565 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
566 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
567 hdd_config_t *cfg_param;
568 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530569 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530570
571 if (NULL == pHddCtx)
572 {
573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
574 "HDD Context is null !!");
575 return ;
576 }
577
578 cfg_param = pHddCtx->cfg_ini;
579
580 if (NULL == cfg_param)
581 {
582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
583 "cfg_params not available !!");
584 return ;
585 }
586
587 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
588
589 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
590 {
591 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
592 (eCSR_DOT11_MODE_11ac == phyMode) ||
593 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
596 "Setting phymode to 11n!!");
597 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
598 }
599 }
600 else
601 {
602 /*New country Supports 11ac as well resetting value back from .ini*/
603 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
604 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
605 return ;
606 }
607
608 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
609 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
610 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
611 {
612 VOS_STATUS vosStatus;
613
614 // need to issue a disconnect to CSR.
615 INIT_COMPLETION(pAdapter->disconnect_comp_var);
616 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
617 pAdapter->sessionId,
618 eCSR_DISCONNECT_REASON_UNSPECIFIED );
619
620 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530621 {
622 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530623 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530624 if (ret <= 0)
625 {
626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
627 "wait on disconnect_comp_var is failed %ld", ret);
628 }
629 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530630
631 }
632}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700633#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530634
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700635void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
636{
637 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
638 hdd_config_t *cfg_param;
639
640 if (NULL == pHddCtx)
641 {
642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
643 "HDD Context is null !!");
644 return ;
645 }
646
647 cfg_param = pHddCtx->cfg_ini;
648
649 if (NULL == cfg_param)
650 {
651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
652 "cfg_params not available !!");
653 return ;
654 }
655
656 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
657 {
658 /*New country doesn't support DFS */
659 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
660 }
661 else
662 {
663 /*New country Supports DFS as well resetting value back from .ini*/
664 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
665 }
666
667}
668
Rajeev79dbe4c2013-10-05 11:03:42 +0530669#ifdef FEATURE_WLAN_BATCH_SCAN
670
671/**---------------------------------------------------------------------------
672
673 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
674 input string
675
676 This function extracts assigned integer from string in below format:
677 "STRING=10" : extracts integer 10 from this string
678
679 \param - pInPtr Pointer to input string
680 \param - base Base for string to int conversion(10 for decimal 16 for hex)
681 \param - pOutPtr Pointer to variable in which extracted integer needs to be
682 assigned
683 \param - pLastArg to tell whether it is last arguement in input string or
684 not
685
686 \return - NULL for failure cases
687 pointer to next arguement in input string for success cases
688 --------------------------------------------------------------------------*/
689static tANI_U8 *
690hdd_extract_assigned_int_from_str
691(
692 tANI_U8 *pInPtr,
693 tANI_U8 base,
694 tANI_U32 *pOutPtr,
695 tANI_U8 *pLastArg
696)
697{
698 int tempInt;
699 int v = 0;
700 char buf[32];
701 int val = 0;
702 *pLastArg = FALSE;
703
704 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
705 if (NULL == pInPtr)
706 {
707 return NULL;
708 }
709
710 pInPtr++;
711
712 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
713
714 val = sscanf(pInPtr, "%32s ", buf);
715 if (val < 0 && val > strlen(pInPtr))
716 {
717 return NULL;
718 }
719 pInPtr += val;
720 v = kstrtos32(buf, base, &tempInt);
721 if (v < 0)
722 {
723 return NULL;
724 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800725 if (tempInt < 0)
726 {
727 tempInt = 0;
728 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530729 *pOutPtr = tempInt;
730
731 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
732 if (NULL == pInPtr)
733 {
734 *pLastArg = TRUE;
735 return NULL;
736 }
737 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
738
739 return pInPtr;
740}
741
742/**---------------------------------------------------------------------------
743
744 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
745 input string
746
747 This function extracts assigned character from string in below format:
748 "STRING=A" : extracts char 'A' from this string
749
750 \param - pInPtr Pointer to input string
751 \param - pOutPtr Pointer to variable in which extracted char needs to be
752 assigned
753 \param - pLastArg to tell whether it is last arguement in input string or
754 not
755
756 \return - NULL for failure cases
757 pointer to next arguement in input string for success cases
758 --------------------------------------------------------------------------*/
759static tANI_U8 *
760hdd_extract_assigned_char_from_str
761(
762 tANI_U8 *pInPtr,
763 tANI_U8 *pOutPtr,
764 tANI_U8 *pLastArg
765)
766{
767 *pLastArg = FALSE;
768
769 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
770 if (NULL == pInPtr)
771 {
772 return NULL;
773 }
774
775 pInPtr++;
776
777 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
778
779 *pOutPtr = *pInPtr;
780
781 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
782 if (NULL == pInPtr)
783 {
784 *pLastArg = TRUE;
785 return NULL;
786 }
787 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
788
789 return pInPtr;
790}
791
792
793/**---------------------------------------------------------------------------
794
795 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
796
797 This function parses set batch scan command in below format:
798 WLS_BATCHING_SET <space> followed by below arguements
799 "SCANFREQ=XX" : Optional defaults to 30 sec
800 "MSCAN=XX" : Required number of scans to attempt to batch
801 "BESTN=XX" : Best Network (RSSI) defaults to 16
802 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
803 A. implies only 5 GHz , B. implies only 2.4GHz
804 "RTT=X" : optional defaults to 0
805 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
806 error
807
808 For example input commands:
809 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
810 translated into set batch scan with following parameters:
811 a) Frequence 60 seconds
812 b) Batch 10 scans together
813 c) Best RSSI to be 20
814 d) 5GHz band only
815 e) RTT is equal to 0
816
817 \param - pValue Pointer to input channel list
818 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
819
820 \return - 0 for success non-zero for failure
821
822 --------------------------------------------------------------------------*/
823static int
824hdd_parse_set_batchscan_command
825(
826 tANI_U8 *pValue,
827 tSirSetBatchScanReq *pHddSetBatchScanReq
828)
829{
830 tANI_U8 *inPtr = pValue;
831 tANI_U8 val = 0;
832 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800833 tANI_U32 nScanFreq;
834 tANI_U32 nMscan;
835 tANI_U32 nBestN;
836 tANI_U8 ucRfBand;
837 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800838 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530839
840 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800841 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
842 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
843 nRtt = 0;
844 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530845
846 /*go to space after WLS_BATCHING_SET command*/
847 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
848 /*no argument after the command*/
849 if (NULL == inPtr)
850 {
851 return -EINVAL;
852 }
853
854 /*no space after the command*/
855 else if (SPACE_ASCII_VALUE != *inPtr)
856 {
857 return -EINVAL;
858 }
859
860 /*removing empty spaces*/
861 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
862
863 /*no argument followed by spaces*/
864 if ('\0' == *inPtr)
865 {
866 return -EINVAL;
867 }
868
869 /*check and parse SCANFREQ*/
870 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
871 {
872 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800873 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800874
Rajeev Kumarc933d982013-11-18 20:04:20 -0800875 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800876 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800877 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800878 }
879
Rajeev79dbe4c2013-10-05 11:03:42 +0530880 if ( (NULL == inPtr) || (TRUE == lastArg))
881 {
882 return -EINVAL;
883 }
884 }
885
886 /*check and parse MSCAN*/
887 if ((strncmp(inPtr, "MSCAN", 5) == 0))
888 {
889 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800890 &nMscan, &lastArg);
891
892 if (0 == nMscan)
893 {
894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
895 "invalid MSCAN=%d", nMscan);
896 return -EINVAL;
897 }
898
Rajeev79dbe4c2013-10-05 11:03:42 +0530899 if (TRUE == lastArg)
900 {
901 goto done;
902 }
903 else if (NULL == inPtr)
904 {
905 return -EINVAL;
906 }
907 }
908 else
909 {
910 return -EINVAL;
911 }
912
913 /*check and parse BESTN*/
914 if ((strncmp(inPtr, "BESTN", 5) == 0))
915 {
916 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800917 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800918
Rajeev Kumarc933d982013-11-18 20:04:20 -0800919 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800920 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800921 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800922 }
923
Rajeev79dbe4c2013-10-05 11:03:42 +0530924 if (TRUE == lastArg)
925 {
926 goto done;
927 }
928 else if (NULL == inPtr)
929 {
930 return -EINVAL;
931 }
932 }
933
934 /*check and parse CHANNEL*/
935 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
936 {
937 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800938
Rajeev79dbe4c2013-10-05 11:03:42 +0530939 if (('A' == val) || ('a' == val))
940 {
c_hpothuebf89732014-02-25 13:00:24 +0530941 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530942 }
943 else if (('B' == val) || ('b' == val))
944 {
c_hpothuebf89732014-02-25 13:00:24 +0530945 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530946 }
947 else
948 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800949 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
950 }
951
952 if (TRUE == lastArg)
953 {
954 goto done;
955 }
956 else if (NULL == inPtr)
957 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 return -EINVAL;
959 }
960 }
961
962 /*check and parse RTT*/
963 if ((strncmp(inPtr, "RTT", 3) == 0))
964 {
965 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800966 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530967 if (TRUE == lastArg)
968 {
969 goto done;
970 }
971 if (NULL == inPtr)
972 {
973 return -EINVAL;
974 }
975 }
976
977
978done:
979
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800980 pHddSetBatchScanReq->scanFrequency = nScanFreq;
981 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
982 pHddSetBatchScanReq->bestNetwork = nBestN;
983 pHddSetBatchScanReq->rfBand = ucRfBand;
984 pHddSetBatchScanReq->rtt = nRtt;
985
Rajeev79dbe4c2013-10-05 11:03:42 +0530986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
987 "Received WLS_BATCHING_SET with SCANFREQ=%d "
988 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
989 pHddSetBatchScanReq->scanFrequency,
990 pHddSetBatchScanReq->numberOfScansToBatch,
991 pHddSetBatchScanReq->bestNetwork,
992 pHddSetBatchScanReq->rfBand,
993 pHddSetBatchScanReq->rtt);
994
995 return 0;
996}/*End of hdd_parse_set_batchscan_command*/
997
998/**---------------------------------------------------------------------------
999
1000 \brief hdd_set_batch_scan_req_callback () - This function is called after
1001 receiving set batch scan response from FW and it saves set batch scan
1002 response data FW to HDD context and sets the completion event on
1003 which hdd_ioctl is waiting
1004
1005 \param - callbackContext Pointer to HDD adapter
1006 \param - pRsp Pointer to set batch scan response data received from FW
1007
1008 \return - nothing
1009
1010 --------------------------------------------------------------------------*/
1011static void hdd_set_batch_scan_req_callback
1012(
1013 void *callbackContext,
1014 tSirSetBatchScanRsp *pRsp
1015)
1016{
1017 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1018 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1019
1020 /*sanity check*/
1021 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1022 {
1023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1024 "%s: Invalid pAdapter magic", __func__);
1025 VOS_ASSERT(0);
1026 return;
1027 }
1028 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1029
1030 /*save set batch scan response*/
1031 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1032
1033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1034 "Received set batch scan rsp from FW with nScansToBatch=%d",
1035 pHddSetBatchScanRsp->nScansToBatch);
1036
1037 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1038 complete(&pAdapter->hdd_set_batch_scan_req_var);
1039
1040 return;
1041}/*End of hdd_set_batch_scan_req_callback*/
1042
1043
1044/**---------------------------------------------------------------------------
1045
1046 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1047 info in hdd batch scan response queue
1048
1049 \param - pAdapter Pointer to hdd adapter
1050 \param - pAPMetaInfo Pointer to access point meta info
1051 \param - scanId scan ID of batch scan response
1052 \param - isLastAp tells whether AP is last AP in batch scan response or not
1053
1054 \return - nothing
1055
1056 --------------------------------------------------------------------------*/
1057static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1058 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1059{
1060 tHddBatchScanRsp *pHead;
1061 tHddBatchScanRsp *pNode;
1062 tHddBatchScanRsp *pPrev;
1063 tHddBatchScanRsp *pTemp;
1064 tANI_U8 ssidLen;
1065
1066 /*head of hdd batch scan response queue*/
1067 pHead = pAdapter->pBatchScanRsp;
1068
1069 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1070 if (NULL == pNode)
1071 {
1072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1073 "%s: Could not allocate memory", __func__);
1074 VOS_ASSERT(0);
1075 return;
1076 }
1077
1078 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1079 sizeof(pNode->ApInfo.bssid));
1080 ssidLen = strlen(pApMetaInfo->ssid);
1081 if (SIR_MAX_SSID_SIZE < ssidLen)
1082 {
1083 /*invalid scan result*/
1084 vos_mem_free(pNode);
1085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1086 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1087 return;
1088 }
1089 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1090 /*null terminate ssid*/
1091 pNode->ApInfo.ssid[ssidLen] = '\0';
1092 pNode->ApInfo.ch = pApMetaInfo->ch;
1093 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1094 pNode->ApInfo.age = pApMetaInfo->timestamp;
1095 pNode->ApInfo.batchId = scanId;
1096 pNode->ApInfo.isLastAp = isLastAp;
1097
1098 pNode->pNext = NULL;
1099 if (NULL == pHead)
1100 {
1101 pAdapter->pBatchScanRsp = pNode;
1102 }
1103 else
1104 {
1105 pTemp = pHead;
1106 while (NULL != pTemp)
1107 {
1108 pPrev = pTemp;
1109 pTemp = pTemp->pNext;
1110 }
1111 pPrev->pNext = pNode;
1112 }
1113
1114 return;
1115}/*End of hdd_populate_batch_scan_rsp_queue*/
1116
1117/**---------------------------------------------------------------------------
1118
1119 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1120 receiving batch scan response indication from FW. It saves get batch scan
1121 response data in HDD batch scan response queue. This callback sets the
1122 completion event on which hdd_ioctl is waiting only after getting complete
1123 batch scan response data from FW
1124
1125 \param - callbackContext Pointer to HDD adapter
1126 \param - pRsp Pointer to get batch scan response data received from FW
1127
1128 \return - nothing
1129
1130 --------------------------------------------------------------------------*/
1131static void hdd_batch_scan_result_ind_callback
1132(
1133 void *callbackContext,
1134 void *pRsp
1135)
1136{
1137 v_BOOL_t isLastAp;
1138 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001139 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301140 tANI_U32 numberScanList;
1141 tANI_U32 nextScanListOffset;
1142 tANI_U32 nextApMetaInfoOffset;
1143 hdd_adapter_t* pAdapter;
1144 tpSirBatchScanList pScanList;
1145 tpSirBatchScanNetworkInfo pApMetaInfo;
1146 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1147 tSirSetBatchScanReq *pReq;
1148
1149 pAdapter = (hdd_adapter_t *)callbackContext;
1150 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001151 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301152 {
1153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1154 "%s: Invalid pAdapter magic", __func__);
1155 VOS_ASSERT(0);
1156 return;
1157 }
1158
1159 /*initialize locals*/
1160 pReq = &pAdapter->hddSetBatchScanReq;
1161 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1162 isLastAp = FALSE;
1163 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001164 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301165 numberScanList = 0;
1166 nextScanListOffset = 0;
1167 nextApMetaInfoOffset = 0;
1168 pScanList = NULL;
1169 pApMetaInfo = NULL;
1170
1171 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1172 {
1173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1174 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1175 isLastAp = TRUE;
1176 goto done;
1177 }
1178
1179 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "Batch scan rsp: numberScalList %d", numberScanList);
1182
1183 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1184 {
1185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1186 "%s: numberScanList %d", __func__, numberScanList);
1187 isLastAp = TRUE;
1188 goto done;
1189 }
1190
1191 while (numberScanList)
1192 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001193 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301194 nextScanListOffset);
1195 if (NULL == pScanList)
1196 {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1198 "%s: pScanList is %p", __func__, pScanList);
1199 isLastAp = TRUE;
1200 goto done;
1201 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001202 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001204 "Batch scan rsp: numApMetaInfo %d scanId %d",
1205 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301206
1207 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1208 {
1209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1210 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1211 isLastAp = TRUE;
1212 goto done;
1213 }
1214
Rajeev Kumarce651e42013-10-21 18:57:15 -07001215 /*Initialize next AP meta info offset for next scan list*/
1216 nextApMetaInfoOffset = 0;
1217
Rajeev79dbe4c2013-10-05 11:03:42 +05301218 while (numApMetaInfo)
1219 {
1220 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1221 nextApMetaInfoOffset);
1222 if (NULL == pApMetaInfo)
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
1229 /*calculate AP age*/
1230 pApMetaInfo->timestamp =
1231 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1232
1233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001234 "%s: bssId "MAC_ADDRESS_STR
1235 " ch %d rssi %d timestamp %d", __func__,
1236 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1237 pApMetaInfo->ch, pApMetaInfo->rssi,
1238 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301239
1240 /*mark last AP in batch scan response*/
1241 if ((TRUE == pBatchScanRsp->isLastResult) &&
1242 (1 == numberScanList) && (1 == numApMetaInfo))
1243 {
1244 isLastAp = TRUE;
1245 }
1246
1247 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1248 /*store batch scan repsonse in hdd queue*/
1249 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1250 pScanList->scanId, isLastAp);
1251 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1252
1253 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1254 numApMetaInfo--;
1255 }
1256
Rajeev Kumarce651e42013-10-21 18:57:15 -07001257 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1258 + (sizeof(tSirBatchScanNetworkInfo)
1259 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301260 numberScanList--;
1261 }
1262
1263done:
1264
1265 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1266 requested from hdd_ioctl*/
1267 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1268 (TRUE == isLastAp))
1269 {
1270 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1271 complete(&pAdapter->hdd_get_batch_scan_req_var);
1272 }
1273
1274 return;
1275}/*End of hdd_batch_scan_result_ind_callback*/
1276
1277/**---------------------------------------------------------------------------
1278
1279 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1280 response as per batch scan FR request format by putting proper markers
1281
1282 \param - pDest pointer to destination buffer
1283 \param - cur_len current length
1284 \param - tot_len total remaining size which can be written to user space
1285 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1286 \param - pAdapter Pointer to HDD adapter
1287
1288 \return - ret no of characters written
1289
1290 --------------------------------------------------------------------------*/
1291static tANI_U32
1292hdd_format_batch_scan_rsp
1293(
1294 tANI_U8 *pDest,
1295 tANI_U32 cur_len,
1296 tANI_U32 tot_len,
1297 tHddBatchScanRsp *pApMetaInfo,
1298 hdd_adapter_t* pAdapter
1299)
1300{
1301 tANI_U32 ret = 0;
1302 tANI_U32 rem_len = 0;
1303 tANI_U8 temp_len = 0;
1304 tANI_U8 temp_total_len = 0;
1305 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1306 tANI_U8 *pTemp = temp;
1307
1308 /*Batch scan reponse needs to be returned to user space in
1309 following format:
1310 "scancount=X\n" where X is the number of scans in current batch
1311 batch
1312 "trunc\n" optional present if current scan truncated
1313 "bssid=XX:XX:XX:XX:XX:XX\n"
1314 "ssid=XXXX\n"
1315 "freq=X\n" frequency in Mhz
1316 "level=XX\n"
1317 "age=X\n" ms
1318 "dist=X\n" cm (-1 if not available)
1319 "errror=X\n" (-1if not available)
1320 "====\n" (end of ap marker)
1321 "####\n" (end of scan marker)
1322 "----\n" (end of results)*/
1323 /*send scan result in above format to user space based on
1324 available length*/
1325 /*The GET response may have more data than the driver can return in its
1326 buffer. In that case the buffer should be filled to the nearest complete
1327 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1328 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1329 The final buffer should end with "----\n"*/
1330
1331 /*sanity*/
1332 if (cur_len > tot_len)
1333 {
1334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1335 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1336 return 0;
1337 }
1338 else
1339 {
1340 rem_len = (tot_len - cur_len);
1341 }
1342
1343 /*end scan marker*/
1344 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1345 {
1346 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1347 pTemp += temp_len;
1348 temp_total_len += temp_len;
1349 }
1350
1351 /*bssid*/
1352 temp_len = snprintf(pTemp, sizeof(temp),
1353 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1354 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1355 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1356 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1357 pTemp += temp_len;
1358 temp_total_len += temp_len;
1359
1360 /*ssid*/
1361 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1362 pApMetaInfo->ApInfo.ssid);
1363 pTemp += temp_len;
1364 temp_total_len += temp_len;
1365
1366 /*freq*/
1367 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001368 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301369 pTemp += temp_len;
1370 temp_total_len += temp_len;
1371
1372 /*level*/
1373 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1374 pApMetaInfo->ApInfo.rssi);
1375 pTemp += temp_len;
1376 temp_total_len += temp_len;
1377
1378 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001379 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301380 pApMetaInfo->ApInfo.age);
1381 pTemp += temp_len;
1382 temp_total_len += temp_len;
1383
1384 /*dist*/
1385 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1386 pTemp += temp_len;
1387 temp_total_len += temp_len;
1388
1389 /*error*/
1390 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1391 pTemp += temp_len;
1392 temp_total_len += temp_len;
1393
1394 /*end AP marker*/
1395 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*last AP in batch scan response*/
1400 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1401 {
1402 /*end scan marker*/
1403 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*end batch scan result marker*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001411
Rajeev79dbe4c2013-10-05 11:03:42 +05301412 }
1413
1414 if (temp_total_len < rem_len)
1415 {
1416 ret = temp_total_len + 1;
1417 strlcpy(pDest, temp, ret);
1418 pAdapter->isTruncated = FALSE;
1419 }
1420 else
1421 {
1422 pAdapter->isTruncated = TRUE;
1423 if (rem_len >= strlen("%%%%"))
1424 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001425 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301426 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001427 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301428 {
1429 ret = 0;
1430 }
1431 }
1432
1433 return ret;
1434
1435}/*End of hdd_format_batch_scan_rsp*/
1436
1437/**---------------------------------------------------------------------------
1438
1439 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1440 buffer starting with head of hdd batch scan response queue
1441
1442 \param - pAdapter Pointer to HDD adapter
1443 \param - pDest Pointer to user data buffer
1444 \param - cur_len current offset in user buffer
1445 \param - rem_len remaining no of bytes in user buffer
1446
1447 \return - number of bytes written in user buffer
1448
1449 --------------------------------------------------------------------------*/
1450
1451tANI_U32 hdd_populate_user_batch_scan_rsp
1452(
1453 hdd_adapter_t* pAdapter,
1454 tANI_U8 *pDest,
1455 tANI_U32 cur_len,
1456 tANI_U32 rem_len
1457)
1458{
1459 tHddBatchScanRsp *pHead;
1460 tHddBatchScanRsp *pPrev;
1461 tANI_U32 len;
1462
Rajeev79dbe4c2013-10-05 11:03:42 +05301463 pAdapter->isTruncated = FALSE;
1464
1465 /*head of hdd batch scan response queue*/
1466 pHead = pAdapter->pBatchScanRsp;
1467 while (pHead)
1468 {
1469 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1470 pAdapter);
1471 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001472 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301473 cur_len += len;
1474 if(TRUE == pAdapter->isTruncated)
1475 {
1476 /*result is truncated return rest of scan rsp in next req*/
1477 cur_len = rem_len;
1478 break;
1479 }
1480 pPrev = pHead;
1481 pHead = pHead->pNext;
1482 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001483 if (TRUE == pPrev->ApInfo.isLastAp)
1484 {
1485 pAdapter->prev_batch_id = 0;
1486 }
1487 else
1488 {
1489 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1490 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301491 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001492 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301493 }
1494
1495 return cur_len;
1496}/*End of hdd_populate_user_batch_scan_rsp*/
1497
1498/**---------------------------------------------------------------------------
1499
1500 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1501 scan response data from HDD queue to user space
1502 It does following in detail:
1503 a) if HDD has enough data in its queue then it 1st copies data to user
1504 space and then send get batch scan indication message to FW. In this
1505 case it does not wait on any event and batch scan response data will
1506 be populated in HDD response queue in MC thread context after receiving
1507 indication from FW
1508 b) else send get batch scan indication message to FW and wait on an event
1509 which will be set once HDD receives complete batch scan response from
1510 FW and then this function returns batch scan response to user space
1511
1512 \param - pAdapter Pointer to HDD adapter
1513 \param - pPrivData Pointer to priv_data
1514
1515 \return - 0 for success -EFAULT for failure
1516
1517 --------------------------------------------------------------------------*/
1518
1519int hdd_return_batch_scan_rsp_to_user
1520(
1521 hdd_adapter_t* pAdapter,
1522 hdd_priv_data_t *pPrivData,
1523 tANI_U8 *command
1524)
1525{
1526 tANI_U8 *pDest;
1527 tANI_U32 count = 0;
1528 tANI_U32 len = 0;
1529 tANI_U32 cur_len = 0;
1530 tANI_U32 rem_len = 0;
1531 eHalStatus halStatus;
1532 unsigned long rc;
1533 tSirTriggerBatchScanResultInd *pReq;
1534
1535 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1536 pReq->param = 0;/*batch scan client*/
1537 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1538 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1539
1540 cur_len = pPrivData->used_len;
1541 if (pPrivData->total_len > pPrivData->used_len)
1542 {
1543 rem_len = pPrivData->total_len - pPrivData->used_len;
1544 }
1545 else
1546 {
1547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1548 "%s: Invalid user data buffer total_len %d used_len %d",
1549 __func__, pPrivData->total_len, pPrivData->used_len);
1550 return -EFAULT;
1551 }
1552
1553 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1554 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1555 cur_len, rem_len);
1556 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1557
1558 /*enough scan result available in cache to return to user space or
1559 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001560 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301561 {
1562 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1563 halStatus = sme_TriggerBatchScanResultInd(
1564 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1565 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1566 pAdapter);
1567 if ( eHAL_STATUS_SUCCESS == halStatus )
1568 {
1569 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1570 {
1571 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1572 rc = wait_for_completion_timeout(
1573 &pAdapter->hdd_get_batch_scan_req_var,
1574 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1575 if (0 == rc)
1576 {
1577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1578 "%s: Timeout waiting to fetch batch scan rsp from fw",
1579 __func__);
1580 return -EFAULT;
1581 }
1582 }
1583
1584 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001585 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301586 pDest += len;
1587 cur_len += len;
1588
1589 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1590 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1591 cur_len, rem_len);
1592 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1593
1594 count = 0;
1595 len = (len - pPrivData->used_len);
1596 pDest = (command + pPrivData->used_len);
1597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001598 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301599 while(count < len)
1600 {
1601 printk("%c", *(pDest + count));
1602 count++;
1603 }
1604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1605 "%s: copy %d data to user buffer", __func__, len);
1606 if (copy_to_user(pPrivData->buf, pDest, len))
1607 {
1608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1609 "%s: failed to copy data to user buffer", __func__);
1610 return -EFAULT;
1611 }
1612 }
1613 else
1614 {
1615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1616 "sme_GetBatchScanScan returned failure halStatus %d",
1617 halStatus);
1618 return -EINVAL;
1619 }
1620 }
1621 else
1622 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301623 count = 0;
1624 len = (len - pPrivData->used_len);
1625 pDest = (command + pPrivData->used_len);
1626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001627 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301628 while(count < len)
1629 {
1630 printk("%c", *(pDest + count));
1631 count++;
1632 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1634 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301635 if (copy_to_user(pPrivData->buf, pDest, len))
1636 {
1637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1638 "%s: failed to copy data to user buffer", __func__);
1639 return -EFAULT;
1640 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301641 }
1642
1643 return 0;
1644} /*End of hdd_return_batch_scan_rsp_to_user*/
1645
Rajeev Kumar8b373292014-01-08 20:36:55 -08001646
1647/**---------------------------------------------------------------------------
1648
1649 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1650 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1651 WLS_BATCHING VERSION
1652 WLS_BATCHING SET
1653 WLS_BATCHING GET
1654 WLS_BATCHING STOP
1655
1656 \param - pAdapter Pointer to HDD adapter
1657 \param - pPrivdata Pointer to priv_data
1658 \param - command Pointer to command
1659
1660 \return - 0 for success -EFAULT for failure
1661
1662 --------------------------------------------------------------------------*/
1663
1664int hdd_handle_batch_scan_ioctl
1665(
1666 hdd_adapter_t *pAdapter,
1667 hdd_priv_data_t *pPrivdata,
1668 tANI_U8 *command
1669)
1670{
1671 int ret = 0;
1672
1673 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1674 {
1675 char extra[32];
1676 tANI_U8 len = 0;
1677 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1678
1679 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1680 {
1681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1682 "%s: Batch scan feature is not supported by FW", __func__);
1683 ret = -EINVAL;
1684 goto exit;
1685 }
1686
1687 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1688 version);
1689 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1690 {
1691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: failed to copy data to user buffer", __func__);
1693 ret = -EFAULT;
1694 goto exit;
1695 }
1696 ret = HDD_BATCH_SCAN_VERSION;
1697 }
1698 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1699 {
1700 int status;
1701 tANI_U8 *value = (command + 16);
1702 eHalStatus halStatus;
1703 unsigned long rc;
1704 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1705 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1706
1707 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1708 {
1709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1710 "%s: Batch scan feature is not supported by FW", __func__);
1711 ret = -EINVAL;
1712 goto exit;
1713 }
1714
1715 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1716 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1717 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1718 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1719 {
1720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "Received WLS_BATCHING SET command in invalid mode %d "
1722 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
1723 pAdapter->device_mode);
1724 ret = -EINVAL;
1725 goto exit;
1726 }
1727
1728 status = hdd_parse_set_batchscan_command(value, pReq);
1729 if (status)
1730 {
1731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1732 "Invalid WLS_BATCHING SET command");
1733 ret = -EINVAL;
1734 goto exit;
1735 }
1736
1737
1738 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1739 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1740 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1741 pAdapter);
1742
1743 if ( eHAL_STATUS_SUCCESS == halStatus )
1744 {
1745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1746 "sme_SetBatchScanReq returned success halStatus %d",
1747 halStatus);
1748 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1749 {
1750 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1751 rc = wait_for_completion_timeout(
1752 &pAdapter->hdd_set_batch_scan_req_var,
1753 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1754 if (0 == rc)
1755 {
1756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1757 "%s: Timeout waiting for set batch scan to complete",
1758 __func__);
1759 ret = -EINVAL;
1760 goto exit;
1761 }
1762 }
1763 if ( !pRsp->nScansToBatch )
1764 {
1765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1766 "%s: Received set batch scan failure response from FW",
1767 __func__);
1768 ret = -EINVAL;
1769 goto exit;
1770 }
1771 /*As per the Batch Scan Framework API we should return the MIN of
1772 either MSCAN or the max # of scans firmware can cache*/
1773 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1774
1775 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1776
1777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1778 "%s: request MSCAN %d response MSCAN %d ret %d",
1779 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1780 }
1781 else
1782 {
1783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "sme_SetBatchScanReq returned failure halStatus %d",
1785 halStatus);
1786 ret = -EINVAL;
1787 goto exit;
1788 }
1789 }
1790 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1791 {
1792 eHalStatus halStatus;
1793 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1794 pInd->param = 0;
1795
1796 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1797 {
1798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: Batch scan feature is not supported by FW", __func__);
1800 ret = -EINVAL;
1801 goto exit;
1802 }
1803
1804 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1805 {
1806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1807 "Batch scan is not yet enabled batch scan state %d",
1808 pAdapter->batchScanState);
1809 ret = -EINVAL;
1810 goto exit;
1811 }
1812
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001813 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1814 hdd_deinit_batch_scan(pAdapter);
1815 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1816
Rajeev Kumar8b373292014-01-08 20:36:55 -08001817 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1818
1819 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1820 pAdapter->sessionId);
1821 if ( eHAL_STATUS_SUCCESS == halStatus )
1822 {
1823 ret = 0;
1824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1825 "sme_StopBatchScanInd returned success halStatus %d",
1826 halStatus);
1827 }
1828 else
1829 {
1830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1831 "sme_StopBatchScanInd returned failure halStatus %d",
1832 halStatus);
1833 ret = -EINVAL;
1834 goto exit;
1835 }
1836 }
1837 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1838 {
1839 tANI_U32 remain_len;
1840
1841 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1842 {
1843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1844 "%s: Batch scan feature is not supported by FW", __func__);
1845 ret = -EINVAL;
1846 goto exit;
1847 }
1848
1849 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1850 {
1851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1852 "Batch scan is not yet enabled could not return results"
1853 "Batch Scan state %d",
1854 pAdapter->batchScanState);
1855 ret = -EINVAL;
1856 goto exit;
1857 }
1858
1859 pPrivdata->used_len = 16;
1860 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1861 if (remain_len < pPrivdata->total_len)
1862 {
1863 /*Clear previous batch scan response data if any*/
1864 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1865 }
1866 else
1867 {
1868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1869 "Invalid total length from user space can't fetch batch"
1870 " scan response total_len %d used_len %d remain len %d",
1871 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1872 ret = -EINVAL;
1873 goto exit;
1874 }
1875 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1876 }
1877
1878exit:
1879
1880 return ret;
1881}
1882
1883
Rajeev79dbe4c2013-10-05 11:03:42 +05301884#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1885
Jeff Johnson295189b2012-06-20 16:38:30 -07001886int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1887{
1888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1889 hdd_priv_data_t priv_data;
1890 tANI_U8 *command = NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301891 long ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001892
1893 if (NULL == pAdapter)
1894 {
1895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301896 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 ret = -ENODEV;
1898 goto exit;
1899 }
1900
Jeff Johnsone7245742012-09-05 17:12:55 -07001901 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1904 "%s: invalid data", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 ret = -EINVAL;
1906 goto exit;
1907 }
1908
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001909 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1910 {
1911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1912 "%s:LOGP in Progress. Ignore!!!", __func__);
1913 ret = -EBUSY;
1914 goto exit;
1915 }
1916
Jeff Johnson295189b2012-06-20 16:38:30 -07001917 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
1918 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1920 FL("failed to get data from user buffer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 ret = -EFAULT;
1922 goto exit;
1923 }
1924
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08001925 if (priv_data.total_len <= 0 ||
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301926 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001927 {
1928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1929 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1930 priv_data.total_len);
1931 ret = -EINVAL;
1932 goto exit;
1933 }
1934
1935 /* Allocate +1 for '\0' */
1936 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001937 if (!command)
1938 {
1939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301940 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 ret = -ENOMEM;
1942 goto exit;
1943 }
1944
1945 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1946 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1948 FL("failed to get data from user buffer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 ret = -EFAULT;
1950 goto exit;
1951 }
1952
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001953 /* Making sure the command is NUL-terminated */
1954 command[priv_data.total_len] = '\0';
1955
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 if ((SIOCDEVPRIVATE + 1) == cmd)
1957 {
1958 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1959
1960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001961 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001962
1963 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1964 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1966 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
1967 pAdapter->sessionId, (unsigned)
1968 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
1969 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
1970 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
1971 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1973 sizeof(tSirMacAddr)))
1974 {
1975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001976 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 ret = -EFAULT;
1978 }
1979 }
Amar Singhal0974e402013-02-12 14:27:46 -08001980 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 {
Amar Singhal0974e402013-02-12 14:27:46 -08001982 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001983
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001985
1986 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08001989 "%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 -07001990 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001991 ret = hdd_setBand_helper(dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301992 if(ret != 0)
1993 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1994 "%s: failed to set band ret=%ld",__func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08001995 }
Kiet Lamf040f472013-11-20 21:15:23 +05301996 else if(strncmp(command, "SETWMMPS", 8) == 0)
1997 {
1998 tANI_U8 *ptr = command;
1999 ret = hdd_wmmps_helper(pAdapter, ptr);
2000 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002001 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2002 {
2003 char *country_code;
2004
2005 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002006
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002007 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002008 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002009#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302010 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002011#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002012 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2013 (void *)(tSmeChangeCountryCallback)
2014 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302015 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002016 if (eHAL_STATUS_SUCCESS == ret)
2017 {
2018 ret = wait_for_completion_interruptible_timeout(
2019 &pAdapter->change_country_code,
2020 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2021 if (0 >= ret)
2022 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %ld",
2024 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002025 }
2026 }
2027 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002028 {
2029 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302030 "%s: SME Change Country code fail ret=%ld", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002031 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002032 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002033
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002034 }
2035 /*
2036 command should be a string having format
2037 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2038 */
Amar Singhal0974e402013-02-12 14:27:46 -08002039 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002040 {
Amar Singhal0974e402013-02-12 14:27:46 -08002041 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002042
2043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002044 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002045
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002046 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002047 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002048 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2049 {
2050 int suspend = 0;
2051 tANI_U8 *ptr = (tANI_U8*)command + 15;
2052
2053 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2055 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2056 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002057 hdd_set_wlan_suspend_mode(suspend);
2058 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002059#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2060 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2061 {
2062 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002063 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002064 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2065 eHalStatus status = eHAL_STATUS_SUCCESS;
2066
2067 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2068 value = value + 15;
2069
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002070 /* Convert the value from ascii to integer */
2071 ret = kstrtos8(value, 10, &rssi);
2072 if (ret < 0)
2073 {
2074 /* If the input value is greater than max value of datatype, then also
2075 kstrtou8 fails */
2076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2077 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002078 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002079 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2080 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2081 ret = -EINVAL;
2082 goto exit;
2083 }
2084
Srinivas Girigowdade697412013-02-14 16:31:48 -08002085 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002086
Srinivas Girigowdade697412013-02-14 16:31:48 -08002087 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2088 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2089 {
2090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2091 "Neighbor lookup threshold value %d is out of range"
2092 " (Min: %d Max: %d)", lookUpThreshold,
2093 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2094 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2095 ret = -EINVAL;
2096 goto exit;
2097 }
2098
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2100 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2101 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2103 "%s: Received Command to Set Roam trigger"
2104 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2105
2106 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2107 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2108 if (eHAL_STATUS_SUCCESS != status)
2109 {
2110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2111 "%s: Failed to set roam trigger, try again", __func__);
2112 ret = -EPERM;
2113 goto exit;
2114 }
2115
2116 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2117 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2118 }
2119 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2120 {
2121 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2122 int rssi = (-1) * lookUpThreshold;
2123 char extra[32];
2124 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302125 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2126 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2127 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002128 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002129 if (copy_to_user(priv_data.buf, &extra, len + 1))
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2132 "%s: failed to copy data to user buffer", __func__);
2133 ret = -EFAULT;
2134 goto exit;
2135 }
2136 }
2137 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2138 {
2139 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002140 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002141 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002142
Srinivas Girigowdade697412013-02-14 16:31:48 -08002143 /* input refresh period is in terms of seconds */
2144 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2145 value = value + 18;
2146 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002147 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002148 if (ret < 0)
2149 {
2150 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002151 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002153 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002154 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002155 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2156 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002157 ret = -EINVAL;
2158 goto exit;
2159 }
2160
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002161 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2162 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002163 {
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002165 "Roam scan period value %d is out of range"
2166 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002167 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2168 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002169 ret = -EINVAL;
2170 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302171 }
2172 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2173 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2174 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002175 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002176
2177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2178 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002179 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002180
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002181 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2182 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002183 }
2184 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2185 {
2186 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2187 char extra[32];
2188 tANI_U8 len = 0;
2189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2191 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2192 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002193 len = scnprintf(extra, sizeof(extra), "%s %d",
2194 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002195 /* Returned value is in units of seconds */
2196 if (copy_to_user(priv_data.buf, &extra, len + 1))
2197 {
2198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2199 "%s: failed to copy data to user buffer", __func__);
2200 ret = -EFAULT;
2201 goto exit;
2202 }
2203 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002204 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2205 {
2206 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002207 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002208 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002209
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002210 /* input refresh period is in terms of seconds */
2211 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2212 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002213
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002214 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002215 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002216 if (ret < 0)
2217 {
2218 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002219 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002221 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002222 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002223 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2224 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2225 ret = -EINVAL;
2226 goto exit;
2227 }
2228
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002229 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2230 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2231 {
2232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2233 "Neighbor scan results refresh period value %d is out of range"
2234 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2235 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2236 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2237 ret = -EINVAL;
2238 goto exit;
2239 }
2240 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2241
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2243 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002244 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002245
2246 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2247 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2248 }
2249 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2250 {
2251 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2252 char extra[32];
2253 tANI_U8 len = 0;
2254
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002255 len = scnprintf(extra, sizeof(extra), "%s %d",
2256 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002257 /* Returned value is in units of seconds */
2258 if (copy_to_user(priv_data.buf, &extra, len + 1))
2259 {
2260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2261 "%s: failed to copy data to user buffer", __func__);
2262 ret = -EFAULT;
2263 goto exit;
2264 }
2265 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002266#ifdef FEATURE_WLAN_LFR
2267 /* SETROAMMODE */
2268 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2269 {
2270 tANI_U8 *value = command;
2271 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2272
2273 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2274 value = value + SIZE_OF_SETROAMMODE + 1;
2275
2276 /* Convert the value from ascii to integer */
2277 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2278 if (ret < 0)
2279 {
2280 /* If the input value is greater than max value of datatype, then also
2281 kstrtou8 fails */
2282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2283 "%s: kstrtou8 failed range [%d - %d]", __func__,
2284 CFG_LFR_FEATURE_ENABLED_MIN,
2285 CFG_LFR_FEATURE_ENABLED_MAX);
2286 ret = -EINVAL;
2287 goto exit;
2288 }
2289 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2290 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2291 {
2292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2293 "Roam Mode value %d is out of range"
2294 " (Min: %d Max: %d)", roamMode,
2295 CFG_LFR_FEATURE_ENABLED_MIN,
2296 CFG_LFR_FEATURE_ENABLED_MAX);
2297 ret = -EINVAL;
2298 goto exit;
2299 }
2300
2301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2302 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2303 /*
2304 * Note that
2305 * SETROAMMODE 0 is to enable LFR while
2306 * SETROAMMODE 1 is to disable LFR, but
2307 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2308 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2309 */
2310 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2311 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2312 else
2313 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2314
2315 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2316 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2317 }
2318 /* GETROAMMODE */
2319 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2320 {
2321 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2322 char extra[32];
2323 tANI_U8 len = 0;
2324
2325 /*
2326 * roamMode value shall be inverted because the sementics is different.
2327 */
2328 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2329 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2330 else
2331 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2332
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002333 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002334 if (copy_to_user(priv_data.buf, &extra, len + 1))
2335 {
2336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2337 "%s: failed to copy data to user buffer", __func__);
2338 ret = -EFAULT;
2339 goto exit;
2340 }
2341 }
2342#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002343#endif
2344#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2345 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2346 {
2347 tANI_U8 *value = command;
2348 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2349
2350 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2351 value = value + 13;
2352 /* Convert the value from ascii to integer */
2353 ret = kstrtou8(value, 10, &roamRssiDiff);
2354 if (ret < 0)
2355 {
2356 /* If the input value is greater than max value of datatype, then also
2357 kstrtou8 fails */
2358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2359 "%s: kstrtou8 failed range [%d - %d]", __func__,
2360 CFG_ROAM_RSSI_DIFF_MIN,
2361 CFG_ROAM_RSSI_DIFF_MAX);
2362 ret = -EINVAL;
2363 goto exit;
2364 }
2365
2366 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2367 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2368 {
2369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2370 "Roam rssi diff value %d is out of range"
2371 " (Min: %d Max: %d)", roamRssiDiff,
2372 CFG_ROAM_RSSI_DIFF_MIN,
2373 CFG_ROAM_RSSI_DIFF_MAX);
2374 ret = -EINVAL;
2375 goto exit;
2376 }
2377
2378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2379 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2380
2381 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2382 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2383 }
2384 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2385 {
2386 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2387 char extra[32];
2388 tANI_U8 len = 0;
2389
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302390 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2391 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2392 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002393 len = scnprintf(extra, sizeof(extra), "%s %d",
2394 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002395 if (copy_to_user(priv_data.buf, &extra, len + 1))
2396 {
2397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2398 "%s: failed to copy data to user buffer", __func__);
2399 ret = -EFAULT;
2400 goto exit;
2401 }
2402 }
2403#endif
2404#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2405 else if (strncmp(command, "GETBAND", 7) == 0)
2406 {
2407 int band = -1;
2408 char extra[32];
2409 tANI_U8 len = 0;
2410 hdd_getBand_helper(pHddCtx, &band);
2411
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302412 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2413 TRACE_CODE_HDD_GETBAND_IOCTL,
2414 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002415 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002416 if (copy_to_user(priv_data.buf, &extra, len + 1))
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2419 "%s: failed to copy data to user buffer", __func__);
2420 ret = -EFAULT;
2421 goto exit;
2422 }
2423 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002424 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2425 {
2426 tANI_U8 *value = command;
2427 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2428 tANI_U8 numChannels = 0;
2429 eHalStatus status = eHAL_STATUS_SUCCESS;
2430
2431 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2432 if (eHAL_STATUS_SUCCESS != status)
2433 {
2434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2435 "%s: Failed to parse channel list information", __func__);
2436 ret = -EINVAL;
2437 goto exit;
2438 }
2439
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302440 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2441 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2442 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002443 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2444 {
2445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2446 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2447 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2448 ret = -EINVAL;
2449 goto exit;
2450 }
2451 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2452 numChannels);
2453 if (eHAL_STATUS_SUCCESS != status)
2454 {
2455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2456 "%s: Failed to update channel list information", __func__);
2457 ret = -EINVAL;
2458 goto exit;
2459 }
2460 }
2461 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2462 {
2463 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2464 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002465 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002466 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002467 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002468
2469 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2470 ChannelList, &numChannels ))
2471 {
2472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2473 "%s: failed to get roam scan channel list", __func__);
2474 ret = -EFAULT;
2475 goto exit;
2476 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2478 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2479 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002480 /* output channel list is of the format
2481 [Number of roam scan channels][Channel1][Channel2]... */
2482 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002483 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002484 for (j = 0; (j < numChannels); j++)
2485 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002486 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2487 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002488 }
2489
2490 if (copy_to_user(priv_data.buf, &extra, len + 1))
2491 {
2492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2493 "%s: failed to copy data to user buffer", __func__);
2494 ret = -EFAULT;
2495 goto exit;
2496 }
2497 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002498 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2499 {
2500 tANI_BOOLEAN ccxMode = sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2501 char extra[32];
2502 tANI_U8 len = 0;
2503
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002504 /* Check if the features OKC/CCX/11R are supported simultaneously,
2505 then this operation is not permitted (return FAILURE) */
2506 if (ccxMode &&
2507 hdd_is_okc_mode_enabled(pHddCtx) &&
2508 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2509 {
2510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2511 "%s: OKC/CCX/11R are supported simultaneously"
2512 " hence this operation is not permitted!", __func__);
2513 ret = -EPERM;
2514 goto exit;
2515 }
2516
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002517 len = scnprintf(extra, sizeof(extra), "%s %d",
2518 "GETCCXMODE", ccxMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002519 if (copy_to_user(priv_data.buf, &extra, len + 1))
2520 {
2521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2522 "%s: failed to copy data to user buffer", __func__);
2523 ret = -EFAULT;
2524 goto exit;
2525 }
2526 }
2527 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2528 {
2529 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2530 char extra[32];
2531 tANI_U8 len = 0;
2532
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002533 /* Check if the features OKC/CCX/11R are supported simultaneously,
2534 then this operation is not permitted (return FAILURE) */
2535 if (okcMode &&
2536 sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
2537 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2538 {
2539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2540 "%s: OKC/CCX/11R are supported simultaneously"
2541 " hence this operation is not permitted!", __func__);
2542 ret = -EPERM;
2543 goto exit;
2544 }
2545
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002546 len = scnprintf(extra, sizeof(extra), "%s %d",
2547 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002548 if (copy_to_user(priv_data.buf, &extra, len + 1))
2549 {
2550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2551 "%s: failed to copy data to user buffer", __func__);
2552 ret = -EFAULT;
2553 goto exit;
2554 }
2555 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 {
2558 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2559 char extra[32];
2560 tANI_U8 len = 0;
2561
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002562 len = scnprintf(extra, sizeof(extra), "%s %d",
2563 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002564 if (copy_to_user(priv_data.buf, &extra, len + 1))
2565 {
2566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2567 "%s: failed to copy data to user buffer", __func__);
2568 ret = -EFAULT;
2569 goto exit;
2570 }
2571 }
2572 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2573 {
2574 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2575 char extra[32];
2576 tANI_U8 len = 0;
2577
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002578 len = scnprintf(extra, sizeof(extra), "%s %d",
2579 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002580 if (copy_to_user(priv_data.buf, &extra, len + 1))
2581 {
2582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2583 "%s: failed to copy data to user buffer", __func__);
2584 ret = -EFAULT;
2585 goto exit;
2586 }
2587 }
2588 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2589 {
2590 tANI_U8 *value = command;
2591 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2592
2593 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2594 value = value + 26;
2595 /* Convert the value from ascii to integer */
2596 ret = kstrtou8(value, 10, &minTime);
2597 if (ret < 0)
2598 {
2599 /* If the input value is greater than max value of datatype, then also
2600 kstrtou8 fails */
2601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2602 "%s: kstrtou8 failed range [%d - %d]", __func__,
2603 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2604 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2605 ret = -EINVAL;
2606 goto exit;
2607 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002608 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2609 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2610 {
2611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2612 "scan min channel time value %d is out of range"
2613 " (Min: %d Max: %d)", minTime,
2614 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2615 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2616 ret = -EINVAL;
2617 goto exit;
2618 }
2619
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2621 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2622 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2624 "%s: Received Command to change channel min time = %d", __func__, minTime);
2625
2626 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2627 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2628 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002629 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2630 {
2631 tANI_U8 *value = command;
2632 tANI_U8 channel = 0;
2633 tANI_U8 dwellTime = 0;
2634 tANI_U8 bufLen = 0;
2635 tANI_U8 *buf = NULL;
2636 tSirMacAddr targetApBssid;
2637 eHalStatus status = eHAL_STATUS_SUCCESS;
2638 struct ieee80211_channel chan;
2639 tANI_U8 finalLen = 0;
2640 tANI_U8 *finalBuf = NULL;
2641 tANI_U8 temp = 0;
2642 u64 cookie;
2643 hdd_station_ctx_t *pHddStaCtx = NULL;
2644 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2645
2646 /* if not associated, no need to send action frame */
2647 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2648 {
2649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2650 ret = -EINVAL;
2651 goto exit;
2652 }
2653
2654 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2655 &dwellTime, &buf, &bufLen);
2656 if (eHAL_STATUS_SUCCESS != status)
2657 {
2658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2659 "%s: Failed to parse send action frame data", __func__);
2660 ret = -EINVAL;
2661 goto exit;
2662 }
2663
2664 /* if the target bssid is different from currently associated AP,
2665 then no need to send action frame */
2666 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2667 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2668 {
2669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2670 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002671 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002672 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002673 goto exit;
2674 }
2675
2676 /* if the channel number is different from operating channel then
2677 no need to send action frame */
2678 if (channel != pHddStaCtx->conn_info.operationChannel)
2679 {
2680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2681 "%s: channel(%d) is different from operating channel(%d)",
2682 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2683 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002684 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002685 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002686 goto exit;
2687 }
2688 chan.center_freq = sme_ChnToFreq(channel);
2689
2690 finalLen = bufLen + 24;
2691 finalBuf = vos_mem_malloc(finalLen);
2692 if (NULL == finalBuf)
2693 {
2694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2695 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002696 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002697 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002698 goto exit;
2699 }
2700 vos_mem_zero(finalBuf, finalLen);
2701
2702 /* Fill subtype */
2703 temp = SIR_MAC_MGMT_ACTION << 4;
2704 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2705
2706 /* Fill type */
2707 temp = SIR_MAC_MGMT_FRAME;
2708 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2709
2710 /* Fill destination address (bssid of the AP) */
2711 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2712
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002713 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002714 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2715
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002716 /* Fill BSSID (AP mac address) */
2717 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002718
2719 /* Fill received buffer from 24th address */
2720 vos_mem_copy(finalBuf + 24, buf, bufLen);
2721
Jeff Johnson11c33152013-04-16 17:52:40 -07002722 /* done with the parsed buffer */
2723 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002724 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002725
DARAM SUDHA39eede62014-02-12 11:16:40 +05302726 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2728 &(pAdapter->wdev),
2729#else
2730 dev,
2731#endif
2732 &chan, 0,
2733#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2734 NL80211_CHAN_HT20, 1,
2735#endif
2736 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002737 1, &cookie );
2738 vos_mem_free(finalBuf);
2739 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002740 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2741 {
2742 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2743 char extra[32];
2744 tANI_U8 len = 0;
2745
2746 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002747 len = scnprintf(extra, sizeof(extra), "%s %d",
2748 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302749 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2750 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2751 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002752 if (copy_to_user(priv_data.buf, &extra, len + 1))
2753 {
2754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2755 "%s: failed to copy data to user buffer", __func__);
2756 ret = -EFAULT;
2757 goto exit;
2758 }
2759 }
2760 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2761 {
2762 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002763 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002764
2765 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2766 value = value + 19;
2767 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002768 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002769 if (ret < 0)
2770 {
2771 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002772 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002774 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002775 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2776 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2777 ret = -EINVAL;
2778 goto exit;
2779 }
2780
2781 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2782 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2783 {
2784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2785 "lfr mode value %d is out of range"
2786 " (Min: %d Max: %d)", maxTime,
2787 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2788 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2789 ret = -EINVAL;
2790 goto exit;
2791 }
2792
2793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2794 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2795
2796 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2797 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2798 }
2799 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2800 {
2801 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2802 char extra[32];
2803 tANI_U8 len = 0;
2804
2805 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002806 len = scnprintf(extra, sizeof(extra), "%s %d",
2807 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002808 if (copy_to_user(priv_data.buf, &extra, len + 1))
2809 {
2810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2811 "%s: failed to copy data to user buffer", __func__);
2812 ret = -EFAULT;
2813 goto exit;
2814 }
2815 }
2816 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2817 {
2818 tANI_U8 *value = command;
2819 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2820
2821 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2822 value = value + 16;
2823 /* Convert the value from ascii to integer */
2824 ret = kstrtou16(value, 10, &val);
2825 if (ret < 0)
2826 {
2827 /* If the input value is greater than max value of datatype, then also
2828 kstrtou16 fails */
2829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2830 "%s: kstrtou16 failed range [%d - %d]", __func__,
2831 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2832 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2833 ret = -EINVAL;
2834 goto exit;
2835 }
2836
2837 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2838 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2839 {
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2841 "scan home time value %d is out of range"
2842 " (Min: %d Max: %d)", val,
2843 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2844 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2845 ret = -EINVAL;
2846 goto exit;
2847 }
2848
2849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2850 "%s: Received Command to change scan home time = %d", __func__, val);
2851
2852 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2853 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2854 }
2855 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2856 {
2857 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2858 char extra[32];
2859 tANI_U8 len = 0;
2860
2861 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002862 len = scnprintf(extra, sizeof(extra), "%s %d",
2863 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002864 if (copy_to_user(priv_data.buf, &extra, len + 1))
2865 {
2866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2867 "%s: failed to copy data to user buffer", __func__);
2868 ret = -EFAULT;
2869 goto exit;
2870 }
2871 }
2872 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2873 {
2874 tANI_U8 *value = command;
2875 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2876
2877 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2878 value = value + 17;
2879 /* Convert the value from ascii to integer */
2880 ret = kstrtou8(value, 10, &val);
2881 if (ret < 0)
2882 {
2883 /* If the input value is greater than max value of datatype, then also
2884 kstrtou8 fails */
2885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2886 "%s: kstrtou8 failed range [%d - %d]", __func__,
2887 CFG_ROAM_INTRA_BAND_MIN,
2888 CFG_ROAM_INTRA_BAND_MAX);
2889 ret = -EINVAL;
2890 goto exit;
2891 }
2892
2893 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2894 (val > CFG_ROAM_INTRA_BAND_MAX))
2895 {
2896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2897 "intra band mode value %d is out of range"
2898 " (Min: %d Max: %d)", val,
2899 CFG_ROAM_INTRA_BAND_MIN,
2900 CFG_ROAM_INTRA_BAND_MAX);
2901 ret = -EINVAL;
2902 goto exit;
2903 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2905 "%s: Received Command to change intra band = %d", __func__, val);
2906
2907 pHddCtx->cfg_ini->nRoamIntraBand = val;
2908 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2909 }
2910 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2911 {
2912 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2913 char extra[32];
2914 tANI_U8 len = 0;
2915
2916 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002917 len = scnprintf(extra, sizeof(extra), "%s %d",
2918 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002919 if (copy_to_user(priv_data.buf, &extra, len + 1))
2920 {
2921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2922 "%s: failed to copy data to user buffer", __func__);
2923 ret = -EFAULT;
2924 goto exit;
2925 }
2926 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002927 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2928 {
2929 tANI_U8 *value = command;
2930 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2931
2932 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2933 value = value + 15;
2934 /* Convert the value from ascii to integer */
2935 ret = kstrtou8(value, 10, &nProbes);
2936 if (ret < 0)
2937 {
2938 /* If the input value is greater than max value of datatype, then also
2939 kstrtou8 fails */
2940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2941 "%s: kstrtou8 failed range [%d - %d]", __func__,
2942 CFG_ROAM_SCAN_N_PROBES_MIN,
2943 CFG_ROAM_SCAN_N_PROBES_MAX);
2944 ret = -EINVAL;
2945 goto exit;
2946 }
2947
2948 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2949 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2950 {
2951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2952 "NProbes value %d is out of range"
2953 " (Min: %d Max: %d)", nProbes,
2954 CFG_ROAM_SCAN_N_PROBES_MIN,
2955 CFG_ROAM_SCAN_N_PROBES_MAX);
2956 ret = -EINVAL;
2957 goto exit;
2958 }
2959
2960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2961 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2962
2963 pHddCtx->cfg_ini->nProbes = nProbes;
2964 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2965 }
2966 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2967 {
2968 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
2969 char extra[32];
2970 tANI_U8 len = 0;
2971
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002972 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002973 if (copy_to_user(priv_data.buf, &extra, len + 1))
2974 {
2975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2976 "%s: failed to copy data to user buffer", __func__);
2977 ret = -EFAULT;
2978 goto exit;
2979 }
2980 }
2981 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
2982 {
2983 tANI_U8 *value = command;
2984 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
2985
2986 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
2987 /* input value is in units of msec */
2988 value = value + 20;
2989 /* Convert the value from ascii to integer */
2990 ret = kstrtou16(value, 10, &homeAwayTime);
2991 if (ret < 0)
2992 {
2993 /* If the input value is greater than max value of datatype, then also
2994 kstrtou8 fails */
2995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2996 "%s: kstrtou8 failed range [%d - %d]", __func__,
2997 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2998 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2999 ret = -EINVAL;
3000 goto exit;
3001 }
3002
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003003 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3004 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3005 {
3006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3007 "homeAwayTime value %d is out of range"
3008 " (Min: %d Max: %d)", homeAwayTime,
3009 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3010 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3011 ret = -EINVAL;
3012 goto exit;
3013 }
3014
3015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3016 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003017 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3018 {
3019 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3020 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3021 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003022 }
3023 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3024 {
3025 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3026 char extra[32];
3027 tANI_U8 len = 0;
3028
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003029 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003030 if (copy_to_user(priv_data.buf, &extra, len + 1))
3031 {
3032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3033 "%s: failed to copy data to user buffer", __func__);
3034 ret = -EFAULT;
3035 goto exit;
3036 }
3037 }
3038 else if (strncmp(command, "REASSOC", 7) == 0)
3039 {
3040 tANI_U8 *value = command;
3041 tANI_U8 channel = 0;
3042 tSirMacAddr targetApBssid;
3043 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003044#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3045 tCsrHandoffRequest handoffInfo;
3046#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003047 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003048 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3049
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003050 /* if not associated, no need to proceed with reassoc */
3051 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3052 {
3053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3054 ret = -EINVAL;
3055 goto exit;
3056 }
3057
3058 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3059 if (eHAL_STATUS_SUCCESS != status)
3060 {
3061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3062 "%s: Failed to parse reassoc command data", __func__);
3063 ret = -EINVAL;
3064 goto exit;
3065 }
3066
3067 /* if the target bssid is same as currently associated AP,
3068 then no need to proceed with reassoc */
3069 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3070 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3071 {
3072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3073 ret = -EINVAL;
3074 goto exit;
3075 }
3076
3077 /* Check channel number is a valid channel number */
3078 if(VOS_STATUS_SUCCESS !=
3079 wlan_hdd_validate_operation_channel(pAdapter, channel))
3080 {
3081 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003082 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003083 return -EINVAL;
3084 }
3085
3086 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003087#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3088 handoffInfo.channel = channel;
3089 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3090 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3091#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003092 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003093 else if (strncmp(command, "SETWESMODE", 10) == 0)
3094 {
3095 tANI_U8 *value = command;
3096 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3097
3098 /* Move pointer to ahead of SETWESMODE<delimiter> */
3099 value = value + 11;
3100 /* Convert the value from ascii to integer */
3101 ret = kstrtou8(value, 10, &wesMode);
3102 if (ret < 0)
3103 {
3104 /* If the input value is greater than max value of datatype, then also
3105 kstrtou8 fails */
3106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3107 "%s: kstrtou8 failed range [%d - %d]", __func__,
3108 CFG_ENABLE_WES_MODE_NAME_MIN,
3109 CFG_ENABLE_WES_MODE_NAME_MAX);
3110 ret = -EINVAL;
3111 goto exit;
3112 }
3113
3114 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3115 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3116 {
3117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3118 "WES Mode value %d is out of range"
3119 " (Min: %d Max: %d)", wesMode,
3120 CFG_ENABLE_WES_MODE_NAME_MIN,
3121 CFG_ENABLE_WES_MODE_NAME_MAX);
3122 ret = -EINVAL;
3123 goto exit;
3124 }
3125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3126 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3127
3128 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3129 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3130 }
3131 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3132 {
3133 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3134 char extra[32];
3135 tANI_U8 len = 0;
3136
Arif Hussain826d9412013-11-12 16:44:54 -08003137 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003138 if (copy_to_user(priv_data.buf, &extra, len + 1))
3139 {
3140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3141 "%s: failed to copy data to user buffer", __func__);
3142 ret = -EFAULT;
3143 goto exit;
3144 }
3145 }
3146#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_CCX || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003147#ifdef FEATURE_WLAN_LFR
3148 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3149 {
3150 tANI_U8 *value = command;
3151 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3152
3153 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3154 value = value + 12;
3155 /* Convert the value from ascii to integer */
3156 ret = kstrtou8(value, 10, &lfrMode);
3157 if (ret < 0)
3158 {
3159 /* If the input value is greater than max value of datatype, then also
3160 kstrtou8 fails */
3161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3162 "%s: kstrtou8 failed range [%d - %d]", __func__,
3163 CFG_LFR_FEATURE_ENABLED_MIN,
3164 CFG_LFR_FEATURE_ENABLED_MAX);
3165 ret = -EINVAL;
3166 goto exit;
3167 }
3168
3169 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3170 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3171 {
3172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3173 "lfr mode value %d is out of range"
3174 " (Min: %d Max: %d)", lfrMode,
3175 CFG_LFR_FEATURE_ENABLED_MIN,
3176 CFG_LFR_FEATURE_ENABLED_MAX);
3177 ret = -EINVAL;
3178 goto exit;
3179 }
3180
3181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3182 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3183
3184 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3185 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3186 }
3187#endif
3188#ifdef WLAN_FEATURE_VOWIFI_11R
3189 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3190 {
3191 tANI_U8 *value = command;
3192 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3193
3194 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3195 value = value + 18;
3196 /* Convert the value from ascii to integer */
3197 ret = kstrtou8(value, 10, &ft);
3198 if (ret < 0)
3199 {
3200 /* If the input value is greater than max value of datatype, then also
3201 kstrtou8 fails */
3202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3203 "%s: kstrtou8 failed range [%d - %d]", __func__,
3204 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3205 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3206 ret = -EINVAL;
3207 goto exit;
3208 }
3209
3210 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3211 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3212 {
3213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3214 "ft mode value %d is out of range"
3215 " (Min: %d Max: %d)", ft,
3216 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3217 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3218 ret = -EINVAL;
3219 goto exit;
3220 }
3221
3222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3223 "%s: Received Command to change ft mode = %d", __func__, ft);
3224
3225 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3226 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3227 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303228
3229 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3230 {
3231 tANI_U8 *value = command;
3232 tSirMacAddr targetApBssid;
3233 tANI_U8 trigger = 0;
3234 eHalStatus status = eHAL_STATUS_SUCCESS;
3235 hdd_station_ctx_t *pHddStaCtx = NULL;
3236 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3237
3238 /* if not associated, no need to proceed with reassoc */
3239 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3240 {
3241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3247 if (eHAL_STATUS_SUCCESS != status)
3248 {
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "%s: Failed to parse reassoc command data", __func__);
3251 ret = -EINVAL;
3252 goto exit;
3253 }
3254
3255 /* if the target bssid is same as currently associated AP,
3256 then no need to proceed with reassoc */
3257 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3258 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3259 {
3260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3261 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3262 __func__);
3263 ret = -EINVAL;
3264 goto exit;
3265 }
3266
3267 /* Proceed with scan/roam */
3268 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3269 &targetApBssid[0],
3270 (tSmeFastRoamTrigger)(trigger));
3271 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003272#endif
3273#ifdef FEATURE_WLAN_CCX
3274 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3275 {
3276 tANI_U8 *value = command;
3277 tANI_U8 ccxMode = CFG_CCX_FEATURE_ENABLED_DEFAULT;
3278
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003279 /* Check if the features OKC/CCX/11R are supported simultaneously,
3280 then this operation is not permitted (return FAILURE) */
3281 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3282 hdd_is_okc_mode_enabled(pHddCtx) &&
3283 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3284 {
3285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3286 "%s: OKC/CCX/11R are supported simultaneously"
3287 " hence this operation is not permitted!", __func__);
3288 ret = -EPERM;
3289 goto exit;
3290 }
3291
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003292 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3293 value = value + 11;
3294 /* Convert the value from ascii to integer */
3295 ret = kstrtou8(value, 10, &ccxMode);
3296 if (ret < 0)
3297 {
3298 /* If the input value is greater than max value of datatype, then also
3299 kstrtou8 fails */
3300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3301 "%s: kstrtou8 failed range [%d - %d]", __func__,
3302 CFG_CCX_FEATURE_ENABLED_MIN,
3303 CFG_CCX_FEATURE_ENABLED_MAX);
3304 ret = -EINVAL;
3305 goto exit;
3306 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003307 if ((ccxMode < CFG_CCX_FEATURE_ENABLED_MIN) ||
3308 (ccxMode > CFG_CCX_FEATURE_ENABLED_MAX))
3309 {
3310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3311 "Ccx mode value %d is out of range"
3312 " (Min: %d Max: %d)", ccxMode,
3313 CFG_CCX_FEATURE_ENABLED_MIN,
3314 CFG_CCX_FEATURE_ENABLED_MAX);
3315 ret = -EINVAL;
3316 goto exit;
3317 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3319 "%s: Received Command to change ccx mode = %d", __func__, ccxMode);
3320
3321 pHddCtx->cfg_ini->isCcxIniFeatureEnabled = ccxMode;
3322 sme_UpdateIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal), ccxMode);
3323 }
3324#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003325 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3326 {
3327 tANI_U8 *value = command;
3328 tANI_BOOLEAN roamScanControl = 0;
3329
3330 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3331 value = value + 19;
3332 /* Convert the value from ascii to integer */
3333 ret = kstrtou8(value, 10, &roamScanControl);
3334 if (ret < 0)
3335 {
3336 /* If the input value is greater than max value of datatype, then also
3337 kstrtou8 fails */
3338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3339 "%s: kstrtou8 failed ", __func__);
3340 ret = -EINVAL;
3341 goto exit;
3342 }
3343
3344 if (0 != roamScanControl)
3345 {
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3347 "roam scan control invalid value = %d",
3348 roamScanControl);
3349 ret = -EINVAL;
3350 goto exit;
3351 }
3352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3353 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3354
3355 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3356 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003357#ifdef FEATURE_WLAN_OKC
3358 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3359 {
3360 tANI_U8 *value = command;
3361 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3362
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003363 /* Check if the features OKC/CCX/11R are supported simultaneously,
3364 then this operation is not permitted (return FAILURE) */
3365 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3366 hdd_is_okc_mode_enabled(pHddCtx) &&
3367 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3368 {
3369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3370 "%s: OKC/CCX/11R are supported simultaneously"
3371 " hence this operation is not permitted!", __func__);
3372 ret = -EPERM;
3373 goto exit;
3374 }
3375
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003376 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3377 value = value + 11;
3378 /* Convert the value from ascii to integer */
3379 ret = kstrtou8(value, 10, &okcMode);
3380 if (ret < 0)
3381 {
3382 /* If the input value is greater than max value of datatype, then also
3383 kstrtou8 fails */
3384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3385 "%s: kstrtou8 failed range [%d - %d]", __func__,
3386 CFG_OKC_FEATURE_ENABLED_MIN,
3387 CFG_OKC_FEATURE_ENABLED_MAX);
3388 ret = -EINVAL;
3389 goto exit;
3390 }
3391
3392 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3393 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3394 {
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3396 "Okc mode value %d is out of range"
3397 " (Min: %d Max: %d)", okcMode,
3398 CFG_OKC_FEATURE_ENABLED_MIN,
3399 CFG_OKC_FEATURE_ENABLED_MAX);
3400 ret = -EINVAL;
3401 goto exit;
3402 }
3403
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3405 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3406
3407 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3408 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003409#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003410 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3411 {
3412 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3413 char extra[32];
3414 tANI_U8 len = 0;
3415
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003416 len = scnprintf(extra, sizeof(extra), "%s %d",
3417 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003418 if (copy_to_user(priv_data.buf, &extra, len + 1))
3419 {
3420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3421 "%s: failed to copy data to user buffer", __func__);
3422 ret = -EFAULT;
3423 goto exit;
3424 }
3425 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303426#ifdef WLAN_FEATURE_PACKET_FILTERING
3427 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3428 {
3429 tANI_U8 filterType = 0;
3430 tANI_U8 *value = command;
3431
3432 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3433 value = value + 22;
3434
3435 /* Convert the value from ascii to integer */
3436 ret = kstrtou8(value, 10, &filterType);
3437 if (ret < 0)
3438 {
3439 /* If the input value is greater than max value of datatype,
3440 * then also kstrtou8 fails
3441 */
3442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3443 "%s: kstrtou8 failed range ", __func__);
3444 ret = -EINVAL;
3445 goto exit;
3446 }
3447
3448 if (filterType != 0 && filterType != 1)
3449 {
3450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3451 "%s: Accepted Values are 0 and 1 ", __func__);
3452 ret = -EINVAL;
3453 goto exit;
3454 }
3455 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3456 pAdapter->sessionId);
3457 }
3458#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303459 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3460 {
3461 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303462 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303463 if ('1' == *dhcpPhase)
3464 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303466 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303467
3468 pHddCtx->btCoexModeSet = TRUE;
3469
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303470 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303471 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303472 }
3473 else if ('2' == *dhcpPhase)
3474 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303476 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303477
3478 pHddCtx->btCoexModeSet = FALSE;
3479
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303480 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303481 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303482 }
3483 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003484 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3485 {
3486 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3487 }
3488 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3489 {
3490 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3491 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303492 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3493 {
3494 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3495 char extra[32];
3496 tANI_U8 len = 0;
3497
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003498 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303499 (int)pCfg->nActiveMaxChnTime);
3500 if (copy_to_user(priv_data.buf, &extra, len + 1))
3501 {
3502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3503 "%s: failed to copy data to user buffer", __func__);
3504 ret = -EFAULT;
3505 goto exit;
3506 }
3507 ret = len;
3508 }
3509 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3510 {
3511 tANI_U8 *value = command;
3512 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3513 int val = 0, temp;
3514
3515 value = value + 13;
3516 temp = kstrtou32(value, 10, &val);
3517 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3518 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3519 {
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3521 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3522 ret = -EFAULT;
3523 goto exit;
3524 }
3525 pCfg->nActiveMaxChnTime = val;
3526 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003527 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3528 {
3529 tANI_U8 filterType = 0;
3530 tANI_U8 *value;
3531 value = command + 9;
3532
3533 /* Convert the value from ascii to integer */
3534 ret = kstrtou8(value, 10, &filterType);
3535 if (ret < 0)
3536 {
3537 /* If the input value is greater than max value of datatype,
3538 * then also kstrtou8 fails
3539 */
3540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3541 "%s: kstrtou8 failed range ", __func__);
3542 ret = -EINVAL;
3543 goto exit;
3544 }
3545 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3546 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3547 {
3548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3549 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3550 " 2-Sink ", __func__);
3551 ret = -EINVAL;
3552 goto exit;
3553 }
3554 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3555 pHddCtx->drvr_miracast = filterType;
3556 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3557 }
Leo Chang614d2072013-08-22 14:59:44 -07003558 else if (strncmp(command, "SETMCRATE", 9) == 0)
3559 {
Leo Chang614d2072013-08-22 14:59:44 -07003560 tANI_U8 *value = command;
3561 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003562 tSirRateUpdateInd *rateUpdate;
3563 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003564
3565 /* Only valid for SAP mode */
3566 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3567 {
3568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3569 "%s: SAP mode is not running", __func__);
3570 ret = -EFAULT;
3571 goto exit;
3572 }
3573
3574 /* Move pointer to ahead of SETMCRATE<delimiter> */
3575 /* input value is in units of hundred kbps */
3576 value = value + 10;
3577 /* Convert the value from ascii to integer, decimal base */
3578 ret = kstrtouint(value, 10, &targetRate);
3579
Leo Chang1f98cbd2013-10-17 15:03:52 -07003580 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3581 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003582 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003583 hddLog(VOS_TRACE_LEVEL_ERROR,
3584 "%s: SETMCRATE indication alloc fail", __func__);
3585 ret = -EFAULT;
3586 goto exit;
3587 }
3588 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3589
3590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3591 "MC Target rate %d", targetRate);
3592 /* Ignore unicast */
3593 rateUpdate->ucastDataRate = -1;
3594 rateUpdate->mcastDataRate24GHz = targetRate;
3595 rateUpdate->mcastDataRate5GHz = targetRate;
3596 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3597 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3598 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3599 if (eHAL_STATUS_SUCCESS != status)
3600 {
3601 hddLog(VOS_TRACE_LEVEL_ERROR,
3602 "%s: SET_MC_RATE failed", __func__);
3603 vos_mem_free(rateUpdate);
3604 ret = -EFAULT;
3605 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003606 }
3607 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303608#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003609 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303610 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003611 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303612 }
3613#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003614#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
3615 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3616 {
3617 tANI_U8 *value = command;
3618 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3619 tANI_U8 numChannels = 0;
3620 eHalStatus status = eHAL_STATUS_SUCCESS;
3621
3622 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3623 if (eHAL_STATUS_SUCCESS != status)
3624 {
3625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3626 "%s: Failed to parse channel list information", __func__);
3627 ret = -EINVAL;
3628 goto exit;
3629 }
3630
3631 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3632 {
3633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3634 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3635 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3636 ret = -EINVAL;
3637 goto exit;
3638 }
3639 status = sme_SetCcxRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
3640 ChannelList,
3641 numChannels);
3642 if (eHAL_STATUS_SUCCESS != status)
3643 {
3644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3645 "%s: Failed to update channel list information", __func__);
3646 ret = -EINVAL;
3647 goto exit;
3648 }
3649 }
3650 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3651 {
3652 tANI_U8 *value = command;
3653 char extra[128] = {0};
3654 int len = 0;
3655 tANI_U8 tid = 0;
3656 hdd_station_ctx_t *pHddStaCtx = NULL;
3657 tAniTrafStrmMetrics tsmMetrics;
3658 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3659
3660 /* if not associated, return error */
3661 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3662 {
3663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3664 ret = -EINVAL;
3665 goto exit;
3666 }
3667
3668 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3669 value = value + 12;
3670 /* Convert the value from ascii to integer */
3671 ret = kstrtou8(value, 10, &tid);
3672 if (ret < 0)
3673 {
3674 /* If the input value is greater than max value of datatype, then also
3675 kstrtou8 fails */
3676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3677 "%s: kstrtou8 failed range [%d - %d]", __func__,
3678 TID_MIN_VALUE,
3679 TID_MAX_VALUE);
3680 ret = -EINVAL;
3681 goto exit;
3682 }
3683
3684 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3685 {
3686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3687 "tid value %d is out of range"
3688 " (Min: %d Max: %d)", tid,
3689 TID_MIN_VALUE,
3690 TID_MAX_VALUE);
3691 ret = -EINVAL;
3692 goto exit;
3693 }
3694
3695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3696 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3697
3698 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3699 {
3700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3701 "%s: failed to get tsm stats", __func__);
3702 ret = -EFAULT;
3703 goto exit;
3704 }
3705
3706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3707 "UplinkPktQueueDly(%d)\n"
3708 "UplinkPktQueueDlyHist[0](%d)\n"
3709 "UplinkPktQueueDlyHist[1](%d)\n"
3710 "UplinkPktQueueDlyHist[2](%d)\n"
3711 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303712 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003713 "UplinkPktLoss(%d)\n"
3714 "UplinkPktCount(%d)\n"
3715 "RoamingCount(%d)\n"
3716 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3717 tsmMetrics.UplinkPktQueueDlyHist[0],
3718 tsmMetrics.UplinkPktQueueDlyHist[1],
3719 tsmMetrics.UplinkPktQueueDlyHist[2],
3720 tsmMetrics.UplinkPktQueueDlyHist[3],
3721 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3722 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3723
3724 /* Output TSM stats is of the format
3725 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3726 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003727 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003728 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3729 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3730 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3731 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3732 tsmMetrics.RoamingDly);
3733
3734 if (copy_to_user(priv_data.buf, &extra, len + 1))
3735 {
3736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3737 "%s: failed to copy data to user buffer", __func__);
3738 ret = -EFAULT;
3739 goto exit;
3740 }
3741 }
3742 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3743 {
3744 tANI_U8 *value = command;
3745 tANI_U8 *cckmIe = NULL;
3746 tANI_U8 cckmIeLen = 0;
3747 eHalStatus status = eHAL_STATUS_SUCCESS;
3748
3749 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3750 if (eHAL_STATUS_SUCCESS != status)
3751 {
3752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3753 "%s: Failed to parse cckm ie data", __func__);
3754 ret = -EINVAL;
3755 goto exit;
3756 }
3757
3758 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3759 {
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3761 "%s: CCKM Ie input length is more than max[%d]", __func__,
3762 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003763 vos_mem_free(cckmIe);
3764 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003765 ret = -EINVAL;
3766 goto exit;
3767 }
3768 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003769 vos_mem_free(cckmIe);
3770 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003771 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003772 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3773 {
3774 tANI_U8 *value = command;
3775 tCsrCcxBeaconReq ccxBcnReq;
3776 eHalStatus status = eHAL_STATUS_SUCCESS;
3777 status = hdd_parse_ccx_beacon_req(value, &ccxBcnReq);
3778 if (eHAL_STATUS_SUCCESS != status)
3779 {
3780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3781 "%s: Failed to parse ccx beacon req", __func__);
3782 ret = -EINVAL;
3783 goto exit;
3784 }
3785
3786 sme_SetCcxBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &ccxBcnReq);
3787 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003788#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003789 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303790 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3791 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3792 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003793 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3794 __func__, command);
3795 }
3796
Jeff Johnson295189b2012-06-20 16:38:30 -07003797 }
3798exit:
3799 if (command)
3800 {
3801 kfree(command);
3802 }
3803 return ret;
3804}
3805
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003806
3807
3808#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003809/**---------------------------------------------------------------------------
3810
3811 \brief hdd_parse_ccx_beacon_req() - Parse ccx beacon request
3812
3813 This function parses the ccx beacon request passed in the format
3814 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3815 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3816 <space>Scan Mode N<space>Meas Duration N
3817 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3818 then take N.
3819 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3820 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3821 This function does not take care of removing duplicate channels from the list
3822
3823 \param - pValue Pointer to data
3824 \param - pCcxBcnReq output pointer to store parsed ie information
3825
3826 \return - 0 for success non-zero for failure
3827
3828 --------------------------------------------------------------------------*/
3829static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
3830 tCsrCcxBeaconReq *pCcxBcnReq)
3831{
3832 tANI_U8 *inPtr = pValue;
3833 int tempInt = 0;
3834 int j = 0, i = 0, v = 0;
3835 char buf[32];
3836
3837 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3838 /*no argument after the command*/
3839 if (NULL == inPtr)
3840 {
3841 return -EINVAL;
3842 }
3843 /*no space after the command*/
3844 else if (SPACE_ASCII_VALUE != *inPtr)
3845 {
3846 return -EINVAL;
3847 }
3848
3849 /*removing empty spaces*/
3850 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3851
3852 /*no argument followed by spaces*/
3853 if ('\0' == *inPtr) return -EINVAL;
3854
3855 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003856 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003857 if (1 != v) return -EINVAL;
3858
3859 v = kstrtos32(buf, 10, &tempInt);
3860 if ( v < 0) return -EINVAL;
3861
3862 pCcxBcnReq->numBcnReqIe = tempInt;
3863
3864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
3865 "Number of Bcn Req Ie fields(%d)", pCcxBcnReq->numBcnReqIe);
3866
3867 for (j = 0; j < (pCcxBcnReq->numBcnReqIe); j++)
3868 {
3869 for (i = 0; i < 4; i++)
3870 {
3871 /*inPtr pointing to the beginning of first space after number of ie fields*/
3872 inPtr = strpbrk( inPtr, " " );
3873 /*no ie data after the number of ie fields argument*/
3874 if (NULL == inPtr) return -EINVAL;
3875
3876 /*removing empty space*/
3877 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3878
3879 /*no ie data after the number of ie fields argument and spaces*/
3880 if ( '\0' == *inPtr ) return -EINVAL;
3881
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003882 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003883 if (1 != v) return -EINVAL;
3884
3885 v = kstrtos32(buf, 10, &tempInt);
3886 if (v < 0) return -EINVAL;
3887
3888 switch (i)
3889 {
3890 case 0: /* Measurement token */
3891 if (tempInt <= 0)
3892 {
3893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3894 "Invalid Measurement Token(%d)", tempInt);
3895 return -EINVAL;
3896 }
3897 pCcxBcnReq->bcnReq[j].measurementToken = tempInt;
3898 break;
3899
3900 case 1: /* Channel number */
3901 if ((tempInt <= 0) ||
3902 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
3903 {
3904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3905 "Invalid Channel Number(%d)", tempInt);
3906 return -EINVAL;
3907 }
3908 pCcxBcnReq->bcnReq[j].channel = tempInt;
3909 break;
3910
3911 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003912 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003913 {
3914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3915 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
3916 return -EINVAL;
3917 }
3918 pCcxBcnReq->bcnReq[j].scanMode= tempInt;
3919 break;
3920
3921 case 3: /* Measurement duration */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003922 if (((tempInt <= 0) && (pCcxBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
3923 ((tempInt < 0) && (pCcxBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003924 {
3925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3926 "Invalid Measurement Duration(%d)", tempInt);
3927 return -EINVAL;
3928 }
3929 pCcxBcnReq->bcnReq[j].measurementDuration = tempInt;
3930 break;
3931 }
3932 }
3933 }
3934
3935 for (j = 0; j < pCcxBcnReq->numBcnReqIe; j++)
3936 {
3937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303938 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003939 j,
3940 pCcxBcnReq->bcnReq[j].measurementToken,
3941 pCcxBcnReq->bcnReq[j].channel,
3942 pCcxBcnReq->bcnReq[j].scanMode,
3943 pCcxBcnReq->bcnReq[j].measurementDuration);
3944 }
3945
3946 return VOS_STATUS_SUCCESS;
3947}
3948
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003949static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
3950{
3951 struct statsContext *pStatsContext = NULL;
3952 hdd_adapter_t *pAdapter = NULL;
3953
3954 if (NULL == pContext)
3955 {
3956 hddLog(VOS_TRACE_LEVEL_ERROR,
3957 "%s: Bad param, pContext [%p]",
3958 __func__, pContext);
3959 return;
3960 }
3961
Jeff Johnson72a40512013-12-19 10:14:15 -08003962 /* there is a race condition that exists between this callback
3963 function and the caller since the caller could time out either
3964 before or while this code is executing. we use a spinlock to
3965 serialize these actions */
3966 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003967
3968 pStatsContext = pContext;
3969 pAdapter = pStatsContext->pAdapter;
3970 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
3971 {
3972 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08003973 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003974 hddLog(VOS_TRACE_LEVEL_WARN,
3975 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3976 __func__, pAdapter, pStatsContext->magic);
3977 return;
3978 }
3979
Jeff Johnson72a40512013-12-19 10:14:15 -08003980 /* context is valid so caller is still waiting */
3981
3982 /* paranoia: invalidate the magic */
3983 pStatsContext->magic = 0;
3984
3985 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003986 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
3987 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
3988 tsmMetrics.UplinkPktQueueDlyHist,
3989 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
3990 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
3991 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
3992 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
3993 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
3994 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
3995 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
3996
Jeff Johnson72a40512013-12-19 10:14:15 -08003997 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003998 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08003999
4000 /* serialization is complete */
4001 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004002}
4003
4004
4005
4006static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4007 tAniTrafStrmMetrics* pTsmMetrics)
4008{
4009 hdd_station_ctx_t *pHddStaCtx = NULL;
4010 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004011 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004012 long lrc;
4013 struct statsContext context;
4014 hdd_context_t *pHddCtx = NULL;
4015
4016 if (NULL == pAdapter)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4019 return VOS_STATUS_E_FAULT;
4020 }
4021
4022 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4023 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4024
4025 /* we are connected prepare our callback context */
4026 init_completion(&context.completion);
4027 context.pAdapter = pAdapter;
4028 context.magic = STATS_CONTEXT_MAGIC;
4029
4030 /* query tsm stats */
4031 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4032 pHddStaCtx->conn_info.staId[ 0 ],
4033 pHddStaCtx->conn_info.bssId,
4034 &context, pHddCtx->pvosContext, tid);
4035
4036 if (eHAL_STATUS_SUCCESS != hstatus)
4037 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4039 __func__);
4040 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004041 }
4042 else
4043 {
4044 /* request was sent -- wait for the response */
4045 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4046 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004047 if (lrc <= 0)
4048 {
4049 hddLog(VOS_TRACE_LEVEL_ERROR,
4050 "%s: SME %s while retrieving statistics",
4051 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004052 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004053 }
4054 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004055
Jeff Johnson72a40512013-12-19 10:14:15 -08004056 /* either we never sent a request, we sent a request and received a
4057 response or we sent a request and timed out. if we never sent a
4058 request or if we sent a request and got a response, we want to
4059 clear the magic out of paranoia. if we timed out there is a
4060 race condition such that the callback function could be
4061 executing at the same time we are. of primary concern is if the
4062 callback function had already verified the "magic" but had not
4063 yet set the completion variable when a timeout occurred. we
4064 serialize these activities by invalidating the magic while
4065 holding a shared spinlock which will cause us to block if the
4066 callback is currently executing */
4067 spin_lock(&hdd_context_lock);
4068 context.magic = 0;
4069 spin_unlock(&hdd_context_lock);
4070
4071 if (VOS_STATUS_SUCCESS == vstatus)
4072 {
4073 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4074 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4075 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4076 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4077 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4078 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4079 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4080 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4081 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4082 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4083 }
4084 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004085}
4086#endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4087
Srinivas Girigowdade697412013-02-14 16:31:48 -08004088#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
4089void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4090{
4091 eCsrBand band = -1;
4092 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4093 switch (band)
4094 {
4095 case eCSR_BAND_ALL:
4096 *pBand = WLAN_HDD_UI_BAND_AUTO;
4097 break;
4098
4099 case eCSR_BAND_24:
4100 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4101 break;
4102
4103 case eCSR_BAND_5G:
4104 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4105 break;
4106
4107 default:
4108 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4109 *pBand = -1;
4110 break;
4111 }
4112}
4113
4114/**---------------------------------------------------------------------------
4115
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004116 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4117
4118 This function parses the send action frame data passed in the format
4119 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4120
Srinivas Girigowda56076852013-08-20 14:00:50 -07004121 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004122 \param - pTargetApBssid Pointer to target Ap bssid
4123 \param - pChannel Pointer to the Target AP channel
4124 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4125 \param - pBuf Pointer to data
4126 \param - pBufLen Pointer to data length
4127
4128 \return - 0 for success non-zero for failure
4129
4130 --------------------------------------------------------------------------*/
4131VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4132 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4133{
4134 tANI_U8 *inPtr = pValue;
4135 tANI_U8 *dataEnd;
4136 int tempInt;
4137 int j = 0;
4138 int i = 0;
4139 int v = 0;
4140 tANI_U8 tempBuf[32];
4141 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004142 /* 12 hexa decimal digits, 5 ':' and '\0' */
4143 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004144
4145 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4146 /*no argument after the command*/
4147 if (NULL == inPtr)
4148 {
4149 return -EINVAL;
4150 }
4151
4152 /*no space after the command*/
4153 else if (SPACE_ASCII_VALUE != *inPtr)
4154 {
4155 return -EINVAL;
4156 }
4157
4158 /*removing empty spaces*/
4159 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4160
4161 /*no argument followed by spaces*/
4162 if ('\0' == *inPtr)
4163 {
4164 return -EINVAL;
4165 }
4166
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004167 v = sscanf(inPtr, "%17s", macAddress);
4168 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004169 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4171 "Invalid MAC address or All hex inputs are not read (%d)", v);
4172 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004173 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004174
4175 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4176 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4177 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4178 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4179 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4180 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004181
4182 /* point to the next argument */
4183 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4184 /*no argument after the command*/
4185 if (NULL == inPtr) return -EINVAL;
4186
4187 /*removing empty spaces*/
4188 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4189
4190 /*no argument followed by spaces*/
4191 if ('\0' == *inPtr)
4192 {
4193 return -EINVAL;
4194 }
4195
4196 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004197 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004198 if (1 != v) return -EINVAL;
4199
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004200 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashishc0126762014-02-17 19:30:26 +05304201 if ( v < 0 || tempInt < 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304202 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004203
4204 *pChannel = tempInt;
4205
4206 /* point to the next argument */
4207 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4208 /*no argument after the command*/
4209 if (NULL == inPtr) return -EINVAL;
4210 /*removing empty spaces*/
4211 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4212
4213 /*no argument followed by spaces*/
4214 if ('\0' == *inPtr)
4215 {
4216 return -EINVAL;
4217 }
4218
4219 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004220 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004221 if (1 != v) return -EINVAL;
4222
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004223 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004224 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004225
4226 *pDwellTime = tempInt;
4227
4228 /* point to the next argument */
4229 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4230 /*no argument after the command*/
4231 if (NULL == inPtr) return -EINVAL;
4232 /*removing empty spaces*/
4233 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4234
4235 /*no argument followed by spaces*/
4236 if ('\0' == *inPtr)
4237 {
4238 return -EINVAL;
4239 }
4240
4241 /* find the length of data */
4242 dataEnd = inPtr;
4243 while(('\0' != *dataEnd) )
4244 {
4245 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004246 }
Kiet Lambe150c22013-11-21 16:30:32 +05304247 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004248 if ( *pBufLen <= 0) return -EINVAL;
4249
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004250 /* Allocate the number of bytes based on the number of input characters
4251 whether it is even or odd.
4252 if the number of input characters are even, then we need N/2 byte.
4253 if the number of input characters are odd, then we need do (N+1)/2 to
4254 compensate rounding off.
4255 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4256 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4257 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004258 if (NULL == *pBuf)
4259 {
4260 hddLog(VOS_TRACE_LEVEL_FATAL,
4261 "%s: vos_mem_alloc failed ", __func__);
4262 return -EINVAL;
4263 }
4264
4265 /* the buffer received from the upper layer is character buffer,
4266 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4267 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4268 and f0 in 3rd location */
4269 for (i = 0, j = 0; j < *pBufLen; j += 2)
4270 {
Kiet Lambe150c22013-11-21 16:30:32 +05304271 if( j+1 == *pBufLen)
4272 {
4273 tempByte = hdd_parse_hex(inPtr[j]);
4274 }
4275 else
4276 {
4277 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4278 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004279 (*pBuf)[i++] = tempByte;
4280 }
4281 *pBufLen = i;
4282 return VOS_STATUS_SUCCESS;
4283}
4284
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004285/**---------------------------------------------------------------------------
4286
Srinivas Girigowdade697412013-02-14 16:31:48 -08004287 \brief hdd_parse_channellist() - HDD Parse channel list
4288
4289 This function parses the channel list passed in the format
4290 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004291 if the Number of channels (N) does not match with the actual number of channels passed
4292 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4293 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4294 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4295 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004296
4297 \param - pValue Pointer to input channel list
4298 \param - ChannelList Pointer to local output array to record channel list
4299 \param - pNumChannels Pointer to number of roam scan channels
4300
4301 \return - 0 for success non-zero for failure
4302
4303 --------------------------------------------------------------------------*/
4304VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4305{
4306 tANI_U8 *inPtr = pValue;
4307 int tempInt;
4308 int j = 0;
4309 int v = 0;
4310 char buf[32];
4311
4312 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4313 /*no argument after the command*/
4314 if (NULL == inPtr)
4315 {
4316 return -EINVAL;
4317 }
4318
4319 /*no space after the command*/
4320 else if (SPACE_ASCII_VALUE != *inPtr)
4321 {
4322 return -EINVAL;
4323 }
4324
4325 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004326 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004327
4328 /*no argument followed by spaces*/
4329 if ('\0' == *inPtr)
4330 {
4331 return -EINVAL;
4332 }
4333
4334 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004335 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004336 if (1 != v) return -EINVAL;
4337
Srinivas Girigowdade697412013-02-14 16:31:48 -08004338 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004339 if ((v < 0) ||
4340 (tempInt <= 0) ||
4341 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4342 {
4343 return -EINVAL;
4344 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004345
4346 *pNumChannels = tempInt;
4347
4348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4349 "Number of channels are: %d", *pNumChannels);
4350
4351 for (j = 0; j < (*pNumChannels); j++)
4352 {
4353 /*inPtr pointing to the beginning of first space after number of channels*/
4354 inPtr = strpbrk( inPtr, " " );
4355 /*no channel list after the number of channels argument*/
4356 if (NULL == inPtr)
4357 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004358 if (0 != j)
4359 {
4360 *pNumChannels = j;
4361 return VOS_STATUS_SUCCESS;
4362 }
4363 else
4364 {
4365 return -EINVAL;
4366 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004367 }
4368
4369 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004370 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004371
4372 /*no channel list after the number of channels argument and spaces*/
4373 if ( '\0' == *inPtr )
4374 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004375 if (0 != j)
4376 {
4377 *pNumChannels = j;
4378 return VOS_STATUS_SUCCESS;
4379 }
4380 else
4381 {
4382 return -EINVAL;
4383 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004384 }
4385
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004386 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004387 if (1 != v) return -EINVAL;
4388
Srinivas Girigowdade697412013-02-14 16:31:48 -08004389 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004390 if ((v < 0) ||
4391 (tempInt <= 0) ||
4392 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4393 {
4394 return -EINVAL;
4395 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004396 pChannelList[j] = tempInt;
4397
4398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4399 "Channel %d added to preferred channel list",
4400 pChannelList[j] );
4401 }
4402
Srinivas Girigowdade697412013-02-14 16:31:48 -08004403 return VOS_STATUS_SUCCESS;
4404}
4405
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004406
4407/**---------------------------------------------------------------------------
4408
4409 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4410
4411 This function parses the reasoc command data passed in the format
4412 REASSOC<space><bssid><space><channel>
4413
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004414 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004415 \param - pTargetApBssid Pointer to target Ap bssid
4416 \param - pChannel Pointer to the Target AP channel
4417
4418 \return - 0 for success non-zero for failure
4419
4420 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004421VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4422 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004423{
4424 tANI_U8 *inPtr = pValue;
4425 int tempInt;
4426 int v = 0;
4427 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004428 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004429 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004430
4431 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4432 /*no argument after the command*/
4433 if (NULL == inPtr)
4434 {
4435 return -EINVAL;
4436 }
4437
4438 /*no space after the command*/
4439 else if (SPACE_ASCII_VALUE != *inPtr)
4440 {
4441 return -EINVAL;
4442 }
4443
4444 /*removing empty spaces*/
4445 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4446
4447 /*no argument followed by spaces*/
4448 if ('\0' == *inPtr)
4449 {
4450 return -EINVAL;
4451 }
4452
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004453 v = sscanf(inPtr, "%17s", macAddress);
4454 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004455 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4457 "Invalid MAC address or All hex inputs are not read (%d)", v);
4458 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004459 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004460
4461 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4462 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4463 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4464 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4465 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4466 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004467
4468 /* point to the next argument */
4469 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4470 /*no argument after the command*/
4471 if (NULL == inPtr) return -EINVAL;
4472
4473 /*removing empty spaces*/
4474 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4475
4476 /*no argument followed by spaces*/
4477 if ('\0' == *inPtr)
4478 {
4479 return -EINVAL;
4480 }
4481
4482 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004483 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004484 if (1 != v) return -EINVAL;
4485
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004486 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004487 if ((v < 0) ||
4488 (tempInt <= 0) ||
4489 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4490 {
4491 return -EINVAL;
4492 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004493
4494 *pChannel = tempInt;
4495 return VOS_STATUS_SUCCESS;
4496}
4497
4498#endif
4499
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004500#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
4501/**---------------------------------------------------------------------------
4502
4503 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4504
4505 This function parses the SETCCKM IE command
4506 SETCCKMIE<space><ie data>
4507
4508 \param - pValue Pointer to input data
4509 \param - pCckmIe Pointer to output cckm Ie
4510 \param - pCckmIeLen Pointer to output cckm ie length
4511
4512 \return - 0 for success non-zero for failure
4513
4514 --------------------------------------------------------------------------*/
4515VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4516 tANI_U8 *pCckmIeLen)
4517{
4518 tANI_U8 *inPtr = pValue;
4519 tANI_U8 *dataEnd;
4520 int j = 0;
4521 int i = 0;
4522 tANI_U8 tempByte = 0;
4523
4524 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4525 /*no argument after the command*/
4526 if (NULL == inPtr)
4527 {
4528 return -EINVAL;
4529 }
4530
4531 /*no space after the command*/
4532 else if (SPACE_ASCII_VALUE != *inPtr)
4533 {
4534 return -EINVAL;
4535 }
4536
4537 /*removing empty spaces*/
4538 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4539
4540 /*no argument followed by spaces*/
4541 if ('\0' == *inPtr)
4542 {
4543 return -EINVAL;
4544 }
4545
4546 /* find the length of data */
4547 dataEnd = inPtr;
4548 while(('\0' != *dataEnd) )
4549 {
4550 dataEnd++;
4551 ++(*pCckmIeLen);
4552 }
4553 if ( *pCckmIeLen <= 0) return -EINVAL;
4554
4555 /* Allocate the number of bytes based on the number of input characters
4556 whether it is even or odd.
4557 if the number of input characters are even, then we need N/2 byte.
4558 if the number of input characters are odd, then we need do (N+1)/2 to
4559 compensate rounding off.
4560 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4561 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4562 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4563 if (NULL == *pCckmIe)
4564 {
4565 hddLog(VOS_TRACE_LEVEL_FATAL,
4566 "%s: vos_mem_alloc failed ", __func__);
4567 return -EINVAL;
4568 }
4569 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4570 /* the buffer received from the upper layer is character buffer,
4571 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4572 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4573 and f0 in 3rd location */
4574 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4575 {
4576 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4577 (*pCckmIe)[i++] = tempByte;
4578 }
4579 *pCckmIeLen = i;
4580
4581 return VOS_STATUS_SUCCESS;
4582}
4583#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4584
Jeff Johnson295189b2012-06-20 16:38:30 -07004585/**---------------------------------------------------------------------------
4586
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004587 \brief hdd_is_valid_mac_address() - Validate MAC address
4588
4589 This function validates whether the given MAC address is valid or not
4590 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4591 where X is the hexa decimal digit character and separated by ':'
4592 This algorithm works even if MAC address is not separated by ':'
4593
4594 This code checks given input string mac contains exactly 12 hexadecimal digits.
4595 and a separator colon : appears in the input string only after
4596 an even number of hex digits.
4597
4598 \param - pMacAddr pointer to the input MAC address
4599 \return - 1 for valid and 0 for invalid
4600
4601 --------------------------------------------------------------------------*/
4602
4603v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4604{
4605 int xdigit = 0;
4606 int separator = 0;
4607 while (*pMacAddr)
4608 {
4609 if (isxdigit(*pMacAddr))
4610 {
4611 xdigit++;
4612 }
4613 else if (':' == *pMacAddr)
4614 {
4615 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4616 break;
4617
4618 ++separator;
4619 }
4620 else
4621 {
4622 separator = -1;
4623 /* Invalid MAC found */
4624 return 0;
4625 }
4626 ++pMacAddr;
4627 }
4628 return (xdigit == 12 && (separator == 5 || separator == 0));
4629}
4630
4631/**---------------------------------------------------------------------------
4632
Jeff Johnson295189b2012-06-20 16:38:30 -07004633 \brief hdd_open() - HDD Open function
4634
4635 This is called in response to ifconfig up
4636
4637 \param - dev Pointer to net_device structure
4638
4639 \return - 0 for success non-zero for failure
4640
4641 --------------------------------------------------------------------------*/
4642int hdd_open (struct net_device *dev)
4643{
4644 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4645 hdd_context_t *pHddCtx;
4646 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4647 VOS_STATUS status;
4648 v_BOOL_t in_standby = TRUE;
4649
4650 if (NULL == pAdapter)
4651 {
4652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304653 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 return -ENODEV;
4655 }
4656
4657 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304658 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4659 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 if (NULL == pHddCtx)
4661 {
4662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004663 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004664 return -ENODEV;
4665 }
4666
4667 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4668 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4669 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004670 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4671 {
4672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304673 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004674 in_standby = FALSE;
4675 break;
4676 }
4677 else
4678 {
4679 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4680 pAdapterNode = pNext;
4681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004682 }
4683
4684 if (TRUE == in_standby)
4685 {
4686 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4687 {
4688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4689 "wlan out of power save", __func__);
4690 return -EINVAL;
4691 }
4692 }
4693
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004694 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4696 {
4697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004698 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004699 /* Enable TX queues only when we are connected */
4700 netif_tx_start_all_queues(dev);
4701 }
4702
4703 return 0;
4704}
4705
4706int hdd_mon_open (struct net_device *dev)
4707{
4708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4709
4710 if(pAdapter == NULL) {
4711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004712 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004713 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004714 }
4715
4716 netif_start_queue(dev);
4717
4718 return 0;
4719}
4720/**---------------------------------------------------------------------------
4721
4722 \brief hdd_stop() - HDD stop function
4723
4724 This is called in response to ifconfig down
4725
4726 \param - dev Pointer to net_device structure
4727
4728 \return - 0 for success non-zero for failure
4729
4730 --------------------------------------------------------------------------*/
4731
4732int hdd_stop (struct net_device *dev)
4733{
4734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4735 hdd_context_t *pHddCtx;
4736 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4737 VOS_STATUS status;
4738 v_BOOL_t enter_standby = TRUE;
4739
4740 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004741 if (NULL == pAdapter)
4742 {
4743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304744 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004745 return -ENODEV;
4746 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304747 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4748 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004749 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4750 if (NULL == pHddCtx)
4751 {
4752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004753 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004754 return -ENODEV;
4755 }
4756
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004757 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4759 netif_tx_disable(pAdapter->dev);
4760 netif_carrier_off(pAdapter->dev);
4761
4762
4763 /* SoftAP ifaces should never go in power save mode
4764 making sure same here. */
4765 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4766 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004767 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004768 )
4769 {
4770 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4772 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004773 EXIT();
4774 return 0;
4775 }
4776
4777 /* Find if any iface is up then
4778 if any iface is up then can't put device to sleep/ power save mode. */
4779 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4780 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4781 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004782 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4783 {
4784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304785 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004786 enter_standby = FALSE;
4787 break;
4788 }
4789 else
4790 {
4791 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4792 pAdapterNode = pNext;
4793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004794 }
4795
4796 if (TRUE == enter_standby)
4797 {
4798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4799 "entering standby", __func__);
4800 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4801 {
4802 /*log and return success*/
4803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4804 "wlan in power save", __func__);
4805 }
4806 }
4807
4808 EXIT();
4809 return 0;
4810}
4811
4812/**---------------------------------------------------------------------------
4813
4814 \brief hdd_uninit() - HDD uninit function
4815
4816 This is called during the netdev unregister to uninitialize all data
4817associated with the device
4818
4819 \param - dev Pointer to net_device structure
4820
4821 \return - void
4822
4823 --------------------------------------------------------------------------*/
4824static void hdd_uninit (struct net_device *dev)
4825{
4826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4827
4828 ENTER();
4829
4830 do
4831 {
4832 if (NULL == pAdapter)
4833 {
4834 hddLog(VOS_TRACE_LEVEL_FATAL,
4835 "%s: NULL pAdapter", __func__);
4836 break;
4837 }
4838
4839 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4840 {
4841 hddLog(VOS_TRACE_LEVEL_FATAL,
4842 "%s: Invalid magic", __func__);
4843 break;
4844 }
4845
4846 if (NULL == pAdapter->pHddCtx)
4847 {
4848 hddLog(VOS_TRACE_LEVEL_FATAL,
4849 "%s: NULL pHddCtx", __func__);
4850 break;
4851 }
4852
4853 if (dev != pAdapter->dev)
4854 {
4855 hddLog(VOS_TRACE_LEVEL_FATAL,
4856 "%s: Invalid device reference", __func__);
4857 /* we haven't validated all cases so let this go for now */
4858 }
4859
4860 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4861
4862 /* after uninit our adapter structure will no longer be valid */
4863 pAdapter->dev = NULL;
4864 pAdapter->magic = 0;
4865 } while (0);
4866
4867 EXIT();
4868}
4869
4870/**---------------------------------------------------------------------------
4871
4872 \brief hdd_release_firmware() -
4873
4874 This function calls the release firmware API to free the firmware buffer.
4875
4876 \param - pFileName Pointer to the File Name.
4877 pCtx - Pointer to the adapter .
4878
4879
4880 \return - 0 for success, non zero for failure
4881
4882 --------------------------------------------------------------------------*/
4883
4884VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4885{
4886 VOS_STATUS status = VOS_STATUS_SUCCESS;
4887 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4888 ENTER();
4889
4890
4891 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4892
4893 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4894
4895 if(pHddCtx->fw) {
4896 release_firmware(pHddCtx->fw);
4897 pHddCtx->fw = NULL;
4898 }
4899 else
4900 status = VOS_STATUS_E_FAILURE;
4901 }
4902 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
4903 if(pHddCtx->nv) {
4904 release_firmware(pHddCtx->nv);
4905 pHddCtx->nv = NULL;
4906 }
4907 else
4908 status = VOS_STATUS_E_FAILURE;
4909
4910 }
4911
4912 EXIT();
4913 return status;
4914}
4915
4916/**---------------------------------------------------------------------------
4917
4918 \brief hdd_request_firmware() -
4919
4920 This function reads the firmware file using the request firmware
4921 API and returns the the firmware data and the firmware file size.
4922
4923 \param - pfileName - Pointer to the file name.
4924 - pCtx - Pointer to the adapter .
4925 - ppfw_data - Pointer to the pointer of the firmware data.
4926 - pSize - Pointer to the file size.
4927
4928 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
4929
4930 --------------------------------------------------------------------------*/
4931
4932
4933VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
4934{
4935 int status;
4936 VOS_STATUS retval = VOS_STATUS_SUCCESS;
4937 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4938 ENTER();
4939
4940 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
4941
4942 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
4943
4944 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4945 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
4946 __func__, pfileName);
4947 retval = VOS_STATUS_E_FAILURE;
4948 }
4949
4950 else {
4951 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
4952 *pSize = pHddCtx->fw->size;
4953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
4954 __func__, *pSize);
4955 }
4956 }
4957 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
4958
4959 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
4960
4961 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
4962 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
4963 __func__, pfileName);
4964 retval = VOS_STATUS_E_FAILURE;
4965 }
4966
4967 else {
4968 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
4969 *pSize = pHddCtx->nv->size;
4970 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
4971 __func__, *pSize);
4972 }
4973 }
4974
4975 EXIT();
4976 return retval;
4977}
4978/**---------------------------------------------------------------------------
4979 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
4980
4981 This is the function invoked by SME to inform the result of a full power
4982 request issued by HDD
4983
4984 \param - callbackcontext - Pointer to cookie
4985 status - result of request
4986
4987 \return - None
4988
4989--------------------------------------------------------------------------*/
4990void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
4991{
4992 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
4993
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004994 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 if(&pHddCtx->full_pwr_comp_var)
4996 {
4997 complete(&pHddCtx->full_pwr_comp_var);
4998 }
4999}
5000
5001/**---------------------------------------------------------------------------
5002
5003 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5004
5005 This is the function invoked by SME to inform the result of BMPS
5006 request issued by HDD
5007
5008 \param - callbackcontext - Pointer to cookie
5009 status - result of request
5010
5011 \return - None
5012
5013--------------------------------------------------------------------------*/
5014void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5015{
5016
5017 struct completion *completion_var = (struct completion*) callbackContext;
5018
Arif Hussain6d2a3322013-11-17 19:50:10 -08005019 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 if(completion_var != NULL)
5021 {
5022 complete(completion_var);
5023 }
5024}
5025
5026/**---------------------------------------------------------------------------
5027
5028 \brief hdd_get_cfg_file_size() -
5029
5030 This function reads the configuration file using the request firmware
5031 API and returns the configuration file size.
5032
5033 \param - pCtx - Pointer to the adapter .
5034 - pFileName - Pointer to the file name.
5035 - pBufSize - Pointer to the buffer size.
5036
5037 \return - 0 for success, non zero for failure
5038
5039 --------------------------------------------------------------------------*/
5040
5041VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5042{
5043 int status;
5044 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5045
5046 ENTER();
5047
5048 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5049
5050 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5051 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5052 status = VOS_STATUS_E_FAILURE;
5053 }
5054 else {
5055 *pBufSize = pHddCtx->fw->size;
5056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5057 release_firmware(pHddCtx->fw);
5058 pHddCtx->fw = NULL;
5059 }
5060
5061 EXIT();
5062 return VOS_STATUS_SUCCESS;
5063}
5064
5065/**---------------------------------------------------------------------------
5066
5067 \brief hdd_read_cfg_file() -
5068
5069 This function reads the configuration file using the request firmware
5070 API and returns the cfg data and the buffer size of the configuration file.
5071
5072 \param - pCtx - Pointer to the adapter .
5073 - pFileName - Pointer to the file name.
5074 - pBuffer - Pointer to the data buffer.
5075 - pBufSize - Pointer to the buffer size.
5076
5077 \return - 0 for success, non zero for failure
5078
5079 --------------------------------------------------------------------------*/
5080
5081VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5082 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5083{
5084 int status;
5085 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5086
5087 ENTER();
5088
5089 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5090
5091 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5092 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5093 return VOS_STATUS_E_FAILURE;
5094 }
5095 else {
5096 if(*pBufSize != pHddCtx->fw->size) {
5097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5098 "file size", __func__);
5099 release_firmware(pHddCtx->fw);
5100 pHddCtx->fw = NULL;
5101 return VOS_STATUS_E_FAILURE;
5102 }
5103 else {
5104 if(pBuffer) {
5105 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5106 }
5107 release_firmware(pHddCtx->fw);
5108 pHddCtx->fw = NULL;
5109 }
5110 }
5111
5112 EXIT();
5113
5114 return VOS_STATUS_SUCCESS;
5115}
5116
5117/**---------------------------------------------------------------------------
5118
Jeff Johnson295189b2012-06-20 16:38:30 -07005119 \brief hdd_set_mac_address() -
5120
5121 This function sets the user specified mac address using
5122 the command ifconfig wlanX hw ether <mac adress>.
5123
5124 \param - dev - Pointer to the net device.
5125 - addr - Pointer to the sockaddr.
5126 \return - 0 for success, non zero for failure
5127
5128 --------------------------------------------------------------------------*/
5129
5130static int hdd_set_mac_address(struct net_device *dev, void *addr)
5131{
5132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5133 struct sockaddr *psta_mac_addr = addr;
5134 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5135
5136 ENTER();
5137
5138 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5139
5140#ifdef HDD_SESSIONIZE
5141 // set the MAC address though the STA ID CFG.
5142 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5143 (v_U8_t *)&pAdapter->macAddressCurrent,
5144 sizeof( pAdapter->macAddressCurrent ),
5145 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305146
5147 if(eHAL_STATUS_SUCCESS != halStatus)
5148 {
5149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5150 "%s: failed to set MAC address in CFG", __func__);
5151 }
5152
Jeff Johnson295189b2012-06-20 16:38:30 -07005153#endif
5154
5155 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5156
5157 EXIT();
5158 return halStatus;
5159}
5160
5161tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5162{
5163 int i;
5164 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5165 {
Abhishek Singheb183782014-02-06 13:37:21 +05305166 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005167 break;
5168 }
5169
5170 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5171 return NULL;
5172
5173 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5174 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5175}
5176
5177void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5178{
5179 int i;
5180 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5181 {
5182 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5183 {
5184 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5185 break;
5186 }
5187 }
5188 return;
5189}
5190
5191#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5192 static struct net_device_ops wlan_drv_ops = {
5193 .ndo_open = hdd_open,
5194 .ndo_stop = hdd_stop,
5195 .ndo_uninit = hdd_uninit,
5196 .ndo_start_xmit = hdd_hard_start_xmit,
5197 .ndo_tx_timeout = hdd_tx_timeout,
5198 .ndo_get_stats = hdd_stats,
5199 .ndo_do_ioctl = hdd_ioctl,
5200 .ndo_set_mac_address = hdd_set_mac_address,
5201 .ndo_select_queue = hdd_select_queue,
5202#ifdef WLAN_FEATURE_PACKET_FILTERING
5203#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5204 .ndo_set_rx_mode = hdd_set_multicast_list,
5205#else
5206 .ndo_set_multicast_list = hdd_set_multicast_list,
5207#endif //LINUX_VERSION_CODE
5208#endif
5209 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 static struct net_device_ops wlan_mon_drv_ops = {
5211 .ndo_open = hdd_mon_open,
5212 .ndo_stop = hdd_stop,
5213 .ndo_uninit = hdd_uninit,
5214 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5215 .ndo_tx_timeout = hdd_tx_timeout,
5216 .ndo_get_stats = hdd_stats,
5217 .ndo_do_ioctl = hdd_ioctl,
5218 .ndo_set_mac_address = hdd_set_mac_address,
5219 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005220
5221#endif
5222
5223void hdd_set_station_ops( struct net_device *pWlanDev )
5224{
5225#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005226 pWlanDev->netdev_ops = &wlan_drv_ops;
5227#else
5228 pWlanDev->open = hdd_open;
5229 pWlanDev->stop = hdd_stop;
5230 pWlanDev->uninit = hdd_uninit;
5231 pWlanDev->hard_start_xmit = NULL;
5232 pWlanDev->tx_timeout = hdd_tx_timeout;
5233 pWlanDev->get_stats = hdd_stats;
5234 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 pWlanDev->set_mac_address = hdd_set_mac_address;
5236#endif
5237}
5238
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005239static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005240{
5241 struct net_device *pWlanDev = NULL;
5242 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 /*
5244 * cfg80211 initialization and registration....
5245 */
5246 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5247
Jeff Johnson295189b2012-06-20 16:38:30 -07005248 if(pWlanDev != NULL)
5249 {
5250
5251 //Save the pointer to the net_device in the HDD adapter
5252 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5253
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5255
5256 pAdapter->dev = pWlanDev;
5257 pAdapter->pHddCtx = pHddCtx;
5258 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5259
5260 init_completion(&pAdapter->session_open_comp_var);
5261 init_completion(&pAdapter->session_close_comp_var);
5262 init_completion(&pAdapter->disconnect_comp_var);
5263 init_completion(&pAdapter->linkup_event_var);
5264 init_completion(&pAdapter->cancel_rem_on_chan_var);
5265 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305266 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005267#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5268 init_completion(&pAdapter->offchannel_tx_event);
5269#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005271#ifdef FEATURE_WLAN_TDLS
5272 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005273 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005274 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305275 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005276#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005277 init_completion(&pHddCtx->mc_sus_event_var);
5278 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305279 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005280 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005281 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005282
Rajeev79dbe4c2013-10-05 11:03:42 +05305283#ifdef FEATURE_WLAN_BATCH_SCAN
5284 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5285 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5286 pAdapter->pBatchScanRsp = NULL;
5287 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005288 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005289 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305290 mutex_init(&pAdapter->hdd_batch_scan_lock);
5291#endif
5292
Jeff Johnson295189b2012-06-20 16:38:30 -07005293 pAdapter->isLinkUpSvcNeeded = FALSE;
5294 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5295 //Init the net_device structure
5296 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5297
5298 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5299 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5300 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5301 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5302
5303 hdd_set_station_ops( pAdapter->dev );
5304
5305 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005306 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5307 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5308 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 /* set pWlanDev's parent to underlying device */
5310 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5311 }
5312
5313 return pAdapter;
5314}
5315
5316VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5317{
5318 struct net_device *pWlanDev = pAdapter->dev;
5319 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5320 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5321 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5322
5323 if( rtnl_lock_held )
5324 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005325 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005326 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5327 {
5328 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5329 return VOS_STATUS_E_FAILURE;
5330 }
5331 }
5332 if (register_netdevice(pWlanDev))
5333 {
5334 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5335 return VOS_STATUS_E_FAILURE;
5336 }
5337 }
5338 else
5339 {
5340 if(register_netdev(pWlanDev))
5341 {
5342 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5343 return VOS_STATUS_E_FAILURE;
5344 }
5345 }
5346 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5347
5348 return VOS_STATUS_SUCCESS;
5349}
5350
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005351static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005352{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005353 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005354
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005355 if (NULL == pAdapter)
5356 {
5357 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5358 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005360
5361 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5362 {
5363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5364 return eHAL_STATUS_NOT_INITIALIZED;
5365 }
5366
5367 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5368
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005369#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005370 /* need to make sure all of our scheduled work has completed.
5371 * This callback is called from MC thread context, so it is safe to
5372 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005373 *
5374 * Even though this is called from MC thread context, if there is a faulty
5375 * work item in the system, that can hang this call forever. So flushing
5376 * this global work queue is not safe; and now we make sure that
5377 * individual work queues are stopped correctly. But the cancel work queue
5378 * is a GPL only API, so the proprietary version of the driver would still
5379 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005380 */
5381 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005382#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005383
5384 /* We can be blocked while waiting for scheduled work to be
5385 * flushed, and the adapter structure can potentially be freed, in
5386 * which case the magic will have been reset. So make sure the
5387 * magic is still good, and hence the adapter structure is still
5388 * valid, before signaling completion */
5389 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5390 {
5391 complete(&pAdapter->session_close_comp_var);
5392 }
5393
Jeff Johnson295189b2012-06-20 16:38:30 -07005394 return eHAL_STATUS_SUCCESS;
5395}
5396
5397VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5398{
5399 struct net_device *pWlanDev = pAdapter->dev;
5400 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5401 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5402 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5403 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305404 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005405
5406 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005407 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005408 //Open a SME session for future operation
5409 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005410 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005411 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5412 {
5413 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005414 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 halStatus, halStatus );
5416 status = VOS_STATUS_E_FAILURE;
5417 goto error_sme_open;
5418 }
5419
5420 //Block on a completion variable. Can't wait forever though.
5421 rc = wait_for_completion_interruptible_timeout(
5422 &pAdapter->session_open_comp_var,
5423 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305424 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 {
5426 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305427 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 status = VOS_STATUS_E_FAILURE;
5429 goto error_sme_open;
5430 }
5431
5432 // Register wireless extensions
5433 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5434 {
5435 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005436 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 halStatus, halStatus );
5438 status = VOS_STATUS_E_FAILURE;
5439 goto error_register_wext;
5440 }
5441 //Safe to register the hard_start_xmit function again
5442#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5443 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5444#else
5445 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5446#endif
5447
5448 //Set the Connection State to Not Connected
5449 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5450
5451 //Set the default operation channel
5452 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5453
5454 /* Make the default Auth Type as OPEN*/
5455 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5456
5457 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5458 {
5459 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005460 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 status, status );
5462 goto error_init_txrx;
5463 }
5464
5465 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5466
5467 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5468 {
5469 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005470 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 status, status );
5472 goto error_wmm_init;
5473 }
5474
5475 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5476
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005477#ifdef FEATURE_WLAN_TDLS
5478 if(0 != wlan_hdd_tdls_init(pAdapter))
5479 {
5480 status = VOS_STATUS_E_FAILURE;
5481 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5482 goto error_tdls_init;
5483 }
5484 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5485#endif
5486
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 return VOS_STATUS_SUCCESS;
5488
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005489#ifdef FEATURE_WLAN_TDLS
5490error_tdls_init:
5491 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5492 hdd_wmm_adapter_close(pAdapter);
5493#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005494error_wmm_init:
5495 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5496 hdd_deinit_tx_rx(pAdapter);
5497error_init_txrx:
5498 hdd_UnregisterWext(pWlanDev);
5499error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005500 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 {
5502 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005503 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005505 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305507 unsigned long rc;
5508
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305510 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005512 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305513 if (rc <= 0)
5514 hddLog(VOS_TRACE_LEVEL_ERROR,
5515 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 }
5517}
5518error_sme_open:
5519 return status;
5520}
5521
Jeff Johnson295189b2012-06-20 16:38:30 -07005522void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5523{
5524 hdd_cfg80211_state_t *cfgState;
5525
5526 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5527
5528 if( NULL != cfgState->buf )
5529 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305530 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5532 rc = wait_for_completion_interruptible_timeout(
5533 &pAdapter->tx_action_cnf_event,
5534 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305535 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305538 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5539 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 }
5541 }
5542 return;
5543}
Jeff Johnson295189b2012-06-20 16:38:30 -07005544
5545void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5546{
5547 ENTER();
5548 switch ( pAdapter->device_mode )
5549 {
5550 case WLAN_HDD_INFRA_STATION:
5551 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005552 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 {
5554 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5555 {
5556 hdd_deinit_tx_rx( pAdapter );
5557 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5558 }
5559
5560 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5561 {
5562 hdd_wmm_adapter_close( pAdapter );
5563 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5564 }
5565
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005567#ifdef FEATURE_WLAN_TDLS
5568 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5569 {
5570 wlan_hdd_tdls_exit(pAdapter);
5571 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5572 }
5573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005574
5575 break;
5576 }
5577
5578 case WLAN_HDD_SOFTAP:
5579 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305581
5582 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5583 {
5584 hdd_wmm_adapter_close( pAdapter );
5585 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5586 }
5587
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005589
5590 hdd_unregister_hostapd(pAdapter);
5591 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 break;
5594 }
5595
5596 case WLAN_HDD_MONITOR:
5597 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5600 {
5601 hdd_deinit_tx_rx( pAdapter );
5602 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 if(NULL != pAdapterforTx)
5605 {
5606 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 break;
5609 }
5610
5611
5612 default:
5613 break;
5614 }
5615
5616 EXIT();
5617}
5618
5619void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5620{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005621 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305622
5623 ENTER();
5624 if (NULL == pAdapter)
5625 {
5626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5627 "%s: HDD adapter is Null", __func__);
5628 return;
5629 }
5630
5631 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005632
Rajeev79dbe4c2013-10-05 11:03:42 +05305633#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305634 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5635 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005636 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305637 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5638 )
5639 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005640 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305641 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005642 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5643 {
5644 hdd_deinit_batch_scan(pAdapter);
5645 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305646 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005647 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305648#endif
5649
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5651 if( rtnl_held )
5652 {
5653 unregister_netdevice(pWlanDev);
5654 }
5655 else
5656 {
5657 unregister_netdev(pWlanDev);
5658 }
5659 // note that the pAdapter is no longer valid at this point
5660 // since the memory has been reclaimed
5661 }
5662
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305663 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005664}
5665
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005666void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5667{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305668 VOS_STATUS status;
5669 hdd_adapter_t *pAdapter = NULL;
5670 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005671
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305672 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005673
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305674 /*loop through all adapters.*/
5675 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005676 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305677 pAdapter = pAdapterNode->pAdapter;
5678 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5679 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005680
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305681 { // we skip this registration for modes other than STA and P2P client modes.
5682 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5683 pAdapterNode = pNext;
5684 continue;
5685 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005686
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305687 //Apply Dynamic DTIM For P2P
5688 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5689 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5690 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5691 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5692 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5693 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5694 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5695 (eConnectionState_Associated ==
5696 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5697 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5698 {
5699 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005700
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305701 powerRequest.uIgnoreDTIM = 1;
5702 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5703
5704 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5705 {
5706 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5707 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5708 }
5709 else
5710 {
5711 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5712 }
5713
5714 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5715 * specified during Enter/Exit BMPS when LCD off*/
5716 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5717 NULL, eANI_BOOLEAN_FALSE);
5718 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5719 NULL, eANI_BOOLEAN_FALSE);
5720
5721 /* switch to the DTIM specified in cfg.ini */
5722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5723 "Switch to DTIM %d", powerRequest.uListenInterval);
5724 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5725 break;
5726
5727 }
5728
5729 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5730 pAdapterNode = pNext;
5731 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005732}
5733
5734void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5735{
5736 /*Switch back to DTIM 1*/
5737 tSirSetPowerParamsReq powerRequest = { 0 };
5738
5739 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5740 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005741 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005742
5743 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5744 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5745 NULL, eANI_BOOLEAN_FALSE);
5746 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5747 NULL, eANI_BOOLEAN_FALSE);
5748
5749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5750 "Switch to DTIM%d",powerRequest.uListenInterval);
5751 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5752
5753}
5754
Jeff Johnson295189b2012-06-20 16:38:30 -07005755VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5756{
5757 VOS_STATUS status = VOS_STATUS_SUCCESS;
5758
5759 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5760 {
5761 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5762 }
5763
5764 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5765 {
5766 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5767 }
5768
5769 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5770 {
5771 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5772 }
5773
5774 return status;
5775}
5776
5777VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5778{
5779 hdd_adapter_t *pAdapter = NULL;
5780 eHalStatus halStatus;
5781 VOS_STATUS status = VOS_STATUS_E_INVAL;
5782 v_BOOL_t disableBmps = FALSE;
5783 v_BOOL_t disableImps = FALSE;
5784
5785 switch(session_type)
5786 {
5787 case WLAN_HDD_INFRA_STATION:
5788 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 case WLAN_HDD_P2P_CLIENT:
5790 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 //Exit BMPS -> Is Sta/P2P Client is already connected
5792 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5793 if((NULL != pAdapter)&&
5794 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5795 {
5796 disableBmps = TRUE;
5797 }
5798
5799 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5800 if((NULL != pAdapter)&&
5801 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5802 {
5803 disableBmps = TRUE;
5804 }
5805
5806 //Exit both Bmps and Imps incase of Go/SAP Mode
5807 if((WLAN_HDD_SOFTAP == session_type) ||
5808 (WLAN_HDD_P2P_GO == session_type))
5809 {
5810 disableBmps = TRUE;
5811 disableImps = TRUE;
5812 }
5813
5814 if(TRUE == disableImps)
5815 {
5816 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5817 {
5818 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5819 }
5820 }
5821
5822 if(TRUE == disableBmps)
5823 {
5824 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5825 {
5826 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5827
5828 if(eHAL_STATUS_SUCCESS != halStatus)
5829 {
5830 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005831 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 VOS_ASSERT(0);
5833 return status;
5834 }
5835 }
5836
5837 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5838 {
5839 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5840
5841 if(eHAL_STATUS_SUCCESS != halStatus)
5842 {
5843 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005844 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 VOS_ASSERT(0);
5846 return status;
5847 }
5848 }
5849 }
5850
5851 if((TRUE == disableBmps) ||
5852 (TRUE == disableImps))
5853 {
5854 /* Now, get the chip into Full Power now */
5855 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5856 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5857 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5858
5859 if(halStatus != eHAL_STATUS_SUCCESS)
5860 {
5861 if(halStatus == eHAL_STATUS_PMC_PENDING)
5862 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305863 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305865 ret = wait_for_completion_interruptible_timeout(
5866 &pHddCtx->full_pwr_comp_var,
5867 msecs_to_jiffies(1000));
5868 if (ret <= 0)
5869 {
5870 hddLog(VOS_TRACE_LEVEL_ERROR,
5871 "%s: wait on full_pwr_comp_var failed %ld",
5872 __func__, ret);
5873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 }
5875 else
5876 {
5877 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005878 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 VOS_ASSERT(0);
5880 return status;
5881 }
5882 }
5883
5884 status = VOS_STATUS_SUCCESS;
5885 }
5886
5887 break;
5888 }
5889 return status;
5890}
5891
5892hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005893 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 tANI_U8 rtnl_held )
5895{
5896 hdd_adapter_t *pAdapter = NULL;
5897 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5898 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5899 VOS_STATUS exitbmpsStatus;
5900
Arif Hussain6d2a3322013-11-17 19:50:10 -08005901 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
Nirav Shah436658f2014-02-28 17:05:45 +05305903 if(macAddr == NULL)
5904 {
5905 /* Not received valid macAddr */
5906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5907 "%s:Unable to add virtual intf: Not able to get"
5908 "valid mac address",__func__);
5909 return NULL;
5910 }
5911
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 //Disable BMPS incase of Concurrency
5913 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
5914
5915 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
5916 {
5917 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305918 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 VOS_ASSERT(0);
5920 return NULL;
5921 }
5922
5923 switch(session_type)
5924 {
5925 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005927 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 {
5929 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5930
5931 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305932 {
5933 hddLog(VOS_TRACE_LEVEL_FATAL,
5934 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305936 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005937
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305938#ifdef FEATURE_WLAN_TDLS
5939 /* A Mutex Lock is introduced while changing/initializing the mode to
5940 * protect the concurrent access for the Adapters by TDLS module.
5941 */
5942 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
5943 {
5944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5945 "%s: unable to lock list", __func__);
5946 return NULL;
5947 }
5948#endif
5949
Jeff Johnsone7245742012-09-05 17:12:55 -07005950 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
5951 NL80211_IFTYPE_P2P_CLIENT:
5952 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07005953
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305955#ifdef FEATURE_WLAN_TDLS
5956 mutex_unlock(&pHddCtx->tdls_lock);
5957#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05305958
5959 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 if( VOS_STATUS_SUCCESS != status )
5961 goto err_free_netdev;
5962
5963 status = hdd_register_interface( pAdapter, rtnl_held );
5964 if( VOS_STATUS_SUCCESS != status )
5965 {
5966 hdd_deinit_adapter(pHddCtx, pAdapter);
5967 goto err_free_netdev;
5968 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305969
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05305970 // Workqueue which gets scheduled in IPv4 notification callback.
5971 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
5972
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305973#ifdef WLAN_NS_OFFLOAD
5974 // Workqueue which gets scheduled in IPv6 notification callback.
5975 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
5976#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 //Stop the Interface TX queue.
5978 netif_tx_disable(pAdapter->dev);
5979 //netif_tx_disable(pWlanDev);
5980 netif_carrier_off(pAdapter->dev);
5981
5982 break;
5983 }
5984
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 case WLAN_HDD_SOFTAP:
5987 {
5988 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
5989 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305990 {
5991 hddLog(VOS_TRACE_LEVEL_FATAL,
5992 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005995
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
5997 NL80211_IFTYPE_AP:
5998 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 pAdapter->device_mode = session_type;
6000
6001 status = hdd_init_ap_mode(pAdapter);
6002 if( VOS_STATUS_SUCCESS != status )
6003 goto err_free_netdev;
6004
6005 status = hdd_register_hostapd( pAdapter, rtnl_held );
6006 if( VOS_STATUS_SUCCESS != status )
6007 {
6008 hdd_deinit_adapter(pHddCtx, pAdapter);
6009 goto err_free_netdev;
6010 }
6011
6012 netif_tx_disable(pAdapter->dev);
6013 netif_carrier_off(pAdapter->dev);
6014
6015 hdd_set_conparam( 1 );
6016 break;
6017 }
6018 case WLAN_HDD_MONITOR:
6019 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6021 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306022 {
6023 hddLog(VOS_TRACE_LEVEL_FATAL,
6024 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006027
6028 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6029 pAdapter->device_mode = session_type;
6030 status = hdd_register_interface( pAdapter, rtnl_held );
6031#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6032 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6033#else
6034 pAdapter->dev->open = hdd_mon_open;
6035 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6036#endif
6037 hdd_init_tx_rx( pAdapter );
6038 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6039 //Set adapter to be used for data tx. It will use either GO or softap.
6040 pAdapter->sessionCtx.monitor.pAdapterForTx =
6041 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6043 {
6044 pAdapter->sessionCtx.monitor.pAdapterForTx =
6045 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6046 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 /* This workqueue will be used to transmit management packet over
6048 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006049 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6050 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6051 return NULL;
6052 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006053
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6055 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 }
6057 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 case WLAN_HDD_FTM:
6059 {
6060 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6061
6062 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306063 {
6064 hddLog(VOS_TRACE_LEVEL_FATAL,
6065 FL("failed to allocate adapter for session %d"), session_type);
6066 return NULL;
6067 }
6068
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6070 * message while loading driver in FTM mode. */
6071 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6072 pAdapter->device_mode = session_type;
6073 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306074
6075 hdd_init_tx_rx( pAdapter );
6076
6077 //Stop the Interface TX queue.
6078 netif_tx_disable(pAdapter->dev);
6079 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 }
6081 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006082 default:
6083 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306084 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6085 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 VOS_ASSERT(0);
6087 return NULL;
6088 }
6089 }
6090
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 if( VOS_STATUS_SUCCESS == status )
6092 {
6093 //Add it to the hdd's session list.
6094 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6095 if( NULL == pHddAdapterNode )
6096 {
6097 status = VOS_STATUS_E_NOMEM;
6098 }
6099 else
6100 {
6101 pHddAdapterNode->pAdapter = pAdapter;
6102 status = hdd_add_adapter_back ( pHddCtx,
6103 pHddAdapterNode );
6104 }
6105 }
6106
6107 if( VOS_STATUS_SUCCESS != status )
6108 {
6109 if( NULL != pAdapter )
6110 {
6111 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6112 pAdapter = NULL;
6113 }
6114 if( NULL != pHddAdapterNode )
6115 {
6116 vos_mem_free( pHddAdapterNode );
6117 }
6118
6119 goto resume_bmps;
6120 }
6121
6122 if(VOS_STATUS_SUCCESS == status)
6123 {
6124 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6125
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006126 //Initialize the WoWL service
6127 if(!hdd_init_wowl(pAdapter))
6128 {
6129 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6130 goto err_free_netdev;
6131 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 return pAdapter;
6134
6135err_free_netdev:
6136 free_netdev(pAdapter->dev);
6137 wlan_hdd_release_intf_addr( pHddCtx,
6138 pAdapter->macAddressCurrent.bytes );
6139
6140resume_bmps:
6141 //If bmps disabled enable it
6142 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6143 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306144 if (pHddCtx->hdd_wlan_suspended)
6145 {
6146 hdd_set_pwrparams(pHddCtx);
6147 }
6148 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 }
6150 return NULL;
6151}
6152
6153VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6154 tANI_U8 rtnl_held )
6155{
6156 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6157 VOS_STATUS status;
6158
6159 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6160 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306161 {
6162 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6163 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306165 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006166
6167 while ( pCurrent->pAdapter != pAdapter )
6168 {
6169 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6170 if( VOS_STATUS_SUCCESS != status )
6171 break;
6172
6173 pCurrent = pNext;
6174 }
6175 pAdapterNode = pCurrent;
6176 if( VOS_STATUS_SUCCESS == status )
6177 {
6178 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6179 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306180
6181#ifdef FEATURE_WLAN_TDLS
6182
6183 /* A Mutex Lock is introduced while changing/initializing the mode to
6184 * protect the concurrent access for the Adapters by TDLS module.
6185 */
6186 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
6187 {
6188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6189 "%s: unable to lock list", __func__);
6190 return VOS_STATUS_E_FAILURE;
6191 }
6192#endif
6193
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 hdd_remove_adapter( pHddCtx, pAdapterNode );
6195 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006196 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006197
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306198#ifdef FEATURE_WLAN_TDLS
6199 mutex_unlock(&pHddCtx->tdls_lock);
6200#endif
6201
Jeff Johnson295189b2012-06-20 16:38:30 -07006202
6203 /* If there is a single session of STA/P2P client, re-enable BMPS */
6204 if ((!vos_concurrent_sessions_running()) &&
6205 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6206 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6207 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306208 if (pHddCtx->hdd_wlan_suspended)
6209 {
6210 hdd_set_pwrparams(pHddCtx);
6211 }
6212 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 }
6214
6215 return VOS_STATUS_SUCCESS;
6216 }
6217
6218 return VOS_STATUS_E_FAILURE;
6219}
6220
6221VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6222{
6223 hdd_adapter_list_node_t *pHddAdapterNode;
6224 VOS_STATUS status;
6225
6226 ENTER();
6227
6228 do
6229 {
6230 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6231 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6232 {
6233 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6234 vos_mem_free( pHddAdapterNode );
6235 }
6236 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6237
6238 EXIT();
6239
6240 return VOS_STATUS_SUCCESS;
6241}
6242
6243void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6244{
6245 v_U8_t addIE[1] = {0};
6246
6247 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6248 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6249 eANI_BOOLEAN_FALSE) )
6250 {
6251 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006252 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 }
6254
6255 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6256 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6257 eANI_BOOLEAN_FALSE) )
6258 {
6259 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006260 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 }
6262
6263 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6264 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6265 eANI_BOOLEAN_FALSE) )
6266 {
6267 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006268 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 }
6270}
6271
6272VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6273{
6274 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6275 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6276 union iwreq_data wrqu;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278
6279 ENTER();
6280
6281 switch(pAdapter->device_mode)
6282 {
6283 case WLAN_HDD_INFRA_STATION:
6284 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006285 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6287 {
6288 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6289 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6290 pAdapter->sessionId,
6291 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6292 else
6293 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6294 pAdapter->sessionId,
6295 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6296 //success implies disconnect command got queued up successfully
6297 if(halStatus == eHAL_STATUS_SUCCESS)
6298 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306299 ret = wait_for_completion_interruptible_timeout(
6300 &pAdapter->disconnect_comp_var,
6301 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6302 if (ret <= 0)
6303 {
6304 hddLog(VOS_TRACE_LEVEL_ERROR,
6305 "%s: wait on disconnect_comp_var failed %ld",
6306 __func__, ret);
6307 }
6308 }
6309 else
6310 {
6311 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6312 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 }
6314 memset(&wrqu, '\0', sizeof(wrqu));
6315 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6316 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6317 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6318 }
6319 else
6320 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306321 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6322 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306324#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306325#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306326 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6327#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306328 if (pAdapter->ipv6_notifier_registered)
6329 {
6330 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6331 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6332 pAdapter->ipv6_notifier_registered = false;
6333 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306334#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306335 if (pAdapter->ipv4_notifier_registered)
6336 {
6337 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6338 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6339 pAdapter->ipv4_notifier_registered = false;
6340 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306341#ifdef WLAN_OPEN_SOURCE
6342 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6345 {
6346 INIT_COMPLETION(pAdapter->session_close_comp_var);
6347 if (eHAL_STATUS_SUCCESS ==
6348 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6349 hdd_smeCloseSessionCallback, pAdapter))
6350 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306351 unsigned long ret;
6352
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306354 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 &pAdapter->session_close_comp_var,
6356 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306357 if ( 0 >= ret)
6358 {
6359 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6360 __func__, ret);
6361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 }
6363 }
6364
6365 break;
6366
6367 case WLAN_HDD_SOFTAP:
6368 case WLAN_HDD_P2P_GO:
6369 //Any softap specific cleanup here...
6370 mutex_lock(&pHddCtx->sap_lock);
6371 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6372 {
6373 VOS_STATUS status;
6374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6375
6376 //Stop Bss.
6377 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6378 if (VOS_IS_STATUS_SUCCESS(status))
6379 {
6380 hdd_hostapd_state_t *pHostapdState =
6381 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6382
6383 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6384
6385 if (!VOS_IS_STATUS_SUCCESS(status))
6386 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306387 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6388 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 }
6390 }
6391 else
6392 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006393 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 }
6395 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6396
6397 if (eHAL_STATUS_FAILURE ==
6398 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6399 0, NULL, eANI_BOOLEAN_FALSE))
6400 {
6401 hddLog(LOGE,
6402 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006403 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 }
6405
6406 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6407 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6408 eANI_BOOLEAN_FALSE) )
6409 {
6410 hddLog(LOGE,
6411 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6412 }
6413
6414 // Reset WNI_CFG_PROBE_RSP Flags
6415 wlan_hdd_reset_prob_rspies(pAdapter);
6416 kfree(pAdapter->sessionCtx.ap.beacon);
6417 pAdapter->sessionCtx.ap.beacon = NULL;
6418 }
6419 mutex_unlock(&pHddCtx->sap_lock);
6420 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006421
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006423#ifdef WLAN_OPEN_SOURCE
6424 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006427
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 default:
6429 break;
6430 }
6431
6432 EXIT();
6433 return VOS_STATUS_SUCCESS;
6434}
6435
6436VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6437{
6438 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6439 VOS_STATUS status;
6440 hdd_adapter_t *pAdapter;
6441
6442 ENTER();
6443
6444 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6445
6446 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6447 {
6448 pAdapter = pAdapterNode->pAdapter;
6449 netif_tx_disable(pAdapter->dev);
6450 netif_carrier_off(pAdapter->dev);
6451
6452 hdd_stop_adapter( pHddCtx, pAdapter );
6453
6454 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6455 pAdapterNode = pNext;
6456 }
6457
6458 EXIT();
6459
6460 return VOS_STATUS_SUCCESS;
6461}
6462
Rajeev Kumarf999e582014-01-09 17:33:29 -08006463
6464#ifdef FEATURE_WLAN_BATCH_SCAN
6465/**---------------------------------------------------------------------------
6466
6467 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6468 structures
6469
6470 \param - pAdapter Pointer to HDD adapter
6471
6472 \return - None
6473
6474 --------------------------------------------------------------------------*/
6475void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6476{
6477 tHddBatchScanRsp *pNode;
6478 tHddBatchScanRsp *pPrev;
6479
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306480 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006481 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306482 hddLog(VOS_TRACE_LEVEL_ERROR,
6483 "%s: Adapter context is Null", __func__);
6484 return;
6485 }
6486
6487 pNode = pAdapter->pBatchScanRsp;
6488 while (pNode)
6489 {
6490 pPrev = pNode;
6491 pNode = pNode->pNext;
6492 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006493 }
6494
6495 pAdapter->pBatchScanRsp = NULL;
6496 pAdapter->numScanList = 0;
6497 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6498 pAdapter->prev_batch_id = 0;
6499
6500 return;
6501}
6502#endif
6503
6504
Jeff Johnson295189b2012-06-20 16:38:30 -07006505VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6506{
6507 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6508 VOS_STATUS status;
6509 hdd_adapter_t *pAdapter;
6510
6511 ENTER();
6512
6513 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6514
6515 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6516 {
6517 pAdapter = pAdapterNode->pAdapter;
6518 netif_tx_disable(pAdapter->dev);
6519 netif_carrier_off(pAdapter->dev);
6520
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006521 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6522
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306524 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6525 {
6526 hdd_wmm_adapter_close( pAdapter );
6527 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006529
Rajeev Kumarf999e582014-01-09 17:33:29 -08006530#ifdef FEATURE_WLAN_BATCH_SCAN
6531 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6532 {
6533 hdd_deinit_batch_scan(pAdapter);
6534 }
6535#endif
6536
Jeff Johnson295189b2012-06-20 16:38:30 -07006537 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6538 pAdapterNode = pNext;
6539 }
6540
6541 EXIT();
6542
6543 return VOS_STATUS_SUCCESS;
6544}
6545
6546VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6547{
6548 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6549 VOS_STATUS status;
6550 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306551 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006552
6553 ENTER();
6554
6555 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6556
6557 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6558 {
6559 pAdapter = pAdapterNode->pAdapter;
6560
6561 switch(pAdapter->device_mode)
6562 {
6563 case WLAN_HDD_INFRA_STATION:
6564 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006565 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306566
6567 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6568
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 hdd_init_station_mode(pAdapter);
6570 /* Open the gates for HDD to receive Wext commands */
6571 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006572 pHddCtx->scan_info.mScanPending = FALSE;
6573 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006574
6575 //Trigger the initial scan
6576 hdd_wlan_initial_scan(pAdapter);
6577
6578 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306579 if (eConnectionState_Associated == connState ||
6580 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 {
6582 union iwreq_data wrqu;
6583 memset(&wrqu, '\0', sizeof(wrqu));
6584 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6585 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6586 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006587 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006588
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 /* indicate disconnected event to nl80211 */
6590 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6591 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306593 else if (eConnectionState_Connecting == connState)
6594 {
6595 /*
6596 * Indicate connect failure to supplicant if we were in the
6597 * process of connecting
6598 */
6599 cfg80211_connect_result(pAdapter->dev, NULL,
6600 NULL, 0, NULL, 0,
6601 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6602 GFP_KERNEL);
6603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 break;
6605
6606 case WLAN_HDD_SOFTAP:
6607 /* softAP can handle SSR */
6608 break;
6609
6610 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006613 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 break;
6615
6616 case WLAN_HDD_MONITOR:
6617 /* monitor interface start */
6618 break;
6619 default:
6620 break;
6621 }
6622
6623 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6624 pAdapterNode = pNext;
6625 }
6626
6627 EXIT();
6628
6629 return VOS_STATUS_SUCCESS;
6630}
6631
6632VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6633{
6634 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6635 hdd_adapter_t *pAdapter;
6636 VOS_STATUS status;
6637 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306638 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006639
6640 ENTER();
6641
6642 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6643
6644 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6645 {
6646 pAdapter = pAdapterNode->pAdapter;
6647
6648 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6649 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6650 {
6651 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6652 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6653
6654 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6655 init_completion(&pAdapter->disconnect_comp_var);
6656 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6657 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6658
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306659 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 &pAdapter->disconnect_comp_var,
6661 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306662 if (0 >= ret)
6663 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6664 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006665
6666 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6667 pHddCtx->isAmpAllowed = VOS_FALSE;
6668 sme_RoamConnect(pHddCtx->hHal,
6669 pAdapter->sessionId, &(pWextState->roamProfile),
6670 &roamId);
6671 }
6672
6673 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6674 pAdapterNode = pNext;
6675 }
6676
6677 EXIT();
6678
6679 return VOS_STATUS_SUCCESS;
6680}
6681
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006682void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6683{
6684 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6685 VOS_STATUS status;
6686 hdd_adapter_t *pAdapter;
6687 hdd_station_ctx_t *pHddStaCtx;
6688 hdd_ap_ctx_t *pHddApCtx;
6689 hdd_hostapd_state_t * pHostapdState;
6690 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6691 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6692 const char *p2pMode = "DEV";
6693 const char *ccMode = "Standalone";
6694 int n;
6695
6696 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6697 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6698 {
6699 pAdapter = pAdapterNode->pAdapter;
6700 switch (pAdapter->device_mode) {
6701 case WLAN_HDD_INFRA_STATION:
6702 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6703 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6704 staChannel = pHddStaCtx->conn_info.operationChannel;
6705 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6706 }
6707 break;
6708 case WLAN_HDD_P2P_CLIENT:
6709 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6710 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6711 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6712 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6713 p2pMode = "CLI";
6714 }
6715 break;
6716 case WLAN_HDD_P2P_GO:
6717 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6718 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6719 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6720 p2pChannel = pHddApCtx->operatingChannel;
6721 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6722 }
6723 p2pMode = "GO";
6724 break;
6725 case WLAN_HDD_SOFTAP:
6726 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6727 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6728 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6729 apChannel = pHddApCtx->operatingChannel;
6730 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6731 }
6732 break;
6733 default:
6734 break;
6735 }
6736 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6737 pAdapterNode = pNext;
6738 }
6739 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6740 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6741 }
6742 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6743 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6744 if (p2pChannel > 0) {
6745 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6746 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6747 }
6748 if (apChannel > 0) {
6749 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6750 apChannel, MAC_ADDR_ARRAY(apBssid));
6751 }
6752
6753 if (p2pChannel > 0 && apChannel > 0) {
6754 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6755 }
6756}
6757
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006758bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006759{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006760 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006761}
6762
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006763/* Once SSR is disabled then it cannot be set. */
6764void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006765{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006766 if (HDD_SSR_DISABLED == isSsrRequired)
6767 return;
6768
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 isSsrRequired = value;
6770}
6771
6772VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6773 hdd_adapter_list_node_t** ppAdapterNode)
6774{
6775 VOS_STATUS status;
6776 spin_lock(&pHddCtx->hddAdapters.lock);
6777 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6778 (hdd_list_node_t**) ppAdapterNode );
6779 spin_unlock(&pHddCtx->hddAdapters.lock);
6780 return status;
6781}
6782
6783VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6784 hdd_adapter_list_node_t* pAdapterNode,
6785 hdd_adapter_list_node_t** pNextAdapterNode)
6786{
6787 VOS_STATUS status;
6788 spin_lock(&pHddCtx->hddAdapters.lock);
6789 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6790 (hdd_list_node_t*) pAdapterNode,
6791 (hdd_list_node_t**)pNextAdapterNode );
6792
6793 spin_unlock(&pHddCtx->hddAdapters.lock);
6794 return status;
6795}
6796
6797VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6798 hdd_adapter_list_node_t* pAdapterNode)
6799{
6800 VOS_STATUS status;
6801 spin_lock(&pHddCtx->hddAdapters.lock);
6802 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6803 &pAdapterNode->node );
6804 spin_unlock(&pHddCtx->hddAdapters.lock);
6805 return status;
6806}
6807
6808VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6809 hdd_adapter_list_node_t** ppAdapterNode)
6810{
6811 VOS_STATUS status;
6812 spin_lock(&pHddCtx->hddAdapters.lock);
6813 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6814 (hdd_list_node_t**) ppAdapterNode );
6815 spin_unlock(&pHddCtx->hddAdapters.lock);
6816 return status;
6817}
6818
6819VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6820 hdd_adapter_list_node_t* pAdapterNode)
6821{
6822 VOS_STATUS status;
6823 spin_lock(&pHddCtx->hddAdapters.lock);
6824 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6825 (hdd_list_node_t*) pAdapterNode );
6826 spin_unlock(&pHddCtx->hddAdapters.lock);
6827 return status;
6828}
6829
6830VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6831 hdd_adapter_list_node_t* pAdapterNode)
6832{
6833 VOS_STATUS status;
6834 spin_lock(&pHddCtx->hddAdapters.lock);
6835 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6836 (hdd_list_node_t*) pAdapterNode );
6837 spin_unlock(&pHddCtx->hddAdapters.lock);
6838 return status;
6839}
6840
6841hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6842 tSirMacAddr macAddr )
6843{
6844 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6845 hdd_adapter_t *pAdapter;
6846 VOS_STATUS status;
6847
6848 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6849
6850 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6851 {
6852 pAdapter = pAdapterNode->pAdapter;
6853
6854 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
6855 macAddr, sizeof(tSirMacAddr) ) )
6856 {
6857 return pAdapter;
6858 }
6859 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6860 pAdapterNode = pNext;
6861 }
6862
6863 return NULL;
6864
6865}
6866
6867hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
6868{
6869 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6870 hdd_adapter_t *pAdapter;
6871 VOS_STATUS status;
6872
6873 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6874
6875 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6876 {
6877 pAdapter = pAdapterNode->pAdapter;
6878
6879 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
6880 IFNAMSIZ ) )
6881 {
6882 return pAdapter;
6883 }
6884 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6885 pAdapterNode = pNext;
6886 }
6887
6888 return NULL;
6889
6890}
6891
6892hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
6893{
6894 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6895 hdd_adapter_t *pAdapter;
6896 VOS_STATUS status;
6897
6898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6899
6900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6901 {
6902 pAdapter = pAdapterNode->pAdapter;
6903
6904 if( pAdapter && (mode == pAdapter->device_mode) )
6905 {
6906 return pAdapter;
6907 }
6908 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6909 pAdapterNode = pNext;
6910 }
6911
6912 return NULL;
6913
6914}
6915
6916//Remove this function later
6917hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
6918{
6919 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6920 hdd_adapter_t *pAdapter;
6921 VOS_STATUS status;
6922
6923 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6924
6925 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6926 {
6927 pAdapter = pAdapterNode->pAdapter;
6928
6929 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
6930 {
6931 return pAdapter;
6932 }
6933
6934 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6935 pAdapterNode = pNext;
6936 }
6937
6938 return NULL;
6939
6940}
6941
Jeff Johnson295189b2012-06-20 16:38:30 -07006942/**---------------------------------------------------------------------------
6943
6944 \brief hdd_set_monitor_tx_adapter() -
6945
6946 This API initializes the adapter to be used while transmitting on monitor
6947 adapter.
6948
6949 \param - pHddCtx - Pointer to the HDD context.
6950 pAdapter - Adapter that will used for TX. This can be NULL.
6951 \return - None.
6952 --------------------------------------------------------------------------*/
6953void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6954{
6955 hdd_adapter_t *pMonAdapter;
6956
6957 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
6958
6959 if( NULL != pMonAdapter )
6960 {
6961 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
6962 }
6963}
Jeff Johnson295189b2012-06-20 16:38:30 -07006964/**---------------------------------------------------------------------------
6965
6966 \brief hdd_select_queue() -
6967
6968 This API returns the operating channel of the requested device mode
6969
6970 \param - pHddCtx - Pointer to the HDD context.
6971 - mode - Device mode for which operating channel is required
6972 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
6973 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
6974 \return - channel number. "0" id the requested device is not found OR it is not connected.
6975 --------------------------------------------------------------------------*/
6976v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
6977{
6978 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6979 VOS_STATUS status;
6980 hdd_adapter_t *pAdapter;
6981 v_U8_t operatingChannel = 0;
6982
6983 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6984
6985 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6986 {
6987 pAdapter = pAdapterNode->pAdapter;
6988
6989 if( mode == pAdapter->device_mode )
6990 {
6991 switch(pAdapter->device_mode)
6992 {
6993 case WLAN_HDD_INFRA_STATION:
6994 case WLAN_HDD_P2P_CLIENT:
6995 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6996 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
6997 break;
6998 case WLAN_HDD_SOFTAP:
6999 case WLAN_HDD_P2P_GO:
7000 /*softap connection info */
7001 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7002 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7003 break;
7004 default:
7005 break;
7006 }
7007
7008 break; //Found the device of interest. break the loop
7009 }
7010
7011 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7012 pAdapterNode = pNext;
7013 }
7014 return operatingChannel;
7015}
7016
7017#ifdef WLAN_FEATURE_PACKET_FILTERING
7018/**---------------------------------------------------------------------------
7019
7020 \brief hdd_set_multicast_list() -
7021
7022 This used to set the multicast address list.
7023
7024 \param - dev - Pointer to the WLAN device.
7025 - skb - Pointer to OS packet (sk_buff).
7026 \return - success/fail
7027
7028 --------------------------------------------------------------------------*/
7029static void hdd_set_multicast_list(struct net_device *dev)
7030{
7031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 int mc_count;
7033 int i = 0;
7034 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307035
7036 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 {
7038 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307039 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 return;
7041 }
7042
7043 if (dev->flags & IFF_ALLMULTI)
7044 {
7045 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007046 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307047 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 }
7049 else
7050 {
7051 mc_count = netdev_mc_count(dev);
7052 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007053 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7055 {
7056 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007057 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307058 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 return;
7060 }
7061
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307062 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007063
7064 netdev_for_each_mc_addr(ha, dev) {
7065 if (i == mc_count)
7066 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307067 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7068 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007069 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007070 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307071 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 i++;
7073 }
7074 }
7075 return;
7076}
7077#endif
7078
7079/**---------------------------------------------------------------------------
7080
7081 \brief hdd_select_queue() -
7082
7083 This function is registered with the Linux OS for network
7084 core to decide which queue to use first.
7085
7086 \param - dev - Pointer to the WLAN device.
7087 - skb - Pointer to OS packet (sk_buff).
7088 \return - ac, Queue Index/access category corresponding to UP in IP header
7089
7090 --------------------------------------------------------------------------*/
7091v_U16_t hdd_select_queue(struct net_device *dev,
7092 struct sk_buff *skb)
7093{
7094 return hdd_wmm_select_queue(dev, skb);
7095}
7096
7097
7098/**---------------------------------------------------------------------------
7099
7100 \brief hdd_wlan_initial_scan() -
7101
7102 This function triggers the initial scan
7103
7104 \param - pAdapter - Pointer to the HDD adapter.
7105
7106 --------------------------------------------------------------------------*/
7107void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7108{
7109 tCsrScanRequest scanReq;
7110 tCsrChannelInfo channelInfo;
7111 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007112 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7114
7115 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7116 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7117 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7118
7119 if(sme_Is11dSupported(pHddCtx->hHal))
7120 {
7121 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7122 if ( HAL_STATUS_SUCCESS( halStatus ) )
7123 {
7124 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7125 if( !scanReq.ChannelInfo.ChannelList )
7126 {
7127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7128 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007129 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 return;
7131 }
7132 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7133 channelInfo.numOfChannels);
7134 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7135 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007136 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 }
7138
7139 scanReq.scanType = eSIR_PASSIVE_SCAN;
7140 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7141 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7142 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7143 }
7144 else
7145 {
7146 scanReq.scanType = eSIR_ACTIVE_SCAN;
7147 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7148 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7149 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7150 }
7151
7152 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7153 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7154 {
7155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7156 __func__, halStatus );
7157 }
7158
7159 if(sme_Is11dSupported(pHddCtx->hHal))
7160 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7161}
7162
Jeff Johnson295189b2012-06-20 16:38:30 -07007163/**---------------------------------------------------------------------------
7164
7165 \brief hdd_full_power_callback() - HDD full power callback function
7166
7167 This is the function invoked by SME to inform the result of a full power
7168 request issued by HDD
7169
7170 \param - callbackcontext - Pointer to cookie
7171 \param - status - result of request
7172
7173 \return - None
7174
7175 --------------------------------------------------------------------------*/
7176static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7177{
Jeff Johnson72a40512013-12-19 10:14:15 -08007178 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007179
7180 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307181 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007182
7183 if (NULL == callbackContext)
7184 {
7185 hddLog(VOS_TRACE_LEVEL_ERROR,
7186 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007187 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 return;
7189 }
7190
Jeff Johnson72a40512013-12-19 10:14:15 -08007191 /* there is a race condition that exists between this callback
7192 function and the caller since the caller could time out either
7193 before or while this code is executing. we use a spinlock to
7194 serialize these actions */
7195 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007196
7197 if (POWER_CONTEXT_MAGIC != pContext->magic)
7198 {
7199 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007200 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007201 hddLog(VOS_TRACE_LEVEL_WARN,
7202 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007203 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 return;
7205 }
7206
Jeff Johnson72a40512013-12-19 10:14:15 -08007207 /* context is valid so caller is still waiting */
7208
7209 /* paranoia: invalidate the magic */
7210 pContext->magic = 0;
7211
7212 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007214
7215 /* serialization is complete */
7216 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007217}
7218
7219/**---------------------------------------------------------------------------
7220
7221 \brief hdd_wlan_exit() - HDD WLAN exit function
7222
7223 This is the driver exit point (invoked during rmmod)
7224
7225 \param - pHddCtx - Pointer to the HDD Context
7226
7227 \return - None
7228
7229 --------------------------------------------------------------------------*/
7230void hdd_wlan_exit(hdd_context_t *pHddCtx)
7231{
7232 eHalStatus halStatus;
7233 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7234 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307235 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007236 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007237 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 long lrc;
7239
7240 ENTER();
7241
Jeff Johnson88ba7742013-02-27 14:36:02 -08007242 if (VOS_FTM_MODE != hdd_get_conparam())
7243 {
7244 // Unloading, restart logic is no more required.
7245 wlan_hdd_restart_deinit(pHddCtx);
7246 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007247
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 {
7252 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7253 WLAN_HDD_INFRA_STATION);
7254 if (pAdapter == NULL)
7255 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7256
7257 if (pAdapter != NULL)
7258 {
7259 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7260 hdd_UnregisterWext(pAdapter->dev);
7261 }
7262 }
7263 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007264
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007266 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307267 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007268 wlan_hdd_ftm_close(pHddCtx);
7269 goto free_hdd_ctx;
7270 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 //Stop the Interface TX queue.
7272 //netif_tx_disable(pWlanDev);
7273 //netif_carrier_off(pWlanDev);
7274
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7276 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307277 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 pAdapter = hdd_get_adapter(pHddCtx,
7279 WLAN_HDD_SOFTAP);
7280 }
7281 else
7282 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307285 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 pAdapter = hdd_get_adapter(pHddCtx,
7287 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007288 if (pAdapter == NULL)
7289 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307292
7293 if(NULL == pAdapter)
7294 {
7295 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7296 goto free_hdd_ctx;
7297 }
7298
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 /* DeRegister with platform driver as client for Suspend/Resume */
7300 vosStatus = hddDeregisterPmOps(pHddCtx);
7301 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7302 {
7303 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7304 VOS_ASSERT(0);
7305 }
7306
7307 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7308 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7309 {
7310 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007312
7313 // Cancel any outstanding scan requests. We are about to close all
7314 // of our adapters, but an adapter structure is what SME passes back
7315 // to our callback function. Hence if there are any outstanding scan
7316 // requests then there is a race condition between when the adapter
7317 // is closed and when the callback is invoked. We try to resolve that
7318 // race condition here by canceling any outstanding scans before we
7319 // close the adapters.
7320 // Note that the scans may be cancelled in an asynchronous manner, so
7321 // ideally there needs to be some kind of synchronization. Rather than
7322 // introduce a new synchronization here, we will utilize the fact that
7323 // we are about to Request Full Power, and since that is synchronized,
7324 // the expectation is that by the time Request Full Power has completed,
7325 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007326 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307327 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007328 else
7329 hddLog(VOS_TRACE_LEVEL_ERROR,
7330 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007331
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007332 //Stop the traffic monitor timer
7333 if ( VOS_TIMER_STATE_RUNNING ==
7334 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7335 {
7336 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7337 }
7338
7339 // Destroy the traffic monitor timer
7340 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7341 &pHddCtx->tx_rx_trafficTmr)))
7342 {
7343 hddLog(VOS_TRACE_LEVEL_ERROR,
7344 "%s: Cannot deallocate Traffic monitor timer", __func__);
7345 }
7346
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 //Disable IMPS/BMPS as we do not want the device to enter any power
7348 //save mode during shutdown
7349 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7350 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7351 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7352
7353 //Ensure that device is in full power as we will touch H/W during vos_Stop
7354 init_completion(&powerContext.completion);
7355 powerContext.magic = POWER_CONTEXT_MAGIC;
7356
7357 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7358 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7359
7360 if (eHAL_STATUS_SUCCESS != halStatus)
7361 {
7362 if (eHAL_STATUS_PMC_PENDING == halStatus)
7363 {
7364 /* request was sent -- wait for the response */
7365 lrc = wait_for_completion_interruptible_timeout(
7366 &powerContext.completion,
7367 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007368 if (lrc <= 0)
7369 {
7370 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007371 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 }
7373 }
7374 else
7375 {
7376 hddLog(VOS_TRACE_LEVEL_ERROR,
7377 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007378 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 /* continue -- need to clean up as much as possible */
7380 }
7381 }
7382
Jeff Johnson72a40512013-12-19 10:14:15 -08007383 /* either we never sent a request, we sent a request and received a
7384 response or we sent a request and timed out. if we never sent a
7385 request or if we sent a request and got a response, we want to
7386 clear the magic out of paranoia. if we timed out there is a
7387 race condition such that the callback function could be
7388 executing at the same time we are. of primary concern is if the
7389 callback function had already verified the "magic" but had not
7390 yet set the completion variable when a timeout occurred. we
7391 serialize these activities by invalidating the magic while
7392 holding a shared spinlock which will cause us to block if the
7393 callback is currently executing */
7394 spin_lock(&hdd_context_lock);
7395 powerContext.magic = 0;
7396 spin_unlock(&hdd_context_lock);
7397
Yue Ma0d4891e2013-08-06 17:01:45 -07007398 hdd_debugfs_exit(pHddCtx);
7399
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 // Unregister the Net Device Notifier
7401 unregister_netdevice_notifier(&hdd_netdev_notifier);
7402
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 hdd_stop_all_adapters( pHddCtx );
7404
Jeff Johnson295189b2012-06-20 16:38:30 -07007405#ifdef WLAN_BTAMP_FEATURE
7406 vosStatus = WLANBAP_Stop(pVosContext);
7407 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7408 {
7409 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7410 "%s: Failed to stop BAP",__func__);
7411 }
7412#endif //WLAN_BTAMP_FEATURE
7413
7414 //Stop all the modules
7415 vosStatus = vos_stop( pVosContext );
7416 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7417 {
7418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7419 "%s: Failed to stop VOSS",__func__);
7420 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7421 }
7422
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 //Assert Deep sleep signal now to put Libra HW in lowest power state
7424 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7425 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7426
7427 //Vote off any PMIC voltage supplies
7428 vos_chipPowerDown(NULL, NULL, NULL);
7429
7430 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7431
Leo Chang59cdc7e2013-07-10 10:08:21 -07007432
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007435
7436 //Close the scheduler before calling vos_close to make sure no thread is
7437 // scheduled after the each module close is called i.e after all the data
7438 // structures are freed.
7439 vosStatus = vos_sched_close( pVosContext );
7440 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7441 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7442 "%s: Failed to close VOSS Scheduler",__func__);
7443 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7444 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007445#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007446#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7447 /* Destroy the wake lock */
7448 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7449#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007450 /* Destroy the wake lock */
7451 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007452#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007453
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307454#ifdef CONFIG_ENABLE_LINUX_REG
7455 vosStatus = vos_nv_close();
7456 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7457 {
7458 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7459 "%s: Failed to close NV", __func__);
7460 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7461 }
7462#endif
7463
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 //Close VOSS
7465 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7466 vos_close(pVosContext);
7467
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 //Close Watchdog
7469 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7470 vos_watchdog_close(pVosContext);
7471
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307472 //Clean up HDD Nlink Service
7473 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007474#ifdef WLAN_KD_READY_NOTIFIER
7475 nl_srv_exit(pHddCtx->ptt_pid);
7476#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307477 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007478#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307479
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 /* Cancel the vote for XO Core ON.
7481 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7482 * exited at this point
7483 */
7484 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007485 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7487 {
7488 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7489 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007490 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 }
7492
7493 hdd_close_all_adapters( pHddCtx );
7494
7495
7496 //Free up dynamically allocated members inside HDD Adapter
7497 kfree(pHddCtx->cfg_ini);
7498 pHddCtx->cfg_ini= NULL;
7499
7500 /* free the power on lock from platform driver */
7501 if (free_riva_power_on_lock("wlan"))
7502 {
7503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7504 __func__);
7505 }
7506
Jeff Johnson88ba7742013-02-27 14:36:02 -08007507free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007508 /* FTM mode, WIPHY did not registered
7509 If un-register here, system crash will happen */
7510 if (VOS_FTM_MODE != hdd_get_conparam())
7511 {
7512 wiphy_unregister(wiphy) ;
7513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 if (hdd_is_ssr_required())
7516 {
7517 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007518 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 msleep(5000);
7520 }
7521 hdd_set_ssr_required (VOS_FALSE);
7522}
7523
7524
7525/**---------------------------------------------------------------------------
7526
7527 \brief hdd_update_config_from_nv() - Function to update the contents of
7528 the running configuration with parameters taken from NV storage
7529
7530 \param - pHddCtx - Pointer to the HDD global context
7531
7532 \return - VOS_STATUS_SUCCESS if successful
7533
7534 --------------------------------------------------------------------------*/
7535static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7536{
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 v_BOOL_t itemIsValid = VOS_FALSE;
7538 VOS_STATUS status;
7539 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7540 v_U8_t macLoop;
7541
7542 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7543 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7544 if(status != VOS_STATUS_SUCCESS)
7545 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007546 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 return VOS_STATUS_E_FAILURE;
7548 }
7549
7550 if (itemIsValid == VOS_TRUE)
7551 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007552 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7554 VOS_MAX_CONCURRENCY_PERSONA);
7555 if(status != VOS_STATUS_SUCCESS)
7556 {
7557 /* Get MAC from NV fail, not update CFG info
7558 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007559 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 return VOS_STATUS_E_FAILURE;
7561 }
7562
7563 /* If first MAC is not valid, treat all others are not valid
7564 * Then all MACs will be got from ini file */
7565 if(vos_is_macaddr_zero(&macFromNV[0]))
7566 {
7567 /* MAC address in NV file is not configured yet */
7568 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7569 return VOS_STATUS_E_INVAL;
7570 }
7571
7572 /* Get MAC address from NV, update CFG info */
7573 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7574 {
7575 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7576 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307577 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007578 /* This MAC is not valid, skip it
7579 * This MAC will be got from ini file */
7580 }
7581 else
7582 {
7583 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7584 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7585 VOS_MAC_ADDR_SIZE);
7586 }
7587 }
7588 }
7589 else
7590 {
7591 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7592 return VOS_STATUS_E_FAILURE;
7593 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007594
Jeff Johnson295189b2012-06-20 16:38:30 -07007595
7596 return VOS_STATUS_SUCCESS;
7597}
7598
7599/**---------------------------------------------------------------------------
7600
7601 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7602
7603 \param - pAdapter - Pointer to the HDD
7604
7605 \return - None
7606
7607 --------------------------------------------------------------------------*/
7608VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7609{
7610 eHalStatus halStatus;
7611 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307612 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007613
Jeff Johnson295189b2012-06-20 16:38:30 -07007614
7615 // Send ready indication to the HDD. This will kick off the MAC
7616 // into a 'running' state and should kick off an initial scan.
7617 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7618 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7619 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307620 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 "code %08d [x%08x]",__func__, halStatus, halStatus );
7622 return VOS_STATUS_E_FAILURE;
7623 }
7624
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307625 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7627 // And RIVA will crash
7628 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7629 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307630 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7631 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7632
7633
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 return VOS_STATUS_SUCCESS;
7635}
7636
Jeff Johnson295189b2012-06-20 16:38:30 -07007637/* wake lock APIs for HDD */
7638void hdd_prevent_suspend(void)
7639{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007640#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007642#else
7643 wcnss_prevent_suspend();
7644#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007645}
7646
7647void hdd_allow_suspend(void)
7648{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007649#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007651#else
7652 wcnss_allow_suspend();
7653#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007654}
7655
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307656void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007657{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007658#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007659 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007660#else
7661 /* Do nothing as there is no API in wcnss for timeout*/
7662#endif
7663}
7664
Jeff Johnson295189b2012-06-20 16:38:30 -07007665/**---------------------------------------------------------------------------
7666
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007667 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7668 information between Host and Riva
7669
7670 This function gets reported version of FW
7671 It also finds the version of Riva headers used to compile the host
7672 It compares the above two and prints a warning if they are different
7673 It gets the SW and HW version string
7674 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7675 indicating the features they support through a bitmap
7676
7677 \param - pHddCtx - Pointer to HDD context
7678
7679 \return - void
7680
7681 --------------------------------------------------------------------------*/
7682
7683void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7684{
7685
7686 tSirVersionType versionCompiled;
7687 tSirVersionType versionReported;
7688 tSirVersionString versionString;
7689 tANI_U8 fwFeatCapsMsgSupported = 0;
7690 VOS_STATUS vstatus;
7691
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007692 memset(&versionCompiled, 0, sizeof(versionCompiled));
7693 memset(&versionReported, 0, sizeof(versionReported));
7694
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007695 /* retrieve and display WCNSS version information */
7696 do {
7697
7698 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7699 &versionCompiled);
7700 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7701 {
7702 hddLog(VOS_TRACE_LEVEL_FATAL,
7703 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007704 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007705 break;
7706 }
7707
7708 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7709 &versionReported);
7710 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7711 {
7712 hddLog(VOS_TRACE_LEVEL_FATAL,
7713 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007714 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007715 break;
7716 }
7717
7718 if ((versionCompiled.major != versionReported.major) ||
7719 (versionCompiled.minor != versionReported.minor) ||
7720 (versionCompiled.version != versionReported.version) ||
7721 (versionCompiled.revision != versionReported.revision))
7722 {
7723 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7724 "Host expected %u.%u.%u.%u\n",
7725 WLAN_MODULE_NAME,
7726 (int)versionReported.major,
7727 (int)versionReported.minor,
7728 (int)versionReported.version,
7729 (int)versionReported.revision,
7730 (int)versionCompiled.major,
7731 (int)versionCompiled.minor,
7732 (int)versionCompiled.version,
7733 (int)versionCompiled.revision);
7734 }
7735 else
7736 {
7737 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7738 WLAN_MODULE_NAME,
7739 (int)versionReported.major,
7740 (int)versionReported.minor,
7741 (int)versionReported.version,
7742 (int)versionReported.revision);
7743 }
7744
7745 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7746 versionString,
7747 sizeof(versionString));
7748 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7749 {
7750 hddLog(VOS_TRACE_LEVEL_FATAL,
7751 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007752 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007753 break;
7754 }
7755
7756 pr_info("%s: WCNSS software version %s\n",
7757 WLAN_MODULE_NAME, versionString);
7758
7759 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7760 versionString,
7761 sizeof(versionString));
7762 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7763 {
7764 hddLog(VOS_TRACE_LEVEL_FATAL,
7765 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007766 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007767 break;
7768 }
7769
7770 pr_info("%s: WCNSS hardware version %s\n",
7771 WLAN_MODULE_NAME, versionString);
7772
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007773 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7774 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007775 send the message only if it the riva is 1.1
7776 minor numbers for different riva branches:
7777 0 -> (1.0)Mainline Build
7778 1 -> (1.1)Mainline Build
7779 2->(1.04) Stability Build
7780 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007781 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007782 ((versionReported.minor>=1) && (versionReported.version>=1)))
7783 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7784 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007785
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007786 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007787 {
7788#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7789 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7790 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7791#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007792 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7793 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7794 {
7795 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7796 }
7797
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007798 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007799 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007800
7801 } while (0);
7802
7803}
7804
7805/**---------------------------------------------------------------------------
7806
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307807 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7808
7809 \param - pHddCtx - Pointer to the hdd context
7810
7811 \return - true if hardware supports 5GHz
7812
7813 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307814boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307815{
7816 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7817 * then hardware support 5Ghz.
7818 */
7819 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7820 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307822 return true;
7823 }
7824 else
7825 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307827 __func__);
7828 return false;
7829 }
7830}
7831
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307832/**---------------------------------------------------------------------------
7833
7834 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7835 generate function
7836
7837 This is generate the random mac address for WLAN interface
7838
7839 \param - pHddCtx - Pointer to HDD context
7840 idx - Start interface index to get auto
7841 generated mac addr.
7842 mac_addr - Mac address
7843
7844 \return - 0 for success, < 0 for failure
7845
7846 --------------------------------------------------------------------------*/
7847
7848static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
7849 int idx, v_MACADDR_t mac_addr)
7850{
7851 int i;
7852 unsigned int serialno;
7853 serialno = wcnss_get_serial_number();
7854
7855 if (0 != serialno)
7856 {
7857 /* MAC address has 3 bytes of OUI so we have a maximum of 3
7858 bytes of the serial number that can be used to generate
7859 the other 3 bytes of the MAC address. Mask off all but
7860 the lower 3 bytes (this will also make sure we don't
7861 overflow in the next step) */
7862 serialno &= 0x00FFFFFF;
7863
7864 /* we need a unique address for each session */
7865 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
7866
7867 /* autogen other Mac addresses */
7868 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7869 {
7870 /* start with the entire default address */
7871 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
7872 /* then replace the lower 3 bytes */
7873 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
7874 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
7875 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
7876
7877 serialno++;
7878 hddLog(VOS_TRACE_LEVEL_ERROR,
7879 "%s: Derived Mac Addr: "
7880 MAC_ADDRESS_STR, __func__,
7881 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
7882 }
7883
7884 }
7885 else
7886 {
7887 hddLog(LOGE, FL("Failed to Get Serial NO"));
7888 return -1;
7889 }
7890 return 0;
7891}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307892
7893/**---------------------------------------------------------------------------
7894
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05307895 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
7896 completed to flush out the scan results
7897
7898 11d scan is done during driver load and is a passive scan on all
7899 channels supported by the device, 11d scans may find some APs on
7900 frequencies which are forbidden to be used in the regulatory domain
7901 the device is operating in. If these APs are notified to the supplicant
7902 it may try to connect to these APs, thus flush out all the scan results
7903 which are present in SME after 11d scan is done.
7904
7905 \return - eHalStatus
7906
7907 --------------------------------------------------------------------------*/
7908static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
7909 tANI_U32 scanId, eCsrScanStatus status)
7910{
7911 ENTER();
7912
7913 sme_ScanFlushResult(halHandle, 0);
7914
7915 EXIT();
7916
7917 return eHAL_STATUS_SUCCESS;
7918}
7919
7920/**---------------------------------------------------------------------------
7921
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 \brief hdd_wlan_startup() - HDD init function
7923
7924 This is the driver startup code executed once a WLAN device has been detected
7925
7926 \param - dev - Pointer to the underlying device
7927
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007928 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07007929
7930 --------------------------------------------------------------------------*/
7931
7932int hdd_wlan_startup(struct device *dev )
7933{
7934 VOS_STATUS status;
7935 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07007936 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007937 hdd_context_t *pHddCtx = NULL;
7938 v_CONTEXT_t pVosContext= NULL;
7939#ifdef WLAN_BTAMP_FEATURE
7940 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
7941 WLANBAP_ConfigType btAmpConfig;
7942 hdd_config_t *pConfig;
7943#endif
7944 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307946 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07007947
7948 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 /*
7950 * cfg80211: wiphy allocation
7951 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307952 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007953
7954 if(wiphy == NULL)
7955 {
7956 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007957 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007958 }
7959
7960 pHddCtx = wiphy_priv(wiphy);
7961
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 //Initialize the adapter context to zeros.
7963 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
7964
Jeff Johnson295189b2012-06-20 16:38:30 -07007965 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 hdd_prevent_suspend();
7967 pHddCtx->isLoadUnloadInProgress = TRUE;
7968
7969 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
7970
7971 /*Get vos context here bcoz vos_open requires it*/
7972 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
7973
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08007974 if(pVosContext == NULL)
7975 {
7976 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
7977 goto err_free_hdd_context;
7978 }
7979
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 //Save the Global VOSS context in adapter context for future.
7981 pHddCtx->pvosContext = pVosContext;
7982
7983 //Save the adapter context in global context for future.
7984 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
7985
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 pHddCtx->parent_dev = dev;
7987
7988 init_completion(&pHddCtx->full_pwr_comp_var);
7989 init_completion(&pHddCtx->standby_comp_var);
7990 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007991 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08007992 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307993 init_completion(&pHddCtx->wiphy_channel_update_event);
Amar Singhala49cbc52013-10-08 18:37:44 -07007994
7995#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07007996 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07007997#else
7998 init_completion(&pHddCtx->driver_crda_req);
7999#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008000
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308001 spin_lock_init(&pHddCtx->schedScan_lock);
8002
Jeff Johnson295189b2012-06-20 16:38:30 -07008003 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8004
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308005#ifdef FEATURE_WLAN_TDLS
8006 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8007 * invoked by other instances also) to protect the concurrent
8008 * access for the Adapters by TDLS module.
8009 */
8010 mutex_init(&pHddCtx->tdls_lock);
8011#endif
8012
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308013 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 // Load all config first as TL config is needed during vos_open
8015 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8016 if(pHddCtx->cfg_ini == NULL)
8017 {
8018 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8019 goto err_free_hdd_context;
8020 }
8021
8022 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8023
8024 // Read and parse the qcom_cfg.ini file
8025 status = hdd_parse_config_ini( pHddCtx );
8026 if ( VOS_STATUS_SUCCESS != status )
8027 {
8028 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8029 __func__, WLAN_INI_FILE);
8030 goto err_config;
8031 }
Arif Hussaind5218912013-12-05 01:10:55 -08008032#ifdef MEMORY_DEBUG
8033 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8034 vos_mem_init();
8035
8036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8037 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8038#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008039
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308040 /* INI has been read, initialise the configuredMcastBcastFilter with
8041 * INI value as this will serve as the default value
8042 */
8043 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8044 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8045 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308046
8047 if (false == hdd_is_5g_supported(pHddCtx))
8048 {
8049 //5Ghz is not supported.
8050 if (1 != pHddCtx->cfg_ini->nBandCapability)
8051 {
8052 hddLog(VOS_TRACE_LEVEL_INFO,
8053 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8054 pHddCtx->cfg_ini->nBandCapability = 1;
8055 }
8056 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308057
8058 /* If SNR Monitoring is enabled, FW has to parse all beacons
8059 * for calcaluting and storing the average SNR, so set Nth beacon
8060 * filter to 1 to enable FW to parse all the beaocons
8061 */
8062 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8063 {
8064 /* The log level is deliberately set to WARN as overriding
8065 * nthBeaconFilter to 1 will increase power cosumption and this
8066 * might just prove helpful to detect the power issue.
8067 */
8068 hddLog(VOS_TRACE_LEVEL_WARN,
8069 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8070 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8071 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308073 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008075 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008077 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8078 {
8079 hddLog(VOS_TRACE_LEVEL_FATAL,
8080 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8081 goto err_config;
8082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008084
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008085 // Update VOS trace levels based upon the cfg.ini
8086 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8087 pHddCtx->cfg_ini->vosTraceEnableBAP);
8088 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8089 pHddCtx->cfg_ini->vosTraceEnableTL);
8090 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8091 pHddCtx->cfg_ini->vosTraceEnableWDI);
8092 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8093 pHddCtx->cfg_ini->vosTraceEnableHDD);
8094 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8095 pHddCtx->cfg_ini->vosTraceEnableSME);
8096 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8097 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308098 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8099 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008100 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8101 pHddCtx->cfg_ini->vosTraceEnableWDA);
8102 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8103 pHddCtx->cfg_ini->vosTraceEnableSYS);
8104 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8105 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008106 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8107 pHddCtx->cfg_ini->vosTraceEnableSAP);
8108 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8109 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008110
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 // Update WDI trace levels based upon the cfg.ini
8112 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8113 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8114 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8115 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8116 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8117 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8118 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8119 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008120
Jeff Johnson88ba7742013-02-27 14:36:02 -08008121 if (VOS_FTM_MODE == hdd_get_conparam())
8122 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8124 {
8125 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8126 goto err_free_hdd_context;
8127 }
8128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
8129 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008131
Jeff Johnson88ba7742013-02-27 14:36:02 -08008132 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8134 {
8135 status = vos_watchdog_open(pVosContext,
8136 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8137
8138 if(!VOS_IS_STATUS_SUCCESS( status ))
8139 {
8140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308141 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 }
8143 }
8144
8145 pHddCtx->isLogpInProgress = FALSE;
8146 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8147
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8149 if(!VOS_IS_STATUS_SUCCESS(status))
8150 {
8151 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 }
8154
Amar Singhala49cbc52013-10-08 18:37:44 -07008155#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008156 /* initialize the NV module. This is required so that
8157 we can initialize the channel information in wiphy
8158 from the NV.bin data. The channel information in
8159 wiphy needs to be initialized before wiphy registration */
8160
8161 status = vos_nv_open();
8162 if (!VOS_IS_STATUS_SUCCESS(status))
8163 {
8164 /* NV module cannot be initialized */
8165 hddLog( VOS_TRACE_LEVEL_FATAL,
8166 "%s: vos_nv_open failed", __func__);
8167 goto err_clkvote;
8168 }
8169
8170 status = vos_init_wiphy_from_nv_bin();
8171 if (!VOS_IS_STATUS_SUCCESS(status))
8172 {
8173 /* NV module cannot be initialized */
8174 hddLog( VOS_TRACE_LEVEL_FATAL,
8175 "%s: vos_init_wiphy failed", __func__);
8176 goto err_vos_nv_close;
8177 }
8178
Amar Singhala49cbc52013-10-08 18:37:44 -07008179#endif
8180
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 status = vos_open( &pVosContext, 0);
8182 if ( !VOS_IS_STATUS_SUCCESS( status ))
8183 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008184 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308185 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008186 }
8187
Jeff Johnson295189b2012-06-20 16:38:30 -07008188 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8189
8190 if ( NULL == pHddCtx->hHal )
8191 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008192 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 goto err_vosclose;
8194 }
8195
Mihir Shetee1093ba2014-01-21 20:13:32 +05308196#ifdef CONFIG_ENABLE_LINUX_REG
8197 /* registration of wiphy dev with cfg80211 */
8198 if (0 > wlan_hdd_cfg80211_register(wiphy))
8199 {
8200 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8201 goto err_vosclose;
8202 }
8203
8204 status = wlan_hdd_init_channels(pHddCtx);
8205 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8206 {
8207 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8208 __func__);
8209 goto err_wiphy_unregister;
8210 }
8211#endif
8212
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008213 status = vos_preStart( pHddCtx->pvosContext );
8214 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8215 {
8216 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308217 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008218 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008219
Arif Hussaineaf68602013-12-30 23:10:44 -08008220 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8221 {
8222 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8224 __func__, enable_dfs_chan_scan);
8225 }
8226 if (0 == enable_11d || 1 == enable_11d)
8227 {
8228 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8229 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8230 __func__, enable_11d);
8231 }
8232
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008233 /* Note that the vos_preStart() sequence triggers the cfg download.
8234 The cfg download must occur before we update the SME config
8235 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 status = hdd_set_sme_config( pHddCtx );
8237
8238 if ( VOS_STATUS_SUCCESS != status )
8239 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008240 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308241 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008242 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008243
8244 //Initialize the WMM module
8245 status = hdd_wmm_init(pHddCtx);
8246 if (!VOS_IS_STATUS_SUCCESS(status))
8247 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008248 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308249 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 }
8251
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 /* In the integrated architecture we update the configuration from
8253 the INI file and from NV before vOSS has been started so that
8254 the final contents are available to send down to the cCPU */
8255
8256 // Apply the cfg.ini to cfg.dat
8257 if (FALSE == hdd_update_config_dat(pHddCtx))
8258 {
8259 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308260 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008261 }
8262
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308263 // Get mac addr from platform driver
8264 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8265
8266 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308268 /* Store the mac addr for first interface */
8269 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8270
8271 hddLog(VOS_TRACE_LEVEL_ERROR,
8272 "%s: WLAN Mac Addr: "
8273 MAC_ADDRESS_STR, __func__,
8274 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8275
8276 /* Here, passing Arg2 as 1 because we do not want to change the
8277 last 3 bytes (means non OUI bytes) of first interface mac
8278 addr.
8279 */
8280 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8281 {
8282 hddLog(VOS_TRACE_LEVEL_ERROR,
8283 "%s: Failed to generate wlan interface mac addr "
8284 "using MAC from ini file ", __func__);
8285 }
8286 }
8287 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8288 {
8289 // Apply the NV to cfg.dat
8290 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008291#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8292 /* There was not a valid set of MAC Addresses in NV. See if the
8293 default addresses were modified by the cfg.ini settings. If so,
8294 we'll use them, but if not, we'll autogenerate a set of MAC
8295 addresses based upon the device serial number */
8296
8297 static const v_MACADDR_t default_address =
8298 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008299
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308300 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8301 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 {
8303 /* cfg.ini has the default address, invoke autogen logic */
8304
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308305 /* Here, passing Arg2 as 0 because we want to change the
8306 last 3 bytes (means non OUI bytes) of all the interfaces
8307 mac addr.
8308 */
8309 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8310 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008311 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308312 hddLog(VOS_TRACE_LEVEL_ERROR,
8313 "%s: Failed to generate wlan interface mac addr "
8314 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8315 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 }
8318 else
8319#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8320 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008321 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008322 "%s: Invalid MAC address in NV, using MAC from ini file "
8323 MAC_ADDRESS_STR, __func__,
8324 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8325 }
8326 }
8327 {
8328 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308329
8330 /* Set the MAC Address Currently this is used by HAL to
8331 * add self sta. Remove this once self sta is added as
8332 * part of session open.
8333 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8335 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8336 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308337
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 if (!HAL_STATUS_SUCCESS( halStatus ))
8339 {
8340 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8341 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308342 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 }
8344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008345
8346 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8347 Note: Firmware image will be read and downloaded inside vos_start API */
8348 status = vos_start( pHddCtx->pvosContext );
8349 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8350 {
8351 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308352 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 }
8354
Leo Chang6cec3e22014-01-21 15:33:49 -08008355#ifdef FEATURE_WLAN_CH_AVOID
8356 /* Plug in avoid channel notification callback
8357 * This should happen before ADD_SELF_STA
8358 * FW will send first IND with ADD_SELF_STA REQ from host */
8359 sme_AddChAvoidCallback(pHddCtx->hHal,
8360 hdd_hostapd_ch_avoid_cb);
8361#endif /* FEATURE_WLAN_CH_AVOID */
8362
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008363 /* Exchange capability info between Host and FW and also get versioning info from FW */
8364 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008365
8366 status = hdd_post_voss_start_config( pHddCtx );
8367 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8368 {
8369 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8370 __func__);
8371 goto err_vosstop;
8372 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008373
8374#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308375 wlan_hdd_cfg80211_update_reg_info( wiphy );
8376
8377 /* registration of wiphy dev with cfg80211 */
8378 if (0 > wlan_hdd_cfg80211_register(wiphy))
8379 {
8380 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8381 goto err_vosstop;
8382 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008383#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008384
Jeff Johnson295189b2012-06-20 16:38:30 -07008385 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8386 {
8387 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8388 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8389 }
8390 else
8391 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8393 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8394 if (pAdapter != NULL)
8395 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308396 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308398 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8399 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8400 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008401
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308402 /* Generate the P2P Device Address. This consists of the device's
8403 * primary MAC address with the locally administered bit set.
8404 */
8405 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008406 }
8407 else
8408 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308409 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8410 if (p2p_dev_addr != NULL)
8411 {
8412 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8413 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8414 }
8415 else
8416 {
8417 hddLog(VOS_TRACE_LEVEL_FATAL,
8418 "%s: Failed to allocate mac_address for p2p_device",
8419 __func__);
8420 goto err_close_adapter;
8421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008423
8424 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8425 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8426 if ( NULL == pP2pAdapter )
8427 {
8428 hddLog(VOS_TRACE_LEVEL_FATAL,
8429 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008430 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008431 goto err_close_adapter;
8432 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
8436 if( pAdapter == NULL )
8437 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8439 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008441
Arif Hussain66559122013-11-21 10:11:40 -08008442 if (country_code)
8443 {
8444 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008445 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008446 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8447#ifndef CONFIG_ENABLE_LINUX_REG
8448 hdd_checkandupdate_phymode(pAdapter, country_code);
8449#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008450 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8451 (void *)(tSmeChangeCountryCallback)
8452 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008453 country_code,
8454 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308455 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008456 if (eHAL_STATUS_SUCCESS == ret)
8457 {
Arif Hussaincb607082013-12-20 11:57:42 -08008458 ret = wait_for_completion_interruptible_timeout(
8459 &pAdapter->change_country_code,
8460 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8461
8462 if (0 >= ret)
8463 {
8464 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8465 "%s: SME while setting country code timed out", __func__);
8466 }
Arif Hussain66559122013-11-21 10:11:40 -08008467 }
8468 else
8469 {
Arif Hussaincb607082013-12-20 11:57:42 -08008470 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8471 "%s: SME Change Country code from module param fail ret=%d",
8472 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008473 }
8474 }
8475
Jeff Johnson295189b2012-06-20 16:38:30 -07008476#ifdef WLAN_BTAMP_FEATURE
8477 vStatus = WLANBAP_Open(pVosContext);
8478 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8479 {
8480 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8481 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008482 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 }
8484
8485 vStatus = BSL_Init(pVosContext);
8486 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8487 {
8488 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8489 "%s: Failed to Init BSL",__func__);
8490 goto err_bap_close;
8491 }
8492 vStatus = WLANBAP_Start(pVosContext);
8493 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8494 {
8495 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8496 "%s: Failed to start TL",__func__);
8497 goto err_bap_close;
8498 }
8499
8500 pConfig = pHddCtx->cfg_ini;
8501 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8502 status = WLANBAP_SetConfig(&btAmpConfig);
8503
8504#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008505
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008506#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8507 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8508 {
8509 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8510 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8511 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8512 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8513 }
8514#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008515#ifdef FEATURE_WLAN_SCAN_PNO
8516 /*SME must send channel update configuration to RIVA*/
8517 sme_UpdateChannelConfig(pHddCtx->hHal);
8518#endif
8519
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308520 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8521
Jeff Johnson295189b2012-06-20 16:38:30 -07008522 /* Register with platform driver as client for Suspend/Resume */
8523 status = hddRegisterPmOps(pHddCtx);
8524 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8525 {
8526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8527#ifdef WLAN_BTAMP_FEATURE
8528 goto err_bap_stop;
8529#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008530 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008531#endif //WLAN_BTAMP_FEATURE
8532 }
8533
Yue Ma0d4891e2013-08-06 17:01:45 -07008534 /* Open debugfs interface */
8535 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8536 {
8537 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8538 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008539 }
8540
Jeff Johnson295189b2012-06-20 16:38:30 -07008541 /* Register TM level change handler function to the platform */
8542 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8543 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8544 {
8545 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8546 goto err_unregister_pmops;
8547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008548
8549 /* register for riva power on lock to platform driver */
8550 if (req_riva_power_on_lock("wlan"))
8551 {
8552 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8553 __func__);
8554 goto err_unregister_pmops;
8555 }
8556
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 // register net device notifier for device change notification
8558 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8559
8560 if(ret < 0)
8561 {
8562 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8563 goto err_free_power_on_lock;
8564 }
8565
8566 //Initialize the nlink service
8567 if(nl_srv_init() != 0)
8568 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308569 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 goto err_reg_netdev;
8571 }
8572
Leo Chang4ce1cc52013-10-21 18:27:15 -07008573#ifdef WLAN_KD_READY_NOTIFIER
8574 pHddCtx->kd_nl_init = 1;
8575#endif /* WLAN_KD_READY_NOTIFIER */
8576
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 //Initialize the BTC service
8578 if(btc_activate_service(pHddCtx) != 0)
8579 {
8580 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8581 goto err_nl_srv;
8582 }
8583
8584#ifdef PTT_SOCK_SVC_ENABLE
8585 //Initialize the PTT service
8586 if(ptt_sock_activate_svc(pHddCtx) != 0)
8587 {
8588 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8589 goto err_nl_srv;
8590 }
8591#endif
8592
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008596 /* Action frame registered in one adapter which will
8597 * applicable to all interfaces
8598 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008599 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008601
8602 mutex_init(&pHddCtx->sap_lock);
8603
8604 pHddCtx->isLoadUnloadInProgress = FALSE;
8605
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008606#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008607#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8608 /* Initialize the wake lcok */
8609 wake_lock_init(&pHddCtx->rx_wake_lock,
8610 WAKE_LOCK_SUSPEND,
8611 "qcom_rx_wakelock");
8612#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008613 /* Initialize the wake lcok */
8614 wake_lock_init(&pHddCtx->sap_wake_lock,
8615 WAKE_LOCK_SUSPEND,
8616 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008617#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008618
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008619 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8620 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008621
8622 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8623 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308624#ifndef CONFIG_ENABLE_LINUX_REG
8625 /*updating wiphy so that regulatory user hints can be processed*/
8626 if (wiphy)
8627 {
8628 regulatory_hint(wiphy, "00");
8629 }
8630#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008631 // Initialize the restart logic
8632 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308633
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008634 //Register the traffic monitor timer now
8635 if ( pHddCtx->cfg_ini->dynSplitscan)
8636 {
8637 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8638 VOS_TIMER_TYPE_SW,
8639 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8640 (void *)pHddCtx);
8641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 goto success;
8643
8644err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008645#ifdef WLAN_KD_READY_NOTIFIER
8646 nl_srv_exit(pHddCtx->ptt_pid);
8647#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008649#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008650err_reg_netdev:
8651 unregister_netdevice_notifier(&hdd_netdev_notifier);
8652
8653err_free_power_on_lock:
8654 free_riva_power_on_lock("wlan");
8655
8656err_unregister_pmops:
8657 hddDevTmUnregisterNotifyCallback(pHddCtx);
8658 hddDeregisterPmOps(pHddCtx);
8659
Yue Ma0d4891e2013-08-06 17:01:45 -07008660 hdd_debugfs_exit(pHddCtx);
8661
Jeff Johnson295189b2012-06-20 16:38:30 -07008662#ifdef WLAN_BTAMP_FEATURE
8663err_bap_stop:
8664 WLANBAP_Stop(pVosContext);
8665#endif
8666
8667#ifdef WLAN_BTAMP_FEATURE
8668err_bap_close:
8669 WLANBAP_Close(pVosContext);
8670#endif
8671
Jeff Johnson295189b2012-06-20 16:38:30 -07008672err_close_adapter:
8673 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008674
8675#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308676 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008678
8679err_vosstop:
8680 vos_stop(pVosContext);
8681
Mihir Shetee1093ba2014-01-21 20:13:32 +05308682err_wiphy_unregister:
8683#ifdef CONFIG_ENABLE_LINUX_REG
8684 wiphy_unregister(wiphy);
8685#endif
8686
Amar Singhala49cbc52013-10-08 18:37:44 -07008687err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 status = vos_sched_close( pVosContext );
8689 if (!VOS_IS_STATUS_SUCCESS(status)) {
8690 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8691 "%s: Failed to close VOSS Scheduler", __func__);
8692 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8693 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008694 vos_close(pVosContext );
8695
Amar Singhala49cbc52013-10-08 18:37:44 -07008696#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008697err_vos_nv_close:
8698
8699 vos_nv_close();
8700
Jeff Johnson295189b2012-06-20 16:38:30 -07008701err_clkvote:
Amar Singhala49cbc52013-10-08 18:37:44 -07008702#endif
8703
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008704 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008705
8706err_wdclose:
8707 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8708 vos_watchdog_close(pVosContext);
8709
Jeff Johnson295189b2012-06-20 16:38:30 -07008710err_config:
8711 kfree(pHddCtx->cfg_ini);
8712 pHddCtx->cfg_ini= NULL;
8713
8714err_free_hdd_context:
8715 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 wiphy_free(wiphy) ;
8717 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 VOS_BUG(1);
8719
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008720 if (hdd_is_ssr_required())
8721 {
8722 /* WDI timeout had happened during load, so SSR is needed here */
8723 subsystem_restart("wcnss");
8724 msleep(5000);
8725 }
8726 hdd_set_ssr_required (VOS_FALSE);
8727
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008728 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008729
8730success:
8731 EXIT();
8732 return 0;
8733}
8734
8735/**---------------------------------------------------------------------------
8736
Jeff Johnson32d95a32012-09-10 13:15:23 -07008737 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008738
Jeff Johnson32d95a32012-09-10 13:15:23 -07008739 This is the driver entry point - called in different timeline depending
8740 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008741
8742 \param - None
8743
8744 \return - 0 for success, non zero for failure
8745
8746 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008747static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008748{
8749 VOS_STATUS status;
8750 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 struct device *dev = NULL;
8752 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008753#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8754 int max_retries = 0;
8755#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008756
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308757#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8758 vos_wconn_trace_init();
8759#endif
8760
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 ENTER();
8762
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008763#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008765#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008766
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308767 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8769 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8770
8771 //Power Up Libra WLAN card first if not already powered up
8772 status = vos_chipPowerUp(NULL,NULL,NULL);
8773 if (!VOS_IS_STATUS_SUCCESS(status))
8774 {
8775 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8776 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308777#ifdef WLAN_OPEN_SOURCE
8778 wake_lock_destroy(&wlan_wake_lock);
8779#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008780 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 }
8782
Jeff Johnson295189b2012-06-20 16:38:30 -07008783#ifdef ANI_BUS_TYPE_PCI
8784
8785 dev = wcnss_wlan_get_device();
8786
8787#endif // ANI_BUS_TYPE_PCI
8788
8789#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008790
8791#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8792 /* wait until WCNSS driver downloads NV */
8793 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8794 msleep(1000);
8795 }
8796 if (max_retries >= 5) {
8797 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308798#ifdef WLAN_OPEN_SOURCE
8799 wake_lock_destroy(&wlan_wake_lock);
8800#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008801 return -ENODEV;
8802 }
8803#endif
8804
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 dev = wcnss_wlan_get_device();
8806#endif // ANI_BUS_TYPE_PLATFORM
8807
8808
8809 do {
8810 if (NULL == dev) {
8811 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8812 ret_status = -1;
8813 break;
8814 }
8815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816#ifdef TIMER_MANAGER
8817 vos_timer_manager_init();
8818#endif
8819
8820 /* Preopen VOSS so that it is ready to start at least SAL */
8821 status = vos_preOpen(&pVosContext);
8822
8823 if (!VOS_IS_STATUS_SUCCESS(status))
8824 {
8825 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8826 ret_status = -1;
8827 break;
8828 }
8829
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008830#ifndef MODULE
8831 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
8832 */
8833 hdd_set_conparam((v_UINT_t)con_mode);
8834#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008835
8836 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008837 if (hdd_wlan_startup(dev))
8838 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008840 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 vos_preClose( &pVosContext );
8842 ret_status = -1;
8843 break;
8844 }
8845
8846 /* Cancel the vote for XO Core ON
8847 * This is done here for safety purposes in case we re-initialize without turning
8848 * it OFF in any error scenario.
8849 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008850 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008852 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07008853 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8854 {
8855 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008856 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 }
8858 } while (0);
8859
8860 if (0 != ret_status)
8861 {
8862 //Assert Deep sleep signal now to put Libra HW in lowest power state
8863 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
8864 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
8865
8866 //Vote off any PMIC voltage supplies
8867 vos_chipPowerDown(NULL, NULL, NULL);
8868#ifdef TIMER_MANAGER
8869 vos_timer_exit();
8870#endif
8871#ifdef MEMORY_DEBUG
8872 vos_mem_exit();
8873#endif
8874
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008875#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008877#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
8879 }
8880 else
8881 {
8882 //Send WLAN UP indication to Nlink Service
8883 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
8884
8885 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 }
8887
8888 EXIT();
8889
8890 return ret_status;
8891}
8892
Jeff Johnson32d95a32012-09-10 13:15:23 -07008893/**---------------------------------------------------------------------------
8894
8895 \brief hdd_module_init() - Init Function
8896
8897 This is the driver entry point (invoked when module is loaded using insmod)
8898
8899 \param - None
8900
8901 \return - 0 for success, non zero for failure
8902
8903 --------------------------------------------------------------------------*/
8904#ifdef MODULE
8905static int __init hdd_module_init ( void)
8906{
8907 return hdd_driver_init();
8908}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008909#else /* #ifdef MODULE */
8910static int __init hdd_module_init ( void)
8911{
8912 /* Driver initialization is delayed to fwpath_changed_handler */
8913 return 0;
8914}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008915#endif /* #ifdef MODULE */
8916
Jeff Johnson295189b2012-06-20 16:38:30 -07008917
8918/**---------------------------------------------------------------------------
8919
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008920 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008921
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008922 This is the driver exit point (invoked when module is unloaded using rmmod
8923 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07008924
8925 \param - None
8926
8927 \return - None
8928
8929 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008930static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008931{
8932 hdd_context_t *pHddCtx = NULL;
8933 v_CONTEXT_t pVosContext = NULL;
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008934 int retry = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008935
8936 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
8937
8938 //Get the global vos context
8939 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8940
8941 if(!pVosContext)
8942 {
8943 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
8944 goto done;
8945 }
8946
8947 //Get the HDD context.
8948 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
8949
8950 if(!pHddCtx)
8951 {
8952 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
8953 }
8954 else
8955 {
Sameer Thalappil14067972014-01-23 14:54:54 -08008956 while (pHddCtx->isLogpInProgress) {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8958 "%s:SSR in Progress; block rmmod for 1 second!!!", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008959 msleep(1000);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008960
8961 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
8962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8963 "%s:SSR never completed, fatal error", __func__);
8964 VOS_BUG(0);
8965 }
8966 }
8967
Jeff Johnson295189b2012-06-20 16:38:30 -07008968
8969 pHddCtx->isLoadUnloadInProgress = TRUE;
8970 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8971
8972 //Do all the cleanup before deregistering the driver
8973 hdd_wlan_exit(pHddCtx);
8974 }
8975
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 vos_preClose( &pVosContext );
8977
8978#ifdef TIMER_MANAGER
8979 vos_timer_exit();
8980#endif
8981#ifdef MEMORY_DEBUG
8982 vos_mem_exit();
8983#endif
8984
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308985#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8986 vos_wconn_trace_exit();
8987#endif
8988
Jeff Johnson295189b2012-06-20 16:38:30 -07008989done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008990#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
8994}
8995
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008996/**---------------------------------------------------------------------------
8997
8998 \brief hdd_module_exit() - Exit function
8999
9000 This is the driver exit point (invoked when module is unloaded using rmmod)
9001
9002 \param - None
9003
9004 \return - None
9005
9006 --------------------------------------------------------------------------*/
9007static void __exit hdd_module_exit(void)
9008{
9009 hdd_driver_exit();
9010}
9011
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009012#ifdef MODULE
9013static int fwpath_changed_handler(const char *kmessage,
9014 struct kernel_param *kp)
9015{
Jeff Johnson76052702013-04-16 13:55:05 -07009016 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009017}
9018
9019static int con_mode_handler(const char *kmessage,
9020 struct kernel_param *kp)
9021{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009022 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009023}
9024#else /* #ifdef MODULE */
9025/**---------------------------------------------------------------------------
9026
Jeff Johnson76052702013-04-16 13:55:05 -07009027 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009028
Jeff Johnson76052702013-04-16 13:55:05 -07009029 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009030 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009031 - invoked when module parameter fwpath is modified from userspace to signal
9032 initializing the WLAN driver or when con_mode is modified from userspace
9033 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009034
9035 \return - 0 for success, non zero for failure
9036
9037 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009038static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009039{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009040 int ret_status;
9041
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009042 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009043 ret_status = hdd_driver_init();
9044 wlan_hdd_inited = ret_status ? 0 : 1;
9045 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009046 }
9047
9048 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009049
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009050 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009051
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009052 ret_status = hdd_driver_init();
9053 wlan_hdd_inited = ret_status ? 0 : 1;
9054 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009055}
9056
Jeff Johnson295189b2012-06-20 16:38:30 -07009057/**---------------------------------------------------------------------------
9058
Jeff Johnson76052702013-04-16 13:55:05 -07009059 \brief fwpath_changed_handler() - Handler Function
9060
9061 Handle changes to the fwpath parameter
9062
9063 \return - 0 for success, non zero for failure
9064
9065 --------------------------------------------------------------------------*/
9066static int fwpath_changed_handler(const char *kmessage,
9067 struct kernel_param *kp)
9068{
9069 int ret;
9070
9071 ret = param_set_copystring(kmessage, kp);
9072 if (0 == ret)
9073 ret = kickstart_driver();
9074 return ret;
9075}
9076
9077/**---------------------------------------------------------------------------
9078
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009079 \brief con_mode_handler() -
9080
9081 Handler function for module param con_mode when it is changed by userspace
9082 Dynamically linked - do nothing
9083 Statically linked - exit and init driver, as in rmmod and insmod
9084
Jeff Johnson76052702013-04-16 13:55:05 -07009085 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009086
Jeff Johnson76052702013-04-16 13:55:05 -07009087 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009088
9089 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009090static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009091{
Jeff Johnson76052702013-04-16 13:55:05 -07009092 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009093
Jeff Johnson76052702013-04-16 13:55:05 -07009094 ret = param_set_int(kmessage, kp);
9095 if (0 == ret)
9096 ret = kickstart_driver();
9097 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009098}
9099#endif /* #ifdef MODULE */
9100
9101/**---------------------------------------------------------------------------
9102
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 \brief hdd_get_conparam() -
9104
9105 This is the driver exit point (invoked when module is unloaded using rmmod)
9106
9107 \param - None
9108
9109 \return - tVOS_CON_MODE
9110
9111 --------------------------------------------------------------------------*/
9112tVOS_CON_MODE hdd_get_conparam ( void )
9113{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009114#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009116#else
9117 return (tVOS_CON_MODE)curr_con_mode;
9118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009119}
9120void hdd_set_conparam ( v_UINT_t newParam )
9121{
9122 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009123#ifndef MODULE
9124 curr_con_mode = con_mode;
9125#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009126}
9127/**---------------------------------------------------------------------------
9128
9129 \brief hdd_softap_sta_deauth() - function
9130
9131 This to take counter measure to handle deauth req from HDD
9132
9133 \param - pAdapter - Pointer to the HDD
9134
9135 \param - enable - boolean value
9136
9137 \return - None
9138
9139 --------------------------------------------------------------------------*/
9140
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009141VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009142{
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009144 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009145
9146 ENTER();
9147
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009148 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9149 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009150
9151 //Ignore request to deauth bcmc station
9152 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009153 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009154
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009155 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009156
9157 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009158 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009159}
9160
9161/**---------------------------------------------------------------------------
9162
9163 \brief hdd_softap_sta_disassoc() - function
9164
9165 This to take counter measure to handle deauth req from HDD
9166
9167 \param - pAdapter - Pointer to the HDD
9168
9169 \param - enable - boolean value
9170
9171 \return - None
9172
9173 --------------------------------------------------------------------------*/
9174
9175void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9176{
9177 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9178
9179 ENTER();
9180
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309181 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009182
9183 //Ignore request to disassoc bcmc station
9184 if( pDestMacAddress[0] & 0x1 )
9185 return;
9186
9187 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9188}
9189
9190void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9191{
9192 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9193
9194 ENTER();
9195
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309196 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009197
9198 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9199}
9200
Jeff Johnson295189b2012-06-20 16:38:30 -07009201/**---------------------------------------------------------------------------
9202 *
9203 * \brief hdd_get__concurrency_mode() -
9204 *
9205 *
9206 * \param - None
9207 *
9208 * \return - CONCURRENCY MODE
9209 *
9210 * --------------------------------------------------------------------------*/
9211tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9212{
9213 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9214 hdd_context_t *pHddCtx;
9215
9216 if (NULL != pVosContext)
9217 {
9218 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9219 if (NULL != pHddCtx)
9220 {
9221 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9222 }
9223 }
9224
9225 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009226 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 return VOS_STA;
9228}
9229
9230/* Decide whether to allow/not the apps power collapse.
9231 * Allow apps power collapse if we are in connected state.
9232 * if not, allow only if we are in IMPS */
9233v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9234{
9235 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009236 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009237 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9239 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9240 hdd_adapter_t *pAdapter = NULL;
9241 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009242 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009243
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9245 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009246
Yathish9f22e662012-12-10 14:21:35 -08009247 concurrent_state = hdd_get_concurrency_mode();
9248
9249#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9250 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9251 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9252 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9253 return TRUE;
9254#endif
9255
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 /*loop through all adapters. TBD fix for Concurrency */
9257 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9258 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9259 {
9260 pAdapter = pAdapterNode->pAdapter;
9261 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9262 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9263 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009264 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009266 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009267 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9268 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009270 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009271 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9272 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 return FALSE;
9274 }
9275 }
9276 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9277 pAdapterNode = pNext;
9278 }
9279 return TRUE;
9280}
9281
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009282/* Decides whether to send suspend notification to Riva
9283 * if any adapter is in BMPS; then it is required */
9284v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9285{
9286 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9287 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9288
9289 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9290 {
9291 return TRUE;
9292 }
9293 return FALSE;
9294}
9295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9297{
9298 switch(mode)
9299 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009300 case VOS_STA_MODE:
9301 case VOS_P2P_CLIENT_MODE:
9302 case VOS_P2P_GO_MODE:
9303 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009304 pHddCtx->concurrency_mode |= (1 << mode);
9305 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 break;
9307 default:
9308 break;
9309
9310 }
9311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9312 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9313}
9314
9315
9316void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9317{
9318 switch(mode)
9319 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009320 case VOS_STA_MODE:
9321 case VOS_P2P_CLIENT_MODE:
9322 case VOS_P2P_GO_MODE:
9323 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 pHddCtx->no_of_sessions[mode]--;
9325 if (!(pHddCtx->no_of_sessions[mode]))
9326 pHddCtx->concurrency_mode &= (~(1 << mode));
9327 break;
9328 default:
9329 break;
9330 }
9331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9332 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9333}
9334
Jeff Johnsone7245742012-09-05 17:12:55 -07009335/**---------------------------------------------------------------------------
9336 *
9337 * \brief wlan_hdd_restart_init
9338 *
9339 * This function initalizes restart timer/flag. An internal function.
9340 *
9341 * \param - pHddCtx
9342 *
9343 * \return - None
9344 *
9345 * --------------------------------------------------------------------------*/
9346
9347static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9348{
9349 /* Initialize */
9350 pHddCtx->hdd_restart_retries = 0;
9351 atomic_set(&pHddCtx->isRestartInProgress, 0);
9352 vos_timer_init(&pHddCtx->hdd_restart_timer,
9353 VOS_TIMER_TYPE_SW,
9354 wlan_hdd_restart_timer_cb,
9355 pHddCtx);
9356}
9357/**---------------------------------------------------------------------------
9358 *
9359 * \brief wlan_hdd_restart_deinit
9360 *
9361 * This function cleans up the resources used. An internal function.
9362 *
9363 * \param - pHddCtx
9364 *
9365 * \return - None
9366 *
9367 * --------------------------------------------------------------------------*/
9368
9369static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9370{
9371
9372 VOS_STATUS vos_status;
9373 /* Block any further calls */
9374 atomic_set(&pHddCtx->isRestartInProgress, 1);
9375 /* Cleanup */
9376 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9377 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309378 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009379 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9380 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309381 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009382
9383}
9384
9385/**---------------------------------------------------------------------------
9386 *
9387 * \brief wlan_hdd_framework_restart
9388 *
9389 * This function uses a cfg80211 API to start a framework initiated WLAN
9390 * driver module unload/load.
9391 *
9392 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9393 *
9394 *
9395 * \param - pHddCtx
9396 *
9397 * \return - VOS_STATUS_SUCCESS: Success
9398 * VOS_STATUS_E_EMPTY: Adapter is Empty
9399 * VOS_STATUS_E_NOMEM: No memory
9400
9401 * --------------------------------------------------------------------------*/
9402
9403static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9404{
9405 VOS_STATUS status = VOS_STATUS_SUCCESS;
9406 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009407 int len = (sizeof (struct ieee80211_mgmt));
9408 struct ieee80211_mgmt *mgmt = NULL;
9409
9410 /* Prepare the DEAUTH managment frame with reason code */
9411 mgmt = kzalloc(len, GFP_KERNEL);
9412 if(mgmt == NULL)
9413 {
9414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9415 "%s: memory allocation failed (%d bytes)", __func__, len);
9416 return VOS_STATUS_E_NOMEM;
9417 }
9418 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009419
9420 /* Iterate over all adapters/devices */
9421 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9422 do
9423 {
9424 if( (status == VOS_STATUS_SUCCESS) &&
9425 pAdapterNode &&
9426 pAdapterNode->pAdapter)
9427 {
9428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9429 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9430 pAdapterNode->pAdapter->dev->name,
9431 pAdapterNode->pAdapter->device_mode,
9432 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009433 /*
9434 * CFG80211 event to restart the driver
9435 *
9436 * 'cfg80211_send_unprot_deauth' sends a
9437 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9438 * of SME(Linux Kernel) state machine.
9439 *
9440 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9441 * the driver.
9442 *
9443 */
9444
9445 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009446 }
9447 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9448 pAdapterNode = pNext;
9449 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9450
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009451
9452 /* Free the allocated management frame */
9453 kfree(mgmt);
9454
Jeff Johnsone7245742012-09-05 17:12:55 -07009455 /* Retry until we unload or reach max count */
9456 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9457 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9458
9459 return status;
9460
9461}
9462/**---------------------------------------------------------------------------
9463 *
9464 * \brief wlan_hdd_restart_timer_cb
9465 *
9466 * Restart timer callback. An internal function.
9467 *
9468 * \param - User data:
9469 *
9470 * \return - None
9471 *
9472 * --------------------------------------------------------------------------*/
9473
9474void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9475{
9476 hdd_context_t *pHddCtx = usrDataForCallback;
9477 wlan_hdd_framework_restart(pHddCtx);
9478 return;
9479
9480}
9481
9482
9483/**---------------------------------------------------------------------------
9484 *
9485 * \brief wlan_hdd_restart_driver
9486 *
9487 * This function sends an event to supplicant to restart the WLAN driver.
9488 *
9489 * This function is called from vos_wlanRestart.
9490 *
9491 * \param - pHddCtx
9492 *
9493 * \return - VOS_STATUS_SUCCESS: Success
9494 * VOS_STATUS_E_EMPTY: Adapter is Empty
9495 * VOS_STATUS_E_ALREADY: Request already in progress
9496
9497 * --------------------------------------------------------------------------*/
9498VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9499{
9500 VOS_STATUS status = VOS_STATUS_SUCCESS;
9501
9502 /* A tight check to make sure reentrancy */
9503 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9504 {
9505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9506 "%s: WLAN restart is already in progress", __func__);
9507
9508 return VOS_STATUS_E_ALREADY;
9509 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009510 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009511#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009512 wcnss_reset_intr();
9513#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009514
Jeff Johnsone7245742012-09-05 17:12:55 -07009515 return status;
9516}
9517
Mihir Shetee1093ba2014-01-21 20:13:32 +05309518/**---------------------------------------------------------------------------
9519 *
9520 * \brief wlan_hdd_init_channels
9521 *
9522 * This function is used to initialize the channel list in CSR
9523 *
9524 * This function is called from hdd_wlan_startup
9525 *
9526 * \param - pHddCtx: HDD context
9527 *
9528 * \return - VOS_STATUS_SUCCESS: Success
9529 * VOS_STATUS_E_FAULT: Failure reported by SME
9530
9531 * --------------------------------------------------------------------------*/
9532static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9533{
9534 eHalStatus status;
9535
9536 status = sme_InitChannels(pHddCtx->hHal);
9537 if (HAL_STATUS_SUCCESS(status))
9538 {
9539 return VOS_STATUS_SUCCESS;
9540 }
9541 else
9542 {
9543 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9544 __func__, status);
9545 return VOS_STATUS_E_FAULT;
9546 }
9547}
9548
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009549/*
9550 * API to find if there is any STA or P2P-Client is connected
9551 */
9552VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9553{
9554 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9555}
Jeff Johnsone7245742012-09-05 17:12:55 -07009556
Jeff Johnson295189b2012-06-20 16:38:30 -07009557//Register the module init/exit functions
9558module_init(hdd_module_init);
9559module_exit(hdd_module_exit);
9560
9561MODULE_LICENSE("Dual BSD/GPL");
9562MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9563MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9564
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009565module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9566 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009567
Jeff Johnson76052702013-04-16 13:55:05 -07009568module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009569 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009570
9571module_param(enable_dfs_chan_scan, int,
9572 S_IRUSR | S_IRGRP | S_IROTH);
9573
9574module_param(enable_11d, int,
9575 S_IRUSR | S_IRGRP | S_IROTH);
9576
9577module_param(country_code, charp,
9578 S_IRUSR | S_IRGRP | S_IROTH);