blob: 5e1a1257e66a5523a6e3050ee9b7ae828c16bcce [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>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053084#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <wlan_hdd_wowl.h>
86#include <wlan_hdd_misc.h>
87#include <wlan_hdd_wext.h>
88#ifdef WLAN_BTAMP_FEATURE
89#include <bap_hdd_main.h>
90#include <bapInternal.h>
91#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053092#include "wlan_hdd_trace.h"
93#include "vos_types.h"
94#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095#include <linux/wireless.h>
96#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053097#include <linux/inetdevice.h>
98#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include "wlan_hdd_cfg80211.h"
100#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700102int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#include "sapApi.h"
104#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700105#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
107#include <soc/qcom/subsystem_restart.h>
108#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include <wlan_hdd_hostapd.h>
112#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "wlan_hdd_dev_pwr.h"
115#ifdef WLAN_BTAMP_FEATURE
116#include "bap_hdd_misc.h"
117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800120#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530121#ifdef FEATURE_WLAN_TDLS
122#include "wlan_hdd_tdls.h"
123#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700124#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
143
144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
155
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700156#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700157static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700159
Jeff Johnsone7245742012-09-05 17:12:55 -0700160/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800161 * spinlock for synchronizing asynchronous request/response
162 * (full description of use in wlan_hdd_main.h)
163 */
164DEFINE_SPINLOCK(hdd_context_lock);
165
166/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700167 * The rate at which the driver sends RESTART event to supplicant
168 * once the function 'vos_wlanRestart()' is called
169 *
170 */
171#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
172#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700173
174/*
175 * Size of Driver command strings from upper layer
176 */
177#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
178#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
179
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800180#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700181#define TID_MIN_VALUE 0
182#define TID_MAX_VALUE 15
183static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
184 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800185static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
186 tCsrEseBeaconReq *pEseBcnReq);
187#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700188
Atul Mittal1d722422014-03-19 11:15:07 +0530189/*
190 * Maximum buffer size used for returning the data back to user space
191 */
192#define WLAN_MAX_BUF_SIZE 1024
193#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700194/*
195 * Driver miracast parameters 0-Disabled
196 * 1-Source, 2-Sink
197 */
198#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
199#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
200
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800201#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700202static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700205static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700206
207//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700208static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
209static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
210static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
211void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800212void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700213
Jeff Johnson295189b2012-06-20 16:38:30 -0700214v_U16_t hdd_select_queue(struct net_device *dev,
215 struct sk_buff *skb);
216
217#ifdef WLAN_FEATURE_PACKET_FILTERING
218static void hdd_set_multicast_list(struct net_device *dev);
219#endif
220
221void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
222
223extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Amar Singhal0a402232013-10-11 20:57:16 -0700224
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800225#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800226void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
227static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700228static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
229 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
230 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700231static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
232 tANI_U8 *pTargetApBssid,
233 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800234#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800237#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700238
Mihir Shetee1093ba2014-01-21 20:13:32 +0530239static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
240
Jeff Johnson295189b2012-06-20 16:38:30 -0700241static int hdd_netdev_notifier_call(struct notifier_block * nb,
242 unsigned long state,
243 void *ndev)
244{
245 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700246 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700247 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700248#ifdef WLAN_BTAMP_FEATURE
249 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700250#endif
251
252 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700253 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700254 (strncmp(dev->name, "p2p", 3)))
255 return NOTIFY_DONE;
256
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700258 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700259
Jeff Johnson27cee452013-03-27 11:10:24 -0700260 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800262 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 VOS_ASSERT(0);
264 return NOTIFY_DONE;
265 }
266
Jeff Johnson27cee452013-03-27 11:10:24 -0700267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
268 if (NULL == pHddCtx)
269 {
270 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
271 VOS_ASSERT(0);
272 return NOTIFY_DONE;
273 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800274 if (pHddCtx->isLogpInProgress)
275 return NOTIFY_DONE;
276
Jeff Johnson27cee452013-03-27 11:10:24 -0700277
278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
279 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
281 switch (state) {
282 case NETDEV_REGISTER:
283 break;
284
285 case NETDEV_UNREGISTER:
286 break;
287
288 case NETDEV_UP:
289 break;
290
291 case NETDEV_DOWN:
292 break;
293
294 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700295 if(TRUE == pAdapter->isLinkUpSvcNeeded)
296 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700297 break;
298
299 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700300 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530302 long result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800303 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530304 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId,
305 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800307 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530309 if (result <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 {
311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530312 "%s: Timeout occurred while waiting for abortscan %ld",
313 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 }
315 }
316 else
317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700319 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 }
321#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 status = WLANBAP_StopAmp();
324 if(VOS_STATUS_SUCCESS != status )
325 {
326 pHddCtx->isAmpAllowed = VOS_TRUE;
327 hddLog(VOS_TRACE_LEVEL_FATAL,
328 "%s: Failed to stop AMP", __func__);
329 }
330 else
331 {
332 //a state m/c implementation in PAL is TBD to avoid this delay
333 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700334 if ( pHddCtx->isAmpAllowed )
335 {
336 WLANBAP_DeregisterFromHCI();
337 pHddCtx->isAmpAllowed = VOS_FALSE;
338 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700339 }
340#endif //WLAN_BTAMP_FEATURE
341 break;
342
343 default:
344 break;
345 }
346
347 return NOTIFY_DONE;
348}
349
350struct notifier_block hdd_netdev_notifier = {
351 .notifier_call = hdd_netdev_notifier_call,
352};
353
354/*---------------------------------------------------------------------------
355 * Function definitions
356 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700357void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
358void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700359//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700360static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700361#ifndef MODULE
362/* current con_mode - used only for statically linked driver
363 * con_mode is changed by userspace to indicate a mode change which will
364 * result in calling the module exit and init functions. The module
365 * exit function will clean up based on the value of con_mode prior to it
366 * being changed by userspace. So curr_con_mode records the current con_mode
367 * for exit when con_mode becomes the next mode for init
368 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700369static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700370#endif
371
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800372/**---------------------------------------------------------------------------
373
374 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
375
376 Called immediately after the cfg.ini is read in order to configure
377 the desired trace levels.
378
379 \param - moduleId - module whose trace level is being configured
380 \param - bitmask - bitmask of log levels to be enabled
381
382 \return - void
383
384 --------------------------------------------------------------------------*/
385static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
386{
387 wpt_tracelevel level;
388
389 /* if the bitmask is the default value, then a bitmask was not
390 specified in cfg.ini, so leave the logging level alone (it
391 will remain at the "compiled in" default value) */
392 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
393 {
394 return;
395 }
396
397 /* a mask was specified. start by disabling all logging */
398 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
399
400 /* now cycle through the bitmask until all "set" bits are serviced */
401 level = VOS_TRACE_LEVEL_FATAL;
402 while (0 != bitmask)
403 {
404 if (bitmask & 1)
405 {
406 vos_trace_setValue(moduleId, level, 1);
407 }
408 level++;
409 bitmask >>= 1;
410 }
411}
412
413
Jeff Johnson295189b2012-06-20 16:38:30 -0700414/**---------------------------------------------------------------------------
415
416 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
417
418 Called immediately after the cfg.ini is read in order to configure
419 the desired trace levels in the WDI.
420
421 \param - moduleId - module whose trace level is being configured
422 \param - bitmask - bitmask of log levels to be enabled
423
424 \return - void
425
426 --------------------------------------------------------------------------*/
427static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
428{
429 wpt_tracelevel level;
430
431 /* if the bitmask is the default value, then a bitmask was not
432 specified in cfg.ini, so leave the logging level alone (it
433 will remain at the "compiled in" default value) */
434 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
435 {
436 return;
437 }
438
439 /* a mask was specified. start by disabling all logging */
440 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
441
442 /* now cycle through the bitmask until all "set" bits are serviced */
443 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
444 while (0 != bitmask)
445 {
446 if (bitmask & 1)
447 {
448 wpalTraceSetLevel(moduleId, level, 1);
449 }
450 level++;
451 bitmask >>= 1;
452 }
453}
Jeff Johnson295189b2012-06-20 16:38:30 -0700454
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530455/*
456 * FUNCTION: wlan_hdd_validate_context
457 * This function is used to check the HDD context
458 */
459int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
460{
461 ENTER();
462
463 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
464 {
465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
466 "%s: HDD context is Null", __func__);
467 return -ENODEV;
468 }
469
470 if (pHddCtx->isLogpInProgress)
471 {
472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
473 "%s: LOGP in Progress. Ignore!!!", __func__);
474 return -EAGAIN;
475 }
476
477 if (pHddCtx->isLoadUnloadInProgress)
478 {
479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
480 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
481 return -EAGAIN;
482 }
483 return 0;
484}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700485#ifdef CONFIG_ENABLE_LINUX_REG
486void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
487{
488 hdd_adapter_t *pAdapter = NULL;
489 hdd_station_ctx_t *pHddStaCtx = NULL;
490 eCsrPhyMode phyMode;
491 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700493 if (NULL == pHddCtx)
494 {
495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
496 "HDD Context is null !!");
497 return ;
498 }
499
500 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
501 if (NULL == pAdapter)
502 {
503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
504 "pAdapter is null !!");
505 return ;
506 }
507
508 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
509 if (NULL == pHddStaCtx)
510 {
511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
512 "pHddStaCtx is null !!");
513 return ;
514 }
515
516 cfg_param = pHddCtx->cfg_ini;
517 if (NULL == cfg_param)
518 {
519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
520 "cfg_params not available !!");
521 return ;
522 }
523
524 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
525
526 if (!pHddCtx->isVHT80Allowed)
527 {
528 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
529 (eCSR_DOT11_MODE_11ac == phyMode) ||
530 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
531 {
532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
533 "Setting phymode to 11n!!");
534 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
535 }
536 }
537 else
538 {
539 /*New country Supports 11ac as well resetting value back from .ini*/
540 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
541 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
542 return ;
543 }
544
545 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
546 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
547 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
548 {
549 VOS_STATUS vosStatus;
550
551 // need to issue a disconnect to CSR.
552 INIT_COMPLETION(pAdapter->disconnect_comp_var);
553 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
554 pAdapter->sessionId,
555 eCSR_DISCONNECT_REASON_UNSPECIFIED );
556
557 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530558 {
559 long ret;
560
561 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700562 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530563 if (0 >= ret)
564 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
565 ret);
566 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700567
568 }
569}
570#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530571void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
572{
573 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
574 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
575 hdd_config_t *cfg_param;
576 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530577 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530578
579 if (NULL == pHddCtx)
580 {
581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
582 "HDD Context is null !!");
583 return ;
584 }
585
586 cfg_param = pHddCtx->cfg_ini;
587
588 if (NULL == cfg_param)
589 {
590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
591 "cfg_params not available !!");
592 return ;
593 }
594
595 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
596
597 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
598 {
599 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
600 (eCSR_DOT11_MODE_11ac == phyMode) ||
601 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
604 "Setting phymode to 11n!!");
605 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
606 }
607 }
608 else
609 {
610 /*New country Supports 11ac as well resetting value back from .ini*/
611 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
612 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
613 return ;
614 }
615
616 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
617 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
618 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
619 {
620 VOS_STATUS vosStatus;
621
622 // need to issue a disconnect to CSR.
623 INIT_COMPLETION(pAdapter->disconnect_comp_var);
624 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
625 pAdapter->sessionId,
626 eCSR_DISCONNECT_REASON_UNSPECIFIED );
627
628 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530629 {
630 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530631 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530632 if (ret <= 0)
633 {
634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
635 "wait on disconnect_comp_var is failed %ld", ret);
636 }
637 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530638
639 }
640}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700641#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700643void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
644{
645 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
646 hdd_config_t *cfg_param;
647
648 if (NULL == pHddCtx)
649 {
650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
651 "HDD Context is null !!");
652 return ;
653 }
654
655 cfg_param = pHddCtx->cfg_ini;
656
657 if (NULL == cfg_param)
658 {
659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
660 "cfg_params not available !!");
661 return ;
662 }
663
664 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
665 {
666 /*New country doesn't support DFS */
667 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
668 }
669 else
670 {
671 /*New country Supports DFS as well resetting value back from .ini*/
672 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
673 }
674
675}
676
Rajeev79dbe4c2013-10-05 11:03:42 +0530677#ifdef FEATURE_WLAN_BATCH_SCAN
678
679/**---------------------------------------------------------------------------
680
681 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
682 input string
683
684 This function extracts assigned integer from string in below format:
685 "STRING=10" : extracts integer 10 from this string
686
687 \param - pInPtr Pointer to input string
688 \param - base Base for string to int conversion(10 for decimal 16 for hex)
689 \param - pOutPtr Pointer to variable in which extracted integer needs to be
690 assigned
691 \param - pLastArg to tell whether it is last arguement in input string or
692 not
693
694 \return - NULL for failure cases
695 pointer to next arguement in input string for success cases
696 --------------------------------------------------------------------------*/
697static tANI_U8 *
698hdd_extract_assigned_int_from_str
699(
700 tANI_U8 *pInPtr,
701 tANI_U8 base,
702 tANI_U32 *pOutPtr,
703 tANI_U8 *pLastArg
704)
705{
706 int tempInt;
707 int v = 0;
708 char buf[32];
709 int val = 0;
710 *pLastArg = FALSE;
711
712 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
713 if (NULL == pInPtr)
714 {
715 return NULL;
716 }
717
718 pInPtr++;
719
720 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
721
722 val = sscanf(pInPtr, "%32s ", buf);
723 if (val < 0 && val > strlen(pInPtr))
724 {
725 return NULL;
726 }
727 pInPtr += val;
728 v = kstrtos32(buf, base, &tempInt);
729 if (v < 0)
730 {
731 return NULL;
732 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800733 if (tempInt < 0)
734 {
735 tempInt = 0;
736 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530737 *pOutPtr = tempInt;
738
739 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
740 if (NULL == pInPtr)
741 {
742 *pLastArg = TRUE;
743 return NULL;
744 }
745 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
746
747 return pInPtr;
748}
749
750/**---------------------------------------------------------------------------
751
752 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
753 input string
754
755 This function extracts assigned character from string in below format:
756 "STRING=A" : extracts char 'A' from this string
757
758 \param - pInPtr Pointer to input string
759 \param - pOutPtr Pointer to variable in which extracted char needs to be
760 assigned
761 \param - pLastArg to tell whether it is last arguement in input string or
762 not
763
764 \return - NULL for failure cases
765 pointer to next arguement in input string for success cases
766 --------------------------------------------------------------------------*/
767static tANI_U8 *
768hdd_extract_assigned_char_from_str
769(
770 tANI_U8 *pInPtr,
771 tANI_U8 *pOutPtr,
772 tANI_U8 *pLastArg
773)
774{
775 *pLastArg = FALSE;
776
777 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
778 if (NULL == pInPtr)
779 {
780 return NULL;
781 }
782
783 pInPtr++;
784
785 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
786
787 *pOutPtr = *pInPtr;
788
789 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
790 if (NULL == pInPtr)
791 {
792 *pLastArg = TRUE;
793 return NULL;
794 }
795 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
796
797 return pInPtr;
798}
799
800
801/**---------------------------------------------------------------------------
802
803 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
804
805 This function parses set batch scan command in below format:
806 WLS_BATCHING_SET <space> followed by below arguements
807 "SCANFREQ=XX" : Optional defaults to 30 sec
808 "MSCAN=XX" : Required number of scans to attempt to batch
809 "BESTN=XX" : Best Network (RSSI) defaults to 16
810 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
811 A. implies only 5 GHz , B. implies only 2.4GHz
812 "RTT=X" : optional defaults to 0
813 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
814 error
815
816 For example input commands:
817 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
818 translated into set batch scan with following parameters:
819 a) Frequence 60 seconds
820 b) Batch 10 scans together
821 c) Best RSSI to be 20
822 d) 5GHz band only
823 e) RTT is equal to 0
824
825 \param - pValue Pointer to input channel list
826 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
827
828 \return - 0 for success non-zero for failure
829
830 --------------------------------------------------------------------------*/
831static int
832hdd_parse_set_batchscan_command
833(
834 tANI_U8 *pValue,
835 tSirSetBatchScanReq *pHddSetBatchScanReq
836)
837{
838 tANI_U8 *inPtr = pValue;
839 tANI_U8 val = 0;
840 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800841 tANI_U32 nScanFreq;
842 tANI_U32 nMscan;
843 tANI_U32 nBestN;
844 tANI_U8 ucRfBand;
845 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800846 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530847
848 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800849 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
850 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
851 nRtt = 0;
852 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530853
854 /*go to space after WLS_BATCHING_SET command*/
855 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
856 /*no argument after the command*/
857 if (NULL == inPtr)
858 {
859 return -EINVAL;
860 }
861
862 /*no space after the command*/
863 else if (SPACE_ASCII_VALUE != *inPtr)
864 {
865 return -EINVAL;
866 }
867
868 /*removing empty spaces*/
869 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
870
871 /*no argument followed by spaces*/
872 if ('\0' == *inPtr)
873 {
874 return -EINVAL;
875 }
876
877 /*check and parse SCANFREQ*/
878 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
879 {
880 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800881 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800882
Rajeev Kumarc933d982013-11-18 20:04:20 -0800883 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800884 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800885 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800886 }
887
Rajeev79dbe4c2013-10-05 11:03:42 +0530888 if ( (NULL == inPtr) || (TRUE == lastArg))
889 {
890 return -EINVAL;
891 }
892 }
893
894 /*check and parse MSCAN*/
895 if ((strncmp(inPtr, "MSCAN", 5) == 0))
896 {
897 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800898 &nMscan, &lastArg);
899
900 if (0 == nMscan)
901 {
902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
903 "invalid MSCAN=%d", nMscan);
904 return -EINVAL;
905 }
906
Rajeev79dbe4c2013-10-05 11:03:42 +0530907 if (TRUE == lastArg)
908 {
909 goto done;
910 }
911 else if (NULL == inPtr)
912 {
913 return -EINVAL;
914 }
915 }
916 else
917 {
918 return -EINVAL;
919 }
920
921 /*check and parse BESTN*/
922 if ((strncmp(inPtr, "BESTN", 5) == 0))
923 {
924 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800925 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800926
Rajeev Kumarc933d982013-11-18 20:04:20 -0800927 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800928 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800929 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800930 }
931
Rajeev79dbe4c2013-10-05 11:03:42 +0530932 if (TRUE == lastArg)
933 {
934 goto done;
935 }
936 else if (NULL == inPtr)
937 {
938 return -EINVAL;
939 }
940 }
941
942 /*check and parse CHANNEL*/
943 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
944 {
945 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800946
Rajeev79dbe4c2013-10-05 11:03:42 +0530947 if (('A' == val) || ('a' == val))
948 {
c_hpothuebf89732014-02-25 13:00:24 +0530949 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530950 }
951 else if (('B' == val) || ('b' == val))
952 {
c_hpothuebf89732014-02-25 13:00:24 +0530953 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530954 }
955 else
956 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800957 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
958 }
959
960 if (TRUE == lastArg)
961 {
962 goto done;
963 }
964 else if (NULL == inPtr)
965 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 return -EINVAL;
967 }
968 }
969
970 /*check and parse RTT*/
971 if ((strncmp(inPtr, "RTT", 3) == 0))
972 {
973 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800974 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530975 if (TRUE == lastArg)
976 {
977 goto done;
978 }
979 if (NULL == inPtr)
980 {
981 return -EINVAL;
982 }
983 }
984
985
986done:
987
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800988 pHddSetBatchScanReq->scanFrequency = nScanFreq;
989 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
990 pHddSetBatchScanReq->bestNetwork = nBestN;
991 pHddSetBatchScanReq->rfBand = ucRfBand;
992 pHddSetBatchScanReq->rtt = nRtt;
993
Rajeev79dbe4c2013-10-05 11:03:42 +0530994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
995 "Received WLS_BATCHING_SET with SCANFREQ=%d "
996 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
997 pHddSetBatchScanReq->scanFrequency,
998 pHddSetBatchScanReq->numberOfScansToBatch,
999 pHddSetBatchScanReq->bestNetwork,
1000 pHddSetBatchScanReq->rfBand,
1001 pHddSetBatchScanReq->rtt);
1002
1003 return 0;
1004}/*End of hdd_parse_set_batchscan_command*/
1005
1006/**---------------------------------------------------------------------------
1007
1008 \brief hdd_set_batch_scan_req_callback () - This function is called after
1009 receiving set batch scan response from FW and it saves set batch scan
1010 response data FW to HDD context and sets the completion event on
1011 which hdd_ioctl is waiting
1012
1013 \param - callbackContext Pointer to HDD adapter
1014 \param - pRsp Pointer to set batch scan response data received from FW
1015
1016 \return - nothing
1017
1018 --------------------------------------------------------------------------*/
1019static void hdd_set_batch_scan_req_callback
1020(
1021 void *callbackContext,
1022 tSirSetBatchScanRsp *pRsp
1023)
1024{
1025 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1026 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1027
1028 /*sanity check*/
1029 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1030 {
1031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1032 "%s: Invalid pAdapter magic", __func__);
1033 VOS_ASSERT(0);
1034 return;
1035 }
1036 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1037
1038 /*save set batch scan response*/
1039 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1040
1041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1042 "Received set batch scan rsp from FW with nScansToBatch=%d",
1043 pHddSetBatchScanRsp->nScansToBatch);
1044
1045 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1046 complete(&pAdapter->hdd_set_batch_scan_req_var);
1047
1048 return;
1049}/*End of hdd_set_batch_scan_req_callback*/
1050
1051
1052/**---------------------------------------------------------------------------
1053
1054 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1055 info in hdd batch scan response queue
1056
1057 \param - pAdapter Pointer to hdd adapter
1058 \param - pAPMetaInfo Pointer to access point meta info
1059 \param - scanId scan ID of batch scan response
1060 \param - isLastAp tells whether AP is last AP in batch scan response or not
1061
1062 \return - nothing
1063
1064 --------------------------------------------------------------------------*/
1065static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1066 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1067{
1068 tHddBatchScanRsp *pHead;
1069 tHddBatchScanRsp *pNode;
1070 tHddBatchScanRsp *pPrev;
1071 tHddBatchScanRsp *pTemp;
1072 tANI_U8 ssidLen;
1073
1074 /*head of hdd batch scan response queue*/
1075 pHead = pAdapter->pBatchScanRsp;
1076
1077 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1078 if (NULL == pNode)
1079 {
1080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1081 "%s: Could not allocate memory", __func__);
1082 VOS_ASSERT(0);
1083 return;
1084 }
1085
1086 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1087 sizeof(pNode->ApInfo.bssid));
1088 ssidLen = strlen(pApMetaInfo->ssid);
1089 if (SIR_MAX_SSID_SIZE < ssidLen)
1090 {
1091 /*invalid scan result*/
1092 vos_mem_free(pNode);
1093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1094 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1095 return;
1096 }
1097 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1098 /*null terminate ssid*/
1099 pNode->ApInfo.ssid[ssidLen] = '\0';
1100 pNode->ApInfo.ch = pApMetaInfo->ch;
1101 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1102 pNode->ApInfo.age = pApMetaInfo->timestamp;
1103 pNode->ApInfo.batchId = scanId;
1104 pNode->ApInfo.isLastAp = isLastAp;
1105
1106 pNode->pNext = NULL;
1107 if (NULL == pHead)
1108 {
1109 pAdapter->pBatchScanRsp = pNode;
1110 }
1111 else
1112 {
1113 pTemp = pHead;
1114 while (NULL != pTemp)
1115 {
1116 pPrev = pTemp;
1117 pTemp = pTemp->pNext;
1118 }
1119 pPrev->pNext = pNode;
1120 }
1121
1122 return;
1123}/*End of hdd_populate_batch_scan_rsp_queue*/
1124
1125/**---------------------------------------------------------------------------
1126
1127 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1128 receiving batch scan response indication from FW. It saves get batch scan
1129 response data in HDD batch scan response queue. This callback sets the
1130 completion event on which hdd_ioctl is waiting only after getting complete
1131 batch scan response data from FW
1132
1133 \param - callbackContext Pointer to HDD adapter
1134 \param - pRsp Pointer to get batch scan response data received from FW
1135
1136 \return - nothing
1137
1138 --------------------------------------------------------------------------*/
1139static void hdd_batch_scan_result_ind_callback
1140(
1141 void *callbackContext,
1142 void *pRsp
1143)
1144{
1145 v_BOOL_t isLastAp;
1146 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001147 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301148 tANI_U32 numberScanList;
1149 tANI_U32 nextScanListOffset;
1150 tANI_U32 nextApMetaInfoOffset;
1151 hdd_adapter_t* pAdapter;
1152 tpSirBatchScanList pScanList;
1153 tpSirBatchScanNetworkInfo pApMetaInfo;
1154 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1155 tSirSetBatchScanReq *pReq;
1156
1157 pAdapter = (hdd_adapter_t *)callbackContext;
1158 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001159 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301160 {
1161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1162 "%s: Invalid pAdapter magic", __func__);
1163 VOS_ASSERT(0);
1164 return;
1165 }
1166
1167 /*initialize locals*/
1168 pReq = &pAdapter->hddSetBatchScanReq;
1169 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1170 isLastAp = FALSE;
1171 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001172 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301173 numberScanList = 0;
1174 nextScanListOffset = 0;
1175 nextApMetaInfoOffset = 0;
1176 pScanList = NULL;
1177 pApMetaInfo = NULL;
1178
1179 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1180 {
1181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1182 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1183 isLastAp = TRUE;
1184 goto done;
1185 }
1186
1187 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1189 "Batch scan rsp: numberScalList %d", numberScanList);
1190
1191 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1192 {
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "%s: numberScanList %d", __func__, numberScanList);
1195 isLastAp = TRUE;
1196 goto done;
1197 }
1198
1199 while (numberScanList)
1200 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001201 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301202 nextScanListOffset);
1203 if (NULL == pScanList)
1204 {
1205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1206 "%s: pScanList is %p", __func__, pScanList);
1207 isLastAp = TRUE;
1208 goto done;
1209 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001210 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001212 "Batch scan rsp: numApMetaInfo %d scanId %d",
1213 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301214
1215 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1216 {
1217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1218 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1219 isLastAp = TRUE;
1220 goto done;
1221 }
1222
Rajeev Kumarce651e42013-10-21 18:57:15 -07001223 /*Initialize next AP meta info offset for next scan list*/
1224 nextApMetaInfoOffset = 0;
1225
Rajeev79dbe4c2013-10-05 11:03:42 +05301226 while (numApMetaInfo)
1227 {
1228 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1229 nextApMetaInfoOffset);
1230 if (NULL == pApMetaInfo)
1231 {
1232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1233 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1234 isLastAp = TRUE;
1235 goto done;
1236 }
1237 /*calculate AP age*/
1238 pApMetaInfo->timestamp =
1239 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1240
1241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001242 "%s: bssId "MAC_ADDRESS_STR
1243 " ch %d rssi %d timestamp %d", __func__,
1244 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1245 pApMetaInfo->ch, pApMetaInfo->rssi,
1246 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301247
1248 /*mark last AP in batch scan response*/
1249 if ((TRUE == pBatchScanRsp->isLastResult) &&
1250 (1 == numberScanList) && (1 == numApMetaInfo))
1251 {
1252 isLastAp = TRUE;
1253 }
1254
1255 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1256 /*store batch scan repsonse in hdd queue*/
1257 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1258 pScanList->scanId, isLastAp);
1259 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1260
1261 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1262 numApMetaInfo--;
1263 }
1264
Rajeev Kumarce651e42013-10-21 18:57:15 -07001265 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1266 + (sizeof(tSirBatchScanNetworkInfo)
1267 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301268 numberScanList--;
1269 }
1270
1271done:
1272
1273 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1274 requested from hdd_ioctl*/
1275 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1276 (TRUE == isLastAp))
1277 {
1278 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1279 complete(&pAdapter->hdd_get_batch_scan_req_var);
1280 }
1281
1282 return;
1283}/*End of hdd_batch_scan_result_ind_callback*/
1284
1285/**---------------------------------------------------------------------------
1286
1287 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1288 response as per batch scan FR request format by putting proper markers
1289
1290 \param - pDest pointer to destination buffer
1291 \param - cur_len current length
1292 \param - tot_len total remaining size which can be written to user space
1293 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1294 \param - pAdapter Pointer to HDD adapter
1295
1296 \return - ret no of characters written
1297
1298 --------------------------------------------------------------------------*/
1299static tANI_U32
1300hdd_format_batch_scan_rsp
1301(
1302 tANI_U8 *pDest,
1303 tANI_U32 cur_len,
1304 tANI_U32 tot_len,
1305 tHddBatchScanRsp *pApMetaInfo,
1306 hdd_adapter_t* pAdapter
1307)
1308{
1309 tANI_U32 ret = 0;
1310 tANI_U32 rem_len = 0;
1311 tANI_U8 temp_len = 0;
1312 tANI_U8 temp_total_len = 0;
1313 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1314 tANI_U8 *pTemp = temp;
1315
1316 /*Batch scan reponse needs to be returned to user space in
1317 following format:
1318 "scancount=X\n" where X is the number of scans in current batch
1319 batch
1320 "trunc\n" optional present if current scan truncated
1321 "bssid=XX:XX:XX:XX:XX:XX\n"
1322 "ssid=XXXX\n"
1323 "freq=X\n" frequency in Mhz
1324 "level=XX\n"
1325 "age=X\n" ms
1326 "dist=X\n" cm (-1 if not available)
1327 "errror=X\n" (-1if not available)
1328 "====\n" (end of ap marker)
1329 "####\n" (end of scan marker)
1330 "----\n" (end of results)*/
1331 /*send scan result in above format to user space based on
1332 available length*/
1333 /*The GET response may have more data than the driver can return in its
1334 buffer. In that case the buffer should be filled to the nearest complete
1335 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1336 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1337 The final buffer should end with "----\n"*/
1338
1339 /*sanity*/
1340 if (cur_len > tot_len)
1341 {
1342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1343 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1344 return 0;
1345 }
1346 else
1347 {
1348 rem_len = (tot_len - cur_len);
1349 }
1350
1351 /*end scan marker*/
1352 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1353 {
1354 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1355 pTemp += temp_len;
1356 temp_total_len += temp_len;
1357 }
1358
1359 /*bssid*/
1360 temp_len = snprintf(pTemp, sizeof(temp),
1361 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1362 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1363 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1364 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1365 pTemp += temp_len;
1366 temp_total_len += temp_len;
1367
1368 /*ssid*/
1369 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1370 pApMetaInfo->ApInfo.ssid);
1371 pTemp += temp_len;
1372 temp_total_len += temp_len;
1373
1374 /*freq*/
1375 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001376 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301377 pTemp += temp_len;
1378 temp_total_len += temp_len;
1379
1380 /*level*/
1381 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1382 pApMetaInfo->ApInfo.rssi);
1383 pTemp += temp_len;
1384 temp_total_len += temp_len;
1385
1386 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001387 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301388 pApMetaInfo->ApInfo.age);
1389 pTemp += temp_len;
1390 temp_total_len += temp_len;
1391
1392 /*dist*/
1393 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*error*/
1398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1399 pTemp += temp_len;
1400 temp_total_len += temp_len;
1401
1402 /*end AP marker*/
1403 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*last AP in batch scan response*/
1408 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1409 {
1410 /*end scan marker*/
1411 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1412 pTemp += temp_len;
1413 temp_total_len += temp_len;
1414
1415 /*end batch scan result marker*/
1416 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1417 pTemp += temp_len;
1418 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001419
Rajeev79dbe4c2013-10-05 11:03:42 +05301420 }
1421
1422 if (temp_total_len < rem_len)
1423 {
1424 ret = temp_total_len + 1;
1425 strlcpy(pDest, temp, ret);
1426 pAdapter->isTruncated = FALSE;
1427 }
1428 else
1429 {
1430 pAdapter->isTruncated = TRUE;
1431 if (rem_len >= strlen("%%%%"))
1432 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001433 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301434 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001435 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301436 {
1437 ret = 0;
1438 }
1439 }
1440
1441 return ret;
1442
1443}/*End of hdd_format_batch_scan_rsp*/
1444
1445/**---------------------------------------------------------------------------
1446
1447 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1448 buffer starting with head of hdd batch scan response queue
1449
1450 \param - pAdapter Pointer to HDD adapter
1451 \param - pDest Pointer to user data buffer
1452 \param - cur_len current offset in user buffer
1453 \param - rem_len remaining no of bytes in user buffer
1454
1455 \return - number of bytes written in user buffer
1456
1457 --------------------------------------------------------------------------*/
1458
1459tANI_U32 hdd_populate_user_batch_scan_rsp
1460(
1461 hdd_adapter_t* pAdapter,
1462 tANI_U8 *pDest,
1463 tANI_U32 cur_len,
1464 tANI_U32 rem_len
1465)
1466{
1467 tHddBatchScanRsp *pHead;
1468 tHddBatchScanRsp *pPrev;
1469 tANI_U32 len;
1470
Rajeev79dbe4c2013-10-05 11:03:42 +05301471 pAdapter->isTruncated = FALSE;
1472
1473 /*head of hdd batch scan response queue*/
1474 pHead = pAdapter->pBatchScanRsp;
1475 while (pHead)
1476 {
1477 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1478 pAdapter);
1479 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001480 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301481 cur_len += len;
1482 if(TRUE == pAdapter->isTruncated)
1483 {
1484 /*result is truncated return rest of scan rsp in next req*/
1485 cur_len = rem_len;
1486 break;
1487 }
1488 pPrev = pHead;
1489 pHead = pHead->pNext;
1490 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001491 if (TRUE == pPrev->ApInfo.isLastAp)
1492 {
1493 pAdapter->prev_batch_id = 0;
1494 }
1495 else
1496 {
1497 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1498 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301499 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001500 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301501 }
1502
1503 return cur_len;
1504}/*End of hdd_populate_user_batch_scan_rsp*/
1505
1506/**---------------------------------------------------------------------------
1507
1508 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1509 scan response data from HDD queue to user space
1510 It does following in detail:
1511 a) if HDD has enough data in its queue then it 1st copies data to user
1512 space and then send get batch scan indication message to FW. In this
1513 case it does not wait on any event and batch scan response data will
1514 be populated in HDD response queue in MC thread context after receiving
1515 indication from FW
1516 b) else send get batch scan indication message to FW and wait on an event
1517 which will be set once HDD receives complete batch scan response from
1518 FW and then this function returns batch scan response to user space
1519
1520 \param - pAdapter Pointer to HDD adapter
1521 \param - pPrivData Pointer to priv_data
1522
1523 \return - 0 for success -EFAULT for failure
1524
1525 --------------------------------------------------------------------------*/
1526
1527int hdd_return_batch_scan_rsp_to_user
1528(
1529 hdd_adapter_t* pAdapter,
1530 hdd_priv_data_t *pPrivData,
1531 tANI_U8 *command
1532)
1533{
1534 tANI_U8 *pDest;
1535 tANI_U32 count = 0;
1536 tANI_U32 len = 0;
1537 tANI_U32 cur_len = 0;
1538 tANI_U32 rem_len = 0;
1539 eHalStatus halStatus;
1540 unsigned long rc;
1541 tSirTriggerBatchScanResultInd *pReq;
1542
1543 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1544 pReq->param = 0;/*batch scan client*/
1545 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1546 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1547
1548 cur_len = pPrivData->used_len;
1549 if (pPrivData->total_len > pPrivData->used_len)
1550 {
1551 rem_len = pPrivData->total_len - pPrivData->used_len;
1552 }
1553 else
1554 {
1555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1556 "%s: Invalid user data buffer total_len %d used_len %d",
1557 __func__, pPrivData->total_len, pPrivData->used_len);
1558 return -EFAULT;
1559 }
1560
1561 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1562 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1563 cur_len, rem_len);
1564 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1565
1566 /*enough scan result available in cache to return to user space or
1567 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001568 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301569 {
1570 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1571 halStatus = sme_TriggerBatchScanResultInd(
1572 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1573 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1574 pAdapter);
1575 if ( eHAL_STATUS_SUCCESS == halStatus )
1576 {
1577 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1578 {
1579 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1580 rc = wait_for_completion_timeout(
1581 &pAdapter->hdd_get_batch_scan_req_var,
1582 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1583 if (0 == rc)
1584 {
1585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1586 "%s: Timeout waiting to fetch batch scan rsp from fw",
1587 __func__);
1588 return -EFAULT;
1589 }
1590 }
1591
1592 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001593 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301594 pDest += len;
1595 cur_len += len;
1596
1597 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1598 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1599 cur_len, rem_len);
1600 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1601
1602 count = 0;
1603 len = (len - pPrivData->used_len);
1604 pDest = (command + pPrivData->used_len);
1605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001606 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301607 while(count < len)
1608 {
1609 printk("%c", *(pDest + count));
1610 count++;
1611 }
1612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1613 "%s: copy %d data to user buffer", __func__, len);
1614 if (copy_to_user(pPrivData->buf, pDest, len))
1615 {
1616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1617 "%s: failed to copy data to user buffer", __func__);
1618 return -EFAULT;
1619 }
1620 }
1621 else
1622 {
1623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1624 "sme_GetBatchScanScan returned failure halStatus %d",
1625 halStatus);
1626 return -EINVAL;
1627 }
1628 }
1629 else
1630 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301631 count = 0;
1632 len = (len - pPrivData->used_len);
1633 pDest = (command + pPrivData->used_len);
1634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001635 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301636 while(count < len)
1637 {
1638 printk("%c", *(pDest + count));
1639 count++;
1640 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1642 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301643 if (copy_to_user(pPrivData->buf, pDest, len))
1644 {
1645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1646 "%s: failed to copy data to user buffer", __func__);
1647 return -EFAULT;
1648 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301649 }
1650
1651 return 0;
1652} /*End of hdd_return_batch_scan_rsp_to_user*/
1653
Rajeev Kumar8b373292014-01-08 20:36:55 -08001654
1655/**---------------------------------------------------------------------------
1656
1657 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1658 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1659 WLS_BATCHING VERSION
1660 WLS_BATCHING SET
1661 WLS_BATCHING GET
1662 WLS_BATCHING STOP
1663
1664 \param - pAdapter Pointer to HDD adapter
1665 \param - pPrivdata Pointer to priv_data
1666 \param - command Pointer to command
1667
1668 \return - 0 for success -EFAULT for failure
1669
1670 --------------------------------------------------------------------------*/
1671
1672int hdd_handle_batch_scan_ioctl
1673(
1674 hdd_adapter_t *pAdapter,
1675 hdd_priv_data_t *pPrivdata,
1676 tANI_U8 *command
1677)
1678{
1679 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001680 hdd_context_t *pHddCtx;
1681
1682 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1683 ret = wlan_hdd_validate_context(pHddCtx);
1684 if (ret)
1685 {
1686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1687 "%s: HDD context is not valid!", __func__);
1688 goto exit;
1689 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001690
1691 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1692 {
1693 char extra[32];
1694 tANI_U8 len = 0;
1695 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1696
1697 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1698 {
1699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1700 "%s: Batch scan feature is not supported by FW", __func__);
1701 ret = -EINVAL;
1702 goto exit;
1703 }
1704
1705 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1706 version);
1707 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1708 {
1709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1710 "%s: failed to copy data to user buffer", __func__);
1711 ret = -EFAULT;
1712 goto exit;
1713 }
1714 ret = HDD_BATCH_SCAN_VERSION;
1715 }
1716 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1717 {
1718 int status;
1719 tANI_U8 *value = (command + 16);
1720 eHalStatus halStatus;
1721 unsigned long rc;
1722 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1723 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1724
1725 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1726 {
1727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1728 "%s: Batch scan feature is not supported by FW", __func__);
1729 ret = -EINVAL;
1730 goto exit;
1731 }
1732
1733 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1734 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1735 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1736 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1737 {
1738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1739 "Received WLS_BATCHING SET command in invalid mode %d "
1740 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
1741 pAdapter->device_mode);
1742 ret = -EINVAL;
1743 goto exit;
1744 }
1745
1746 status = hdd_parse_set_batchscan_command(value, pReq);
1747 if (status)
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1750 "Invalid WLS_BATCHING SET command");
1751 ret = -EINVAL;
1752 goto exit;
1753 }
1754
1755
1756 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1757 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1758 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1759 pAdapter);
1760
1761 if ( eHAL_STATUS_SUCCESS == halStatus )
1762 {
1763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1764 "sme_SetBatchScanReq returned success halStatus %d",
1765 halStatus);
1766 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1767 {
1768 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1769 rc = wait_for_completion_timeout(
1770 &pAdapter->hdd_set_batch_scan_req_var,
1771 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1772 if (0 == rc)
1773 {
1774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1775 "%s: Timeout waiting for set batch scan to complete",
1776 __func__);
1777 ret = -EINVAL;
1778 goto exit;
1779 }
1780 }
1781 if ( !pRsp->nScansToBatch )
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "%s: Received set batch scan failure response from FW",
1785 __func__);
1786 ret = -EINVAL;
1787 goto exit;
1788 }
1789 /*As per the Batch Scan Framework API we should return the MIN of
1790 either MSCAN or the max # of scans firmware can cache*/
1791 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1792
1793 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1794
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 "%s: request MSCAN %d response MSCAN %d ret %d",
1797 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1798 }
1799 else
1800 {
1801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 "sme_SetBatchScanReq returned failure halStatus %d",
1803 halStatus);
1804 ret = -EINVAL;
1805 goto exit;
1806 }
1807 }
1808 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1809 {
1810 eHalStatus halStatus;
1811 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1812 pInd->param = 0;
1813
1814 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1815 {
1816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1817 "%s: Batch scan feature is not supported by FW", __func__);
1818 ret = -EINVAL;
1819 goto exit;
1820 }
1821
1822 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1823 {
1824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1825 "Batch scan is not yet enabled batch scan state %d",
1826 pAdapter->batchScanState);
1827 ret = -EINVAL;
1828 goto exit;
1829 }
1830
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001831 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1832 hdd_deinit_batch_scan(pAdapter);
1833 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1834
Rajeev Kumar8b373292014-01-08 20:36:55 -08001835 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1836
1837 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1838 pAdapter->sessionId);
1839 if ( eHAL_STATUS_SUCCESS == halStatus )
1840 {
1841 ret = 0;
1842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1843 "sme_StopBatchScanInd returned success halStatus %d",
1844 halStatus);
1845 }
1846 else
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "sme_StopBatchScanInd returned failure halStatus %d",
1850 halStatus);
1851 ret = -EINVAL;
1852 goto exit;
1853 }
1854 }
1855 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1856 {
1857 tANI_U32 remain_len;
1858
1859 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1860 {
1861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1862 "%s: Batch scan feature is not supported by FW", __func__);
1863 ret = -EINVAL;
1864 goto exit;
1865 }
1866
1867 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1868 {
1869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1870 "Batch scan is not yet enabled could not return results"
1871 "Batch Scan state %d",
1872 pAdapter->batchScanState);
1873 ret = -EINVAL;
1874 goto exit;
1875 }
1876
1877 pPrivdata->used_len = 16;
1878 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1879 if (remain_len < pPrivdata->total_len)
1880 {
1881 /*Clear previous batch scan response data if any*/
1882 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1883 }
1884 else
1885 {
1886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1887 "Invalid total length from user space can't fetch batch"
1888 " scan response total_len %d used_len %d remain len %d",
1889 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1890 ret = -EINVAL;
1891 goto exit;
1892 }
1893 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1894 }
1895
1896exit:
1897
1898 return ret;
1899}
1900
1901
Rajeev79dbe4c2013-10-05 11:03:42 +05301902#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1903
Jeff Johnson295189b2012-06-20 16:38:30 -07001904int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1905{
1906 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1907 hdd_priv_data_t priv_data;
1908 tANI_U8 *command = NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301909 long ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001910
1911 if (NULL == pAdapter)
1912 {
1913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301914 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 ret = -ENODEV;
1916 goto exit;
1917 }
1918
Jeff Johnsone7245742012-09-05 17:12:55 -07001919 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -07001920 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1922 "%s: invalid data", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 ret = -EINVAL;
1924 goto exit;
1925 }
1926
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001927 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1928 {
1929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1930 "%s:LOGP in Progress. Ignore!!!", __func__);
1931 ret = -EBUSY;
1932 goto exit;
1933 }
1934
Jeff Johnson295189b2012-06-20 16:38:30 -07001935 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
1936 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1938 FL("failed to get data from user buffer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001939 ret = -EFAULT;
1940 goto exit;
1941 }
1942
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08001943 if (priv_data.total_len <= 0 ||
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301944 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001945 {
1946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1947 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1948 priv_data.total_len);
1949 ret = -EINVAL;
1950 goto exit;
1951 }
1952
1953 /* Allocate +1 for '\0' */
1954 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001955 if (!command)
1956 {
1957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301958 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 ret = -ENOMEM;
1960 goto exit;
1961 }
1962
1963 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1964 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1966 FL("failed to get data from user buffer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 ret = -EFAULT;
1968 goto exit;
1969 }
1970
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001971 /* Making sure the command is NUL-terminated */
1972 command[priv_data.total_len] = '\0';
1973
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 if ((SIOCDEVPRIVATE + 1) == cmd)
1975 {
1976 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1977
1978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001979 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001980
1981 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1982 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301983 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1984 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
1985 pAdapter->sessionId, (unsigned)
1986 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
1987 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
1988 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
1989 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1991 sizeof(tSirMacAddr)))
1992 {
1993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001994 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 ret = -EFAULT;
1996 }
1997 }
Amar Singhal0974e402013-02-12 14:27:46 -08001998 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 {
Amar Singhal0974e402013-02-12 14:27:46 -08002000 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002001
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002003
2004 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002007 "%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 -07002008 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002009 ret = hdd_setBand_helper(dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302010 if(ret != 0)
2011 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2012 "%s: failed to set band ret=%ld",__func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002013 }
Kiet Lamf040f472013-11-20 21:15:23 +05302014 else if(strncmp(command, "SETWMMPS", 8) == 0)
2015 {
2016 tANI_U8 *ptr = command;
2017 ret = hdd_wmmps_helper(pAdapter, ptr);
2018 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002019 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2020 {
2021 char *country_code;
2022
2023 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002024
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002025 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002026 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002027#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302028 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002029#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002030 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2031 (void *)(tSmeChangeCountryCallback)
2032 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302033 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002034 if (eHAL_STATUS_SUCCESS == ret)
2035 {
2036 ret = wait_for_completion_interruptible_timeout(
2037 &pAdapter->change_country_code,
2038 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2039 if (0 >= ret)
2040 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %ld",
2042 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002043 }
2044 }
2045 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002046 {
2047 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302048 "%s: SME Change Country code fail ret=%ld", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002049 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002050 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002051
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002052 }
2053 /*
2054 command should be a string having format
2055 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2056 */
Amar Singhal0974e402013-02-12 14:27:46 -08002057 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002058 {
Amar Singhal0974e402013-02-12 14:27:46 -08002059 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002060
2061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002062 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002063
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002064 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002065 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002066 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2067 {
2068 int suspend = 0;
2069 tANI_U8 *ptr = (tANI_U8*)command + 15;
2070
2071 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302072 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2073 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2074 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002075 hdd_set_wlan_suspend_mode(suspend);
2076 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002077#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2078 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2079 {
2080 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002081 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002082 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2083 eHalStatus status = eHAL_STATUS_SUCCESS;
2084
2085 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2086 value = value + 15;
2087
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002088 /* Convert the value from ascii to integer */
2089 ret = kstrtos8(value, 10, &rssi);
2090 if (ret < 0)
2091 {
2092 /* If the input value is greater than max value of datatype, then also
2093 kstrtou8 fails */
2094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2095 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002096 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002097 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2098 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2099 ret = -EINVAL;
2100 goto exit;
2101 }
2102
Srinivas Girigowdade697412013-02-14 16:31:48 -08002103 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002104
Srinivas Girigowdade697412013-02-14 16:31:48 -08002105 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2106 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2107 {
2108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2109 "Neighbor lookup threshold value %d is out of range"
2110 " (Min: %d Max: %d)", lookUpThreshold,
2111 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2112 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2113 ret = -EINVAL;
2114 goto exit;
2115 }
2116
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302117 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2118 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2119 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2121 "%s: Received Command to Set Roam trigger"
2122 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2123
2124 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2125 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2126 if (eHAL_STATUS_SUCCESS != status)
2127 {
2128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2129 "%s: Failed to set roam trigger, try again", __func__);
2130 ret = -EPERM;
2131 goto exit;
2132 }
2133
2134 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2135 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2136 }
2137 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2138 {
2139 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2140 int rssi = (-1) * lookUpThreshold;
2141 char extra[32];
2142 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302143 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2144 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2145 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002146 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002147 if (copy_to_user(priv_data.buf, &extra, len + 1))
2148 {
2149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2150 "%s: failed to copy data to user buffer", __func__);
2151 ret = -EFAULT;
2152 goto exit;
2153 }
2154 }
2155 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2156 {
2157 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002158 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002159 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002160
Srinivas Girigowdade697412013-02-14 16:31:48 -08002161 /* input refresh period is in terms of seconds */
2162 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2163 value = value + 18;
2164 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002165 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002166 if (ret < 0)
2167 {
2168 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002169 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002171 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002172 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002173 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2174 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002175 ret = -EINVAL;
2176 goto exit;
2177 }
2178
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002179 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2180 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002181 {
2182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002183 "Roam scan period value %d is out of range"
2184 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002185 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2186 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002187 ret = -EINVAL;
2188 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302189 }
2190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2191 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2192 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002193 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002194
2195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2196 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002197 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002198
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002199 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2200 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002201 }
2202 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2203 {
2204 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2205 char extra[32];
2206 tANI_U8 len = 0;
2207
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302208 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2209 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2210 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002211 len = scnprintf(extra, sizeof(extra), "%s %d",
2212 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002213 /* Returned value is in units of seconds */
2214 if (copy_to_user(priv_data.buf, &extra, len + 1))
2215 {
2216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2217 "%s: failed to copy data to user buffer", __func__);
2218 ret = -EFAULT;
2219 goto exit;
2220 }
2221 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002222 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2223 {
2224 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002225 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002226 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002227
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002228 /* input refresh period is in terms of seconds */
2229 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2230 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002231
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002232 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002233 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002234 if (ret < 0)
2235 {
2236 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002237 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002239 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002240 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002241 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2242 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2243 ret = -EINVAL;
2244 goto exit;
2245 }
2246
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002247 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2248 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2249 {
2250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2251 "Neighbor scan results refresh period value %d is out of range"
2252 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2253 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2254 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2255 ret = -EINVAL;
2256 goto exit;
2257 }
2258 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2259
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2261 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002262 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002263
2264 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2265 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2266 }
2267 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2268 {
2269 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2270 char extra[32];
2271 tANI_U8 len = 0;
2272
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002273 len = scnprintf(extra, sizeof(extra), "%s %d",
2274 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002275 /* Returned value is in units of seconds */
2276 if (copy_to_user(priv_data.buf, &extra, len + 1))
2277 {
2278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2279 "%s: failed to copy data to user buffer", __func__);
2280 ret = -EFAULT;
2281 goto exit;
2282 }
2283 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002284#ifdef FEATURE_WLAN_LFR
2285 /* SETROAMMODE */
2286 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2287 {
2288 tANI_U8 *value = command;
2289 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2290
2291 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2292 value = value + SIZE_OF_SETROAMMODE + 1;
2293
2294 /* Convert the value from ascii to integer */
2295 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2296 if (ret < 0)
2297 {
2298 /* If the input value is greater than max value of datatype, then also
2299 kstrtou8 fails */
2300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2301 "%s: kstrtou8 failed range [%d - %d]", __func__,
2302 CFG_LFR_FEATURE_ENABLED_MIN,
2303 CFG_LFR_FEATURE_ENABLED_MAX);
2304 ret = -EINVAL;
2305 goto exit;
2306 }
2307 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2308 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2309 {
2310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2311 "Roam Mode value %d is out of range"
2312 " (Min: %d Max: %d)", roamMode,
2313 CFG_LFR_FEATURE_ENABLED_MIN,
2314 CFG_LFR_FEATURE_ENABLED_MAX);
2315 ret = -EINVAL;
2316 goto exit;
2317 }
2318
2319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2320 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2321 /*
2322 * Note that
2323 * SETROAMMODE 0 is to enable LFR while
2324 * SETROAMMODE 1 is to disable LFR, but
2325 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2326 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2327 */
2328 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2329 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2330 else
2331 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2332
2333 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2334 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2335 }
2336 /* GETROAMMODE */
2337 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2338 {
2339 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2340 char extra[32];
2341 tANI_U8 len = 0;
2342
2343 /*
2344 * roamMode value shall be inverted because the sementics is different.
2345 */
2346 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2347 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2348 else
2349 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2350
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002351 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002352 if (copy_to_user(priv_data.buf, &extra, len + 1))
2353 {
2354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2355 "%s: failed to copy data to user buffer", __func__);
2356 ret = -EFAULT;
2357 goto exit;
2358 }
2359 }
2360#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002362#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002363 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2364 {
2365 tANI_U8 *value = command;
2366 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2367
2368 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2369 value = value + 13;
2370 /* Convert the value from ascii to integer */
2371 ret = kstrtou8(value, 10, &roamRssiDiff);
2372 if (ret < 0)
2373 {
2374 /* If the input value is greater than max value of datatype, then also
2375 kstrtou8 fails */
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 "%s: kstrtou8 failed range [%d - %d]", __func__,
2378 CFG_ROAM_RSSI_DIFF_MIN,
2379 CFG_ROAM_RSSI_DIFF_MAX);
2380 ret = -EINVAL;
2381 goto exit;
2382 }
2383
2384 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2385 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2386 {
2387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2388 "Roam rssi diff value %d is out of range"
2389 " (Min: %d Max: %d)", roamRssiDiff,
2390 CFG_ROAM_RSSI_DIFF_MIN,
2391 CFG_ROAM_RSSI_DIFF_MAX);
2392 ret = -EINVAL;
2393 goto exit;
2394 }
2395
2396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2397 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2398
2399 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2400 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2401 }
2402 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2403 {
2404 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2405 char extra[32];
2406 tANI_U8 len = 0;
2407
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302408 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2409 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2410 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002411 len = scnprintf(extra, sizeof(extra), "%s %d",
2412 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002413 if (copy_to_user(priv_data.buf, &extra, len + 1))
2414 {
2415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2416 "%s: failed to copy data to user buffer", __func__);
2417 ret = -EFAULT;
2418 goto exit;
2419 }
2420 }
2421#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002422#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002423 else if (strncmp(command, "GETBAND", 7) == 0)
2424 {
2425 int band = -1;
2426 char extra[32];
2427 tANI_U8 len = 0;
2428 hdd_getBand_helper(pHddCtx, &band);
2429
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2431 TRACE_CODE_HDD_GETBAND_IOCTL,
2432 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002433 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002434 if (copy_to_user(priv_data.buf, &extra, len + 1))
2435 {
2436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2437 "%s: failed to copy data to user buffer", __func__);
2438 ret = -EFAULT;
2439 goto exit;
2440 }
2441 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002442 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2443 {
2444 tANI_U8 *value = command;
2445 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2446 tANI_U8 numChannels = 0;
2447 eHalStatus status = eHAL_STATUS_SUCCESS;
2448
2449 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2450 if (eHAL_STATUS_SUCCESS != status)
2451 {
2452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2453 "%s: Failed to parse channel list information", __func__);
2454 ret = -EINVAL;
2455 goto exit;
2456 }
2457
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2459 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2460 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002461 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2462 {
2463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2464 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2465 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2466 ret = -EINVAL;
2467 goto exit;
2468 }
2469 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2470 numChannels);
2471 if (eHAL_STATUS_SUCCESS != status)
2472 {
2473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2474 "%s: Failed to update channel list information", __func__);
2475 ret = -EINVAL;
2476 goto exit;
2477 }
2478 }
2479 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2480 {
2481 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2482 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002483 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002484 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002485 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002486
2487 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2488 ChannelList, &numChannels ))
2489 {
2490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2491 "%s: failed to get roam scan channel list", __func__);
2492 ret = -EFAULT;
2493 goto exit;
2494 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302495 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2496 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2497 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 /* output channel list is of the format
2499 [Number of roam scan channels][Channel1][Channel2]... */
2500 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002501 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002502 for (j = 0; (j < numChannels); j++)
2503 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002504 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2505 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002506 }
2507
2508 if (copy_to_user(priv_data.buf, &extra, len + 1))
2509 {
2510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2511 "%s: failed to copy data to user buffer", __func__);
2512 ret = -EFAULT;
2513 goto exit;
2514 }
2515 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2517 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002518 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002519 char extra[32];
2520 tANI_U8 len = 0;
2521
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002522 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002523 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002524 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002525 hdd_is_okc_mode_enabled(pHddCtx) &&
2526 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2527 {
2528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002529 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002530 " hence this operation is not permitted!", __func__);
2531 ret = -EPERM;
2532 goto exit;
2533 }
2534
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002535 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002536 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002537 if (copy_to_user(priv_data.buf, &extra, len + 1))
2538 {
2539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2540 "%s: failed to copy data to user buffer", __func__);
2541 ret = -EFAULT;
2542 goto exit;
2543 }
2544 }
2545 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2546 {
2547 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2548 char extra[32];
2549 tANI_U8 len = 0;
2550
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002551 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002552 then this operation is not permitted (return FAILURE) */
2553 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002554 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002555 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2556 {
2557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002558 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002559 " hence this operation is not permitted!", __func__);
2560 ret = -EPERM;
2561 goto exit;
2562 }
2563
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002564 len = scnprintf(extra, sizeof(extra), "%s %d",
2565 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002566 if (copy_to_user(priv_data.buf, &extra, len + 1))
2567 {
2568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2569 "%s: failed to copy data to user buffer", __func__);
2570 ret = -EFAULT;
2571 goto exit;
2572 }
2573 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002574 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002575 {
2576 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2577 char extra[32];
2578 tANI_U8 len = 0;
2579
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002580 len = scnprintf(extra, sizeof(extra), "%s %d",
2581 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002582 if (copy_to_user(priv_data.buf, &extra, len + 1))
2583 {
2584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2585 "%s: failed to copy data to user buffer", __func__);
2586 ret = -EFAULT;
2587 goto exit;
2588 }
2589 }
2590 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2591 {
2592 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2593 char extra[32];
2594 tANI_U8 len = 0;
2595
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002596 len = scnprintf(extra, sizeof(extra), "%s %d",
2597 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002598 if (copy_to_user(priv_data.buf, &extra, len + 1))
2599 {
2600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2601 "%s: failed to copy data to user buffer", __func__);
2602 ret = -EFAULT;
2603 goto exit;
2604 }
2605 }
2606 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2607 {
2608 tANI_U8 *value = command;
2609 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2610
2611 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2612 value = value + 26;
2613 /* Convert the value from ascii to integer */
2614 ret = kstrtou8(value, 10, &minTime);
2615 if (ret < 0)
2616 {
2617 /* If the input value is greater than max value of datatype, then also
2618 kstrtou8 fails */
2619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2620 "%s: kstrtou8 failed range [%d - %d]", __func__,
2621 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2622 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2623 ret = -EINVAL;
2624 goto exit;
2625 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002626 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2627 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2628 {
2629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2630 "scan min channel time value %d is out of range"
2631 " (Min: %d Max: %d)", minTime,
2632 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2633 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2634 ret = -EINVAL;
2635 goto exit;
2636 }
2637
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302638 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2639 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2640 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2642 "%s: Received Command to change channel min time = %d", __func__, minTime);
2643
2644 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2645 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2646 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002647 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2648 {
2649 tANI_U8 *value = command;
2650 tANI_U8 channel = 0;
2651 tANI_U8 dwellTime = 0;
2652 tANI_U8 bufLen = 0;
2653 tANI_U8 *buf = NULL;
2654 tSirMacAddr targetApBssid;
2655 eHalStatus status = eHAL_STATUS_SUCCESS;
2656 struct ieee80211_channel chan;
2657 tANI_U8 finalLen = 0;
2658 tANI_U8 *finalBuf = NULL;
2659 tANI_U8 temp = 0;
2660 u64 cookie;
2661 hdd_station_ctx_t *pHddStaCtx = NULL;
2662 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2663
2664 /* if not associated, no need to send action frame */
2665 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2666 {
2667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2668 ret = -EINVAL;
2669 goto exit;
2670 }
2671
2672 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2673 &dwellTime, &buf, &bufLen);
2674 if (eHAL_STATUS_SUCCESS != status)
2675 {
2676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2677 "%s: Failed to parse send action frame data", __func__);
2678 ret = -EINVAL;
2679 goto exit;
2680 }
2681
2682 /* if the target bssid is different from currently associated AP,
2683 then no need to send action frame */
2684 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2685 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2686 {
2687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2688 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002689 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002690 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002691 goto exit;
2692 }
2693
2694 /* if the channel number is different from operating channel then
2695 no need to send action frame */
2696 if (channel != pHddStaCtx->conn_info.operationChannel)
2697 {
2698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2699 "%s: channel(%d) is different from operating channel(%d)",
2700 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2701 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002702 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002703 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002704 goto exit;
2705 }
2706 chan.center_freq = sme_ChnToFreq(channel);
2707
2708 finalLen = bufLen + 24;
2709 finalBuf = vos_mem_malloc(finalLen);
2710 if (NULL == finalBuf)
2711 {
2712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2713 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002714 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002715 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002716 goto exit;
2717 }
2718 vos_mem_zero(finalBuf, finalLen);
2719
2720 /* Fill subtype */
2721 temp = SIR_MAC_MGMT_ACTION << 4;
2722 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2723
2724 /* Fill type */
2725 temp = SIR_MAC_MGMT_FRAME;
2726 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2727
2728 /* Fill destination address (bssid of the AP) */
2729 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2730
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002731 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002732 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2733
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002734 /* Fill BSSID (AP mac address) */
2735 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002736
2737 /* Fill received buffer from 24th address */
2738 vos_mem_copy(finalBuf + 24, buf, bufLen);
2739
Jeff Johnson11c33152013-04-16 17:52:40 -07002740 /* done with the parsed buffer */
2741 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002742 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002743
DARAM SUDHA39eede62014-02-12 11:16:40 +05302744 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2746 &(pAdapter->wdev),
2747#else
2748 dev,
2749#endif
2750 &chan, 0,
2751#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2752 NL80211_CHAN_HT20, 1,
2753#endif
2754 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002755 1, &cookie );
2756 vos_mem_free(finalBuf);
2757 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002758 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2759 {
2760 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2761 char extra[32];
2762 tANI_U8 len = 0;
2763
2764 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002765 len = scnprintf(extra, sizeof(extra), "%s %d",
2766 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302767 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2768 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2769 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002770 if (copy_to_user(priv_data.buf, &extra, len + 1))
2771 {
2772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "%s: failed to copy data to user buffer", __func__);
2774 ret = -EFAULT;
2775 goto exit;
2776 }
2777 }
2778 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2779 {
2780 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002781 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002782
2783 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2784 value = value + 19;
2785 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002786 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002787 if (ret < 0)
2788 {
2789 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002790 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002792 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002793 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2794 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2795 ret = -EINVAL;
2796 goto exit;
2797 }
2798
2799 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2800 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2801 {
2802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2803 "lfr mode value %d is out of range"
2804 " (Min: %d Max: %d)", maxTime,
2805 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2806 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2807 ret = -EINVAL;
2808 goto exit;
2809 }
2810
2811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2812 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2813
2814 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2815 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2816 }
2817 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2818 {
2819 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2820 char extra[32];
2821 tANI_U8 len = 0;
2822
2823 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002824 len = scnprintf(extra, sizeof(extra), "%s %d",
2825 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002826 if (copy_to_user(priv_data.buf, &extra, len + 1))
2827 {
2828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2829 "%s: failed to copy data to user buffer", __func__);
2830 ret = -EFAULT;
2831 goto exit;
2832 }
2833 }
2834 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2835 {
2836 tANI_U8 *value = command;
2837 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2838
2839 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2840 value = value + 16;
2841 /* Convert the value from ascii to integer */
2842 ret = kstrtou16(value, 10, &val);
2843 if (ret < 0)
2844 {
2845 /* If the input value is greater than max value of datatype, then also
2846 kstrtou16 fails */
2847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2848 "%s: kstrtou16 failed range [%d - %d]", __func__,
2849 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2850 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2851 ret = -EINVAL;
2852 goto exit;
2853 }
2854
2855 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2856 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2857 {
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "scan home time value %d is out of range"
2860 " (Min: %d Max: %d)", val,
2861 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2862 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2863 ret = -EINVAL;
2864 goto exit;
2865 }
2866
2867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2868 "%s: Received Command to change scan home time = %d", __func__, val);
2869
2870 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2871 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2872 }
2873 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2874 {
2875 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2876 char extra[32];
2877 tANI_U8 len = 0;
2878
2879 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002880 len = scnprintf(extra, sizeof(extra), "%s %d",
2881 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002882 if (copy_to_user(priv_data.buf, &extra, len + 1))
2883 {
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "%s: failed to copy data to user buffer", __func__);
2886 ret = -EFAULT;
2887 goto exit;
2888 }
2889 }
2890 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2891 {
2892 tANI_U8 *value = command;
2893 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2894
2895 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2896 value = value + 17;
2897 /* Convert the value from ascii to integer */
2898 ret = kstrtou8(value, 10, &val);
2899 if (ret < 0)
2900 {
2901 /* If the input value is greater than max value of datatype, then also
2902 kstrtou8 fails */
2903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2904 "%s: kstrtou8 failed range [%d - %d]", __func__,
2905 CFG_ROAM_INTRA_BAND_MIN,
2906 CFG_ROAM_INTRA_BAND_MAX);
2907 ret = -EINVAL;
2908 goto exit;
2909 }
2910
2911 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2912 (val > CFG_ROAM_INTRA_BAND_MAX))
2913 {
2914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2915 "intra band mode value %d is out of range"
2916 " (Min: %d Max: %d)", val,
2917 CFG_ROAM_INTRA_BAND_MIN,
2918 CFG_ROAM_INTRA_BAND_MAX);
2919 ret = -EINVAL;
2920 goto exit;
2921 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2923 "%s: Received Command to change intra band = %d", __func__, val);
2924
2925 pHddCtx->cfg_ini->nRoamIntraBand = val;
2926 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2927 }
2928 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2929 {
2930 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2931 char extra[32];
2932 tANI_U8 len = 0;
2933
2934 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002935 len = scnprintf(extra, sizeof(extra), "%s %d",
2936 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002937 if (copy_to_user(priv_data.buf, &extra, len + 1))
2938 {
2939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2940 "%s: failed to copy data to user buffer", __func__);
2941 ret = -EFAULT;
2942 goto exit;
2943 }
2944 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002945 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2946 {
2947 tANI_U8 *value = command;
2948 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2949
2950 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2951 value = value + 15;
2952 /* Convert the value from ascii to integer */
2953 ret = kstrtou8(value, 10, &nProbes);
2954 if (ret < 0)
2955 {
2956 /* If the input value is greater than max value of datatype, then also
2957 kstrtou8 fails */
2958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2959 "%s: kstrtou8 failed range [%d - %d]", __func__,
2960 CFG_ROAM_SCAN_N_PROBES_MIN,
2961 CFG_ROAM_SCAN_N_PROBES_MAX);
2962 ret = -EINVAL;
2963 goto exit;
2964 }
2965
2966 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2967 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2968 {
2969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2970 "NProbes value %d is out of range"
2971 " (Min: %d Max: %d)", nProbes,
2972 CFG_ROAM_SCAN_N_PROBES_MIN,
2973 CFG_ROAM_SCAN_N_PROBES_MAX);
2974 ret = -EINVAL;
2975 goto exit;
2976 }
2977
2978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2979 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2980
2981 pHddCtx->cfg_ini->nProbes = nProbes;
2982 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2983 }
2984 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2985 {
2986 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
2987 char extra[32];
2988 tANI_U8 len = 0;
2989
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002990 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002991 if (copy_to_user(priv_data.buf, &extra, len + 1))
2992 {
2993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2994 "%s: failed to copy data to user buffer", __func__);
2995 ret = -EFAULT;
2996 goto exit;
2997 }
2998 }
2999 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3000 {
3001 tANI_U8 *value = command;
3002 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3003
3004 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3005 /* input value is in units of msec */
3006 value = value + 20;
3007 /* Convert the value from ascii to integer */
3008 ret = kstrtou16(value, 10, &homeAwayTime);
3009 if (ret < 0)
3010 {
3011 /* If the input value is greater than max value of datatype, then also
3012 kstrtou8 fails */
3013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3014 "%s: kstrtou8 failed range [%d - %d]", __func__,
3015 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3016 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3017 ret = -EINVAL;
3018 goto exit;
3019 }
3020
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003021 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3022 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3023 {
3024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3025 "homeAwayTime value %d is out of range"
3026 " (Min: %d Max: %d)", homeAwayTime,
3027 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3028 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3029 ret = -EINVAL;
3030 goto exit;
3031 }
3032
3033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3034 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003035 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3036 {
3037 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3038 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3039 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003040 }
3041 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3042 {
3043 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3044 char extra[32];
3045 tANI_U8 len = 0;
3046
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003047 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003048 if (copy_to_user(priv_data.buf, &extra, len + 1))
3049 {
3050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3051 "%s: failed to copy data to user buffer", __func__);
3052 ret = -EFAULT;
3053 goto exit;
3054 }
3055 }
3056 else if (strncmp(command, "REASSOC", 7) == 0)
3057 {
3058 tANI_U8 *value = command;
3059 tANI_U8 channel = 0;
3060 tSirMacAddr targetApBssid;
3061 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003062#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3063 tCsrHandoffRequest handoffInfo;
3064#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003065 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003066 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3067
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003068 /* if not associated, no need to proceed with reassoc */
3069 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3070 {
3071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3072 ret = -EINVAL;
3073 goto exit;
3074 }
3075
3076 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3077 if (eHAL_STATUS_SUCCESS != status)
3078 {
3079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3080 "%s: Failed to parse reassoc command data", __func__);
3081 ret = -EINVAL;
3082 goto exit;
3083 }
3084
3085 /* if the target bssid is same as currently associated AP,
3086 then no need to proceed with reassoc */
3087 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3088 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3089 {
3090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3091 ret = -EINVAL;
3092 goto exit;
3093 }
3094
3095 /* Check channel number is a valid channel number */
3096 if(VOS_STATUS_SUCCESS !=
3097 wlan_hdd_validate_operation_channel(pAdapter, channel))
3098 {
3099 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003100 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003101 return -EINVAL;
3102 }
3103
3104 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003105#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3106 handoffInfo.channel = channel;
3107 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3108 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3109#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003110 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003111 else if (strncmp(command, "SETWESMODE", 10) == 0)
3112 {
3113 tANI_U8 *value = command;
3114 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3115
3116 /* Move pointer to ahead of SETWESMODE<delimiter> */
3117 value = value + 11;
3118 /* Convert the value from ascii to integer */
3119 ret = kstrtou8(value, 10, &wesMode);
3120 if (ret < 0)
3121 {
3122 /* If the input value is greater than max value of datatype, then also
3123 kstrtou8 fails */
3124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3125 "%s: kstrtou8 failed range [%d - %d]", __func__,
3126 CFG_ENABLE_WES_MODE_NAME_MIN,
3127 CFG_ENABLE_WES_MODE_NAME_MAX);
3128 ret = -EINVAL;
3129 goto exit;
3130 }
3131
3132 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3133 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3134 {
3135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3136 "WES Mode value %d is out of range"
3137 " (Min: %d Max: %d)", wesMode,
3138 CFG_ENABLE_WES_MODE_NAME_MIN,
3139 CFG_ENABLE_WES_MODE_NAME_MAX);
3140 ret = -EINVAL;
3141 goto exit;
3142 }
3143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3144 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3145
3146 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3147 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3148 }
3149 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3150 {
3151 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3152 char extra[32];
3153 tANI_U8 len = 0;
3154
Arif Hussain826d9412013-11-12 16:44:54 -08003155 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003156 if (copy_to_user(priv_data.buf, &extra, len + 1))
3157 {
3158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3159 "%s: failed to copy data to user buffer", __func__);
3160 ret = -EFAULT;
3161 goto exit;
3162 }
3163 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003164#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003165#ifdef FEATURE_WLAN_LFR
3166 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3167 {
3168 tANI_U8 *value = command;
3169 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3170
3171 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3172 value = value + 12;
3173 /* Convert the value from ascii to integer */
3174 ret = kstrtou8(value, 10, &lfrMode);
3175 if (ret < 0)
3176 {
3177 /* If the input value is greater than max value of datatype, then also
3178 kstrtou8 fails */
3179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3180 "%s: kstrtou8 failed range [%d - %d]", __func__,
3181 CFG_LFR_FEATURE_ENABLED_MIN,
3182 CFG_LFR_FEATURE_ENABLED_MAX);
3183 ret = -EINVAL;
3184 goto exit;
3185 }
3186
3187 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3188 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3189 {
3190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3191 "lfr mode value %d is out of range"
3192 " (Min: %d Max: %d)", lfrMode,
3193 CFG_LFR_FEATURE_ENABLED_MIN,
3194 CFG_LFR_FEATURE_ENABLED_MAX);
3195 ret = -EINVAL;
3196 goto exit;
3197 }
3198
3199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3200 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3201
3202 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3203 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3204 }
3205#endif
3206#ifdef WLAN_FEATURE_VOWIFI_11R
3207 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3208 {
3209 tANI_U8 *value = command;
3210 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3211
3212 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3213 value = value + 18;
3214 /* Convert the value from ascii to integer */
3215 ret = kstrtou8(value, 10, &ft);
3216 if (ret < 0)
3217 {
3218 /* If the input value is greater than max value of datatype, then also
3219 kstrtou8 fails */
3220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3221 "%s: kstrtou8 failed range [%d - %d]", __func__,
3222 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3223 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3224 ret = -EINVAL;
3225 goto exit;
3226 }
3227
3228 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3229 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3230 {
3231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3232 "ft mode value %d is out of range"
3233 " (Min: %d Max: %d)", ft,
3234 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3235 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3236 ret = -EINVAL;
3237 goto exit;
3238 }
3239
3240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3241 "%s: Received Command to change ft mode = %d", __func__, ft);
3242
3243 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3244 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3245 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303246
3247 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3248 {
3249 tANI_U8 *value = command;
3250 tSirMacAddr targetApBssid;
3251 tANI_U8 trigger = 0;
3252 eHalStatus status = eHAL_STATUS_SUCCESS;
3253 hdd_station_ctx_t *pHddStaCtx = NULL;
3254 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3255
3256 /* if not associated, no need to proceed with reassoc */
3257 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3258 {
3259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3260 ret = -EINVAL;
3261 goto exit;
3262 }
3263
3264 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3265 if (eHAL_STATUS_SUCCESS != status)
3266 {
3267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3268 "%s: Failed to parse reassoc command data", __func__);
3269 ret = -EINVAL;
3270 goto exit;
3271 }
3272
3273 /* if the target bssid is same as currently associated AP,
3274 then no need to proceed with reassoc */
3275 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3276 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3277 {
3278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3279 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3280 __func__);
3281 ret = -EINVAL;
3282 goto exit;
3283 }
3284
3285 /* Proceed with scan/roam */
3286 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3287 &targetApBssid[0],
3288 (tSmeFastRoamTrigger)(trigger));
3289 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003290#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003291#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003292 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3293 {
3294 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003295 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003296
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003297 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003298 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003299 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003300 hdd_is_okc_mode_enabled(pHddCtx) &&
3301 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003304 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003305 " hence this operation is not permitted!", __func__);
3306 ret = -EPERM;
3307 goto exit;
3308 }
3309
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003310 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3311 value = value + 11;
3312 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003313 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003314 if (ret < 0)
3315 {
3316 /* If the input value is greater than max value of datatype, then also
3317 kstrtou8 fails */
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3319 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003320 CFG_ESE_FEATURE_ENABLED_MIN,
3321 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003322 ret = -EINVAL;
3323 goto exit;
3324 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003325 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3326 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003327 {
3328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003329 "Ese mode value %d is out of range"
3330 " (Min: %d Max: %d)", eseMode,
3331 CFG_ESE_FEATURE_ENABLED_MIN,
3332 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003333 ret = -EINVAL;
3334 goto exit;
3335 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003337 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003338
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003339 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3340 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003341 }
3342#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003343 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3344 {
3345 tANI_U8 *value = command;
3346 tANI_BOOLEAN roamScanControl = 0;
3347
3348 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3349 value = value + 19;
3350 /* Convert the value from ascii to integer */
3351 ret = kstrtou8(value, 10, &roamScanControl);
3352 if (ret < 0)
3353 {
3354 /* If the input value is greater than max value of datatype, then also
3355 kstrtou8 fails */
3356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3357 "%s: kstrtou8 failed ", __func__);
3358 ret = -EINVAL;
3359 goto exit;
3360 }
3361
3362 if (0 != roamScanControl)
3363 {
3364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3365 "roam scan control invalid value = %d",
3366 roamScanControl);
3367 ret = -EINVAL;
3368 goto exit;
3369 }
3370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3371 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3372
3373 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3374 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003375#ifdef FEATURE_WLAN_OKC
3376 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3377 {
3378 tANI_U8 *value = command;
3379 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3380
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003381 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003382 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003383 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003384 hdd_is_okc_mode_enabled(pHddCtx) &&
3385 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3386 {
3387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003388 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003389 " hence this operation is not permitted!", __func__);
3390 ret = -EPERM;
3391 goto exit;
3392 }
3393
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003394 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3395 value = value + 11;
3396 /* Convert the value from ascii to integer */
3397 ret = kstrtou8(value, 10, &okcMode);
3398 if (ret < 0)
3399 {
3400 /* If the input value is greater than max value of datatype, then also
3401 kstrtou8 fails */
3402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3403 "%s: kstrtou8 failed range [%d - %d]", __func__,
3404 CFG_OKC_FEATURE_ENABLED_MIN,
3405 CFG_OKC_FEATURE_ENABLED_MAX);
3406 ret = -EINVAL;
3407 goto exit;
3408 }
3409
3410 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3411 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3412 {
3413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3414 "Okc mode value %d is out of range"
3415 " (Min: %d Max: %d)", okcMode,
3416 CFG_OKC_FEATURE_ENABLED_MIN,
3417 CFG_OKC_FEATURE_ENABLED_MAX);
3418 ret = -EINVAL;
3419 goto exit;
3420 }
3421
3422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3423 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3424
3425 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3426 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003427#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003428 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3429 {
3430 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3431 char extra[32];
3432 tANI_U8 len = 0;
3433
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003434 len = scnprintf(extra, sizeof(extra), "%s %d",
3435 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003436 if (copy_to_user(priv_data.buf, &extra, len + 1))
3437 {
3438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3439 "%s: failed to copy data to user buffer", __func__);
3440 ret = -EFAULT;
3441 goto exit;
3442 }
3443 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303444#ifdef WLAN_FEATURE_PACKET_FILTERING
3445 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3446 {
3447 tANI_U8 filterType = 0;
3448 tANI_U8 *value = command;
3449
3450 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3451 value = value + 22;
3452
3453 /* Convert the value from ascii to integer */
3454 ret = kstrtou8(value, 10, &filterType);
3455 if (ret < 0)
3456 {
3457 /* If the input value is greater than max value of datatype,
3458 * then also kstrtou8 fails
3459 */
3460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3461 "%s: kstrtou8 failed range ", __func__);
3462 ret = -EINVAL;
3463 goto exit;
3464 }
3465
3466 if (filterType != 0 && filterType != 1)
3467 {
3468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3469 "%s: Accepted Values are 0 and 1 ", __func__);
3470 ret = -EINVAL;
3471 goto exit;
3472 }
3473 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3474 pAdapter->sessionId);
3475 }
3476#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303477 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3478 {
3479 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303480 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303481 if ('1' == *dhcpPhase)
3482 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303484 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303485
3486 pHddCtx->btCoexModeSet = TRUE;
3487
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303488 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303489 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303490 }
3491 else if ('2' == *dhcpPhase)
3492 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303494 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303495
3496 pHddCtx->btCoexModeSet = FALSE;
3497
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303498 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303499 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303500 }
3501 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003502 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3503 {
3504 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3505 }
3506 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3507 {
3508 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3509 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303510 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3511 {
3512 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3513 char extra[32];
3514 tANI_U8 len = 0;
3515
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003516 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303517 (int)pCfg->nActiveMaxChnTime);
3518 if (copy_to_user(priv_data.buf, &extra, len + 1))
3519 {
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3521 "%s: failed to copy data to user buffer", __func__);
3522 ret = -EFAULT;
3523 goto exit;
3524 }
3525 ret = len;
3526 }
3527 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3528 {
3529 tANI_U8 *value = command;
3530 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3531 int val = 0, temp;
3532
3533 value = value + 13;
3534 temp = kstrtou32(value, 10, &val);
3535 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3536 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3537 {
3538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3539 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3540 ret = -EFAULT;
3541 goto exit;
3542 }
3543 pCfg->nActiveMaxChnTime = val;
3544 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003545 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3546 {
3547 tANI_U8 filterType = 0;
3548 tANI_U8 *value;
3549 value = command + 9;
3550
3551 /* Convert the value from ascii to integer */
3552 ret = kstrtou8(value, 10, &filterType);
3553 if (ret < 0)
3554 {
3555 /* If the input value is greater than max value of datatype,
3556 * then also kstrtou8 fails
3557 */
3558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3559 "%s: kstrtou8 failed range ", __func__);
3560 ret = -EINVAL;
3561 goto exit;
3562 }
3563 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3564 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3565 {
3566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3567 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3568 " 2-Sink ", __func__);
3569 ret = -EINVAL;
3570 goto exit;
3571 }
3572 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3573 pHddCtx->drvr_miracast = filterType;
3574 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3575 }
Leo Chang614d2072013-08-22 14:59:44 -07003576 else if (strncmp(command, "SETMCRATE", 9) == 0)
3577 {
Leo Chang614d2072013-08-22 14:59:44 -07003578 tANI_U8 *value = command;
3579 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003580 tSirRateUpdateInd *rateUpdate;
3581 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003582
3583 /* Only valid for SAP mode */
3584 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3585 {
3586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3587 "%s: SAP mode is not running", __func__);
3588 ret = -EFAULT;
3589 goto exit;
3590 }
3591
3592 /* Move pointer to ahead of SETMCRATE<delimiter> */
3593 /* input value is in units of hundred kbps */
3594 value = value + 10;
3595 /* Convert the value from ascii to integer, decimal base */
3596 ret = kstrtouint(value, 10, &targetRate);
3597
Leo Chang1f98cbd2013-10-17 15:03:52 -07003598 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3599 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003600 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003601 hddLog(VOS_TRACE_LEVEL_ERROR,
3602 "%s: SETMCRATE indication alloc fail", __func__);
3603 ret = -EFAULT;
3604 goto exit;
3605 }
3606 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3607
3608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3609 "MC Target rate %d", targetRate);
3610 /* Ignore unicast */
3611 rateUpdate->ucastDataRate = -1;
3612 rateUpdate->mcastDataRate24GHz = targetRate;
3613 rateUpdate->mcastDataRate5GHz = targetRate;
3614 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3615 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3616 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3617 if (eHAL_STATUS_SUCCESS != status)
3618 {
3619 hddLog(VOS_TRACE_LEVEL_ERROR,
3620 "%s: SET_MC_RATE failed", __func__);
3621 vos_mem_free(rateUpdate);
3622 ret = -EFAULT;
3623 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003624 }
3625 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303626#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003627 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303628 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003629 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303630 }
3631#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003632#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003633 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3634 {
3635 tANI_U8 *value = command;
3636 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3637 tANI_U8 numChannels = 0;
3638 eHalStatus status = eHAL_STATUS_SUCCESS;
3639
3640 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3641 if (eHAL_STATUS_SUCCESS != status)
3642 {
3643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3644 "%s: Failed to parse channel list information", __func__);
3645 ret = -EINVAL;
3646 goto exit;
3647 }
3648
3649 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3650 {
3651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3652 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3653 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3654 ret = -EINVAL;
3655 goto exit;
3656 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003657 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003658 ChannelList,
3659 numChannels);
3660 if (eHAL_STATUS_SUCCESS != status)
3661 {
3662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3663 "%s: Failed to update channel list information", __func__);
3664 ret = -EINVAL;
3665 goto exit;
3666 }
3667 }
3668 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3669 {
3670 tANI_U8 *value = command;
3671 char extra[128] = {0};
3672 int len = 0;
3673 tANI_U8 tid = 0;
3674 hdd_station_ctx_t *pHddStaCtx = NULL;
3675 tAniTrafStrmMetrics tsmMetrics;
3676 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3677
3678 /* if not associated, return error */
3679 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3680 {
3681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3682 ret = -EINVAL;
3683 goto exit;
3684 }
3685
3686 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3687 value = value + 12;
3688 /* Convert the value from ascii to integer */
3689 ret = kstrtou8(value, 10, &tid);
3690 if (ret < 0)
3691 {
3692 /* If the input value is greater than max value of datatype, then also
3693 kstrtou8 fails */
3694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3695 "%s: kstrtou8 failed range [%d - %d]", __func__,
3696 TID_MIN_VALUE,
3697 TID_MAX_VALUE);
3698 ret = -EINVAL;
3699 goto exit;
3700 }
3701
3702 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3703 {
3704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3705 "tid value %d is out of range"
3706 " (Min: %d Max: %d)", tid,
3707 TID_MIN_VALUE,
3708 TID_MAX_VALUE);
3709 ret = -EINVAL;
3710 goto exit;
3711 }
3712
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3714 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3715
3716 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3717 {
3718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3719 "%s: failed to get tsm stats", __func__);
3720 ret = -EFAULT;
3721 goto exit;
3722 }
3723
3724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3725 "UplinkPktQueueDly(%d)\n"
3726 "UplinkPktQueueDlyHist[0](%d)\n"
3727 "UplinkPktQueueDlyHist[1](%d)\n"
3728 "UplinkPktQueueDlyHist[2](%d)\n"
3729 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303730 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003731 "UplinkPktLoss(%d)\n"
3732 "UplinkPktCount(%d)\n"
3733 "RoamingCount(%d)\n"
3734 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3735 tsmMetrics.UplinkPktQueueDlyHist[0],
3736 tsmMetrics.UplinkPktQueueDlyHist[1],
3737 tsmMetrics.UplinkPktQueueDlyHist[2],
3738 tsmMetrics.UplinkPktQueueDlyHist[3],
3739 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3740 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3741
3742 /* Output TSM stats is of the format
3743 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3744 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003745 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003746 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3747 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3748 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3749 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3750 tsmMetrics.RoamingDly);
3751
3752 if (copy_to_user(priv_data.buf, &extra, len + 1))
3753 {
3754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3755 "%s: failed to copy data to user buffer", __func__);
3756 ret = -EFAULT;
3757 goto exit;
3758 }
3759 }
3760 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3761 {
3762 tANI_U8 *value = command;
3763 tANI_U8 *cckmIe = NULL;
3764 tANI_U8 cckmIeLen = 0;
3765 eHalStatus status = eHAL_STATUS_SUCCESS;
3766
3767 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3768 if (eHAL_STATUS_SUCCESS != status)
3769 {
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3771 "%s: Failed to parse cckm ie data", __func__);
3772 ret = -EINVAL;
3773 goto exit;
3774 }
3775
3776 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3777 {
3778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3779 "%s: CCKM Ie input length is more than max[%d]", __func__,
3780 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003781 vos_mem_free(cckmIe);
3782 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003783 ret = -EINVAL;
3784 goto exit;
3785 }
3786 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003787 vos_mem_free(cckmIe);
3788 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003789 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003790 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3791 {
3792 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003793 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003794 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003795 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003796 if (eHAL_STATUS_SUCCESS != status)
3797 {
3798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003799 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003800 ret = -EINVAL;
3801 goto exit;
3802 }
3803
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003804 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3805 if (eHAL_STATUS_SUCCESS != status)
3806 {
3807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3808 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3809 ret = -EINVAL;
3810 goto exit;
3811 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003812 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003813#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003814 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3816 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3817 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003818 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3819 __func__, command);
3820 }
3821
Jeff Johnson295189b2012-06-20 16:38:30 -07003822 }
3823exit:
3824 if (command)
3825 {
3826 kfree(command);
3827 }
3828 return ret;
3829}
3830
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003831
3832
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003833#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003834/**---------------------------------------------------------------------------
3835
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003836 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003837
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003838 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003839 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3840 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3841 <space>Scan Mode N<space>Meas Duration N
3842 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3843 then take N.
3844 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3845 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3846 This function does not take care of removing duplicate channels from the list
3847
3848 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003849 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003850
3851 \return - 0 for success non-zero for failure
3852
3853 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003854static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
3855 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003856{
3857 tANI_U8 *inPtr = pValue;
3858 int tempInt = 0;
3859 int j = 0, i = 0, v = 0;
3860 char buf[32];
3861
3862 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3863 /*no argument after the command*/
3864 if (NULL == inPtr)
3865 {
3866 return -EINVAL;
3867 }
3868 /*no space after the command*/
3869 else if (SPACE_ASCII_VALUE != *inPtr)
3870 {
3871 return -EINVAL;
3872 }
3873
3874 /*removing empty spaces*/
3875 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3876
3877 /*no argument followed by spaces*/
3878 if ('\0' == *inPtr) return -EINVAL;
3879
3880 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003881 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003882 if (1 != v) return -EINVAL;
3883
3884 v = kstrtos32(buf, 10, &tempInt);
3885 if ( v < 0) return -EINVAL;
3886
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003887 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003888
3889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003890 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003891
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003892 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003893 {
3894 for (i = 0; i < 4; i++)
3895 {
3896 /*inPtr pointing to the beginning of first space after number of ie fields*/
3897 inPtr = strpbrk( inPtr, " " );
3898 /*no ie data after the number of ie fields argument*/
3899 if (NULL == inPtr) return -EINVAL;
3900
3901 /*removing empty space*/
3902 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3903
3904 /*no ie data after the number of ie fields argument and spaces*/
3905 if ( '\0' == *inPtr ) return -EINVAL;
3906
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003907 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003908 if (1 != v) return -EINVAL;
3909
3910 v = kstrtos32(buf, 10, &tempInt);
3911 if (v < 0) return -EINVAL;
3912
3913 switch (i)
3914 {
3915 case 0: /* Measurement token */
3916 if (tempInt <= 0)
3917 {
3918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3919 "Invalid Measurement Token(%d)", tempInt);
3920 return -EINVAL;
3921 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003922 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003923 break;
3924
3925 case 1: /* Channel number */
3926 if ((tempInt <= 0) ||
3927 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
3928 {
3929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3930 "Invalid Channel Number(%d)", tempInt);
3931 return -EINVAL;
3932 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003933 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003934 break;
3935
3936 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003937 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003938 {
3939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3940 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
3941 return -EINVAL;
3942 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003943 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003944 break;
3945
3946 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003947 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
3948 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003949 {
3950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3951 "Invalid Measurement Duration(%d)", tempInt);
3952 return -EINVAL;
3953 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003954 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003955 break;
3956 }
3957 }
3958 }
3959
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003960 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003961 {
3962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303963 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003964 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003965 pEseBcnReq->bcnReq[j].measurementToken,
3966 pEseBcnReq->bcnReq[j].channel,
3967 pEseBcnReq->bcnReq[j].scanMode,
3968 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003969 }
3970
3971 return VOS_STATUS_SUCCESS;
3972}
3973
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003974static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
3975{
3976 struct statsContext *pStatsContext = NULL;
3977 hdd_adapter_t *pAdapter = NULL;
3978
3979 if (NULL == pContext)
3980 {
3981 hddLog(VOS_TRACE_LEVEL_ERROR,
3982 "%s: Bad param, pContext [%p]",
3983 __func__, pContext);
3984 return;
3985 }
3986
Jeff Johnson72a40512013-12-19 10:14:15 -08003987 /* there is a race condition that exists between this callback
3988 function and the caller since the caller could time out either
3989 before or while this code is executing. we use a spinlock to
3990 serialize these actions */
3991 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003992
3993 pStatsContext = pContext;
3994 pAdapter = pStatsContext->pAdapter;
3995 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
3996 {
3997 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08003998 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003999 hddLog(VOS_TRACE_LEVEL_WARN,
4000 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4001 __func__, pAdapter, pStatsContext->magic);
4002 return;
4003 }
4004
Jeff Johnson72a40512013-12-19 10:14:15 -08004005 /* context is valid so caller is still waiting */
4006
4007 /* paranoia: invalidate the magic */
4008 pStatsContext->magic = 0;
4009
4010 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004011 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4012 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4013 tsmMetrics.UplinkPktQueueDlyHist,
4014 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4015 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4016 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4017 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4018 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4019 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4020 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4021
Jeff Johnson72a40512013-12-19 10:14:15 -08004022 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004023 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004024
4025 /* serialization is complete */
4026 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004027}
4028
4029
4030
4031static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4032 tAniTrafStrmMetrics* pTsmMetrics)
4033{
4034 hdd_station_ctx_t *pHddStaCtx = NULL;
4035 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004036 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004037 long lrc;
4038 struct statsContext context;
4039 hdd_context_t *pHddCtx = NULL;
4040
4041 if (NULL == pAdapter)
4042 {
4043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4044 return VOS_STATUS_E_FAULT;
4045 }
4046
4047 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4048 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4049
4050 /* we are connected prepare our callback context */
4051 init_completion(&context.completion);
4052 context.pAdapter = pAdapter;
4053 context.magic = STATS_CONTEXT_MAGIC;
4054
4055 /* query tsm stats */
4056 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4057 pHddStaCtx->conn_info.staId[ 0 ],
4058 pHddStaCtx->conn_info.bssId,
4059 &context, pHddCtx->pvosContext, tid);
4060
4061 if (eHAL_STATUS_SUCCESS != hstatus)
4062 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4064 __func__);
4065 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004066 }
4067 else
4068 {
4069 /* request was sent -- wait for the response */
4070 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4071 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004072 if (lrc <= 0)
4073 {
4074 hddLog(VOS_TRACE_LEVEL_ERROR,
4075 "%s: SME %s while retrieving statistics",
4076 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004077 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004078 }
4079 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004080
Jeff Johnson72a40512013-12-19 10:14:15 -08004081 /* either we never sent a request, we sent a request and received a
4082 response or we sent a request and timed out. if we never sent a
4083 request or if we sent a request and got a response, we want to
4084 clear the magic out of paranoia. if we timed out there is a
4085 race condition such that the callback function could be
4086 executing at the same time we are. of primary concern is if the
4087 callback function had already verified the "magic" but had not
4088 yet set the completion variable when a timeout occurred. we
4089 serialize these activities by invalidating the magic while
4090 holding a shared spinlock which will cause us to block if the
4091 callback is currently executing */
4092 spin_lock(&hdd_context_lock);
4093 context.magic = 0;
4094 spin_unlock(&hdd_context_lock);
4095
4096 if (VOS_STATUS_SUCCESS == vstatus)
4097 {
4098 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4099 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4100 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4101 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4102 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4103 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4104 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4105 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4106 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4107 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4108 }
4109 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004110}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004111#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004112
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004113#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004114void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4115{
4116 eCsrBand band = -1;
4117 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4118 switch (band)
4119 {
4120 case eCSR_BAND_ALL:
4121 *pBand = WLAN_HDD_UI_BAND_AUTO;
4122 break;
4123
4124 case eCSR_BAND_24:
4125 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4126 break;
4127
4128 case eCSR_BAND_5G:
4129 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4130 break;
4131
4132 default:
4133 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4134 *pBand = -1;
4135 break;
4136 }
4137}
4138
4139/**---------------------------------------------------------------------------
4140
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004141 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4142
4143 This function parses the send action frame data passed in the format
4144 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4145
Srinivas Girigowda56076852013-08-20 14:00:50 -07004146 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004147 \param - pTargetApBssid Pointer to target Ap bssid
4148 \param - pChannel Pointer to the Target AP channel
4149 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4150 \param - pBuf Pointer to data
4151 \param - pBufLen Pointer to data length
4152
4153 \return - 0 for success non-zero for failure
4154
4155 --------------------------------------------------------------------------*/
4156VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4157 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4158{
4159 tANI_U8 *inPtr = pValue;
4160 tANI_U8 *dataEnd;
4161 int tempInt;
4162 int j = 0;
4163 int i = 0;
4164 int v = 0;
4165 tANI_U8 tempBuf[32];
4166 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004167 /* 12 hexa decimal digits, 5 ':' and '\0' */
4168 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004169
4170 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4171 /*no argument after the command*/
4172 if (NULL == inPtr)
4173 {
4174 return -EINVAL;
4175 }
4176
4177 /*no space after the command*/
4178 else if (SPACE_ASCII_VALUE != *inPtr)
4179 {
4180 return -EINVAL;
4181 }
4182
4183 /*removing empty spaces*/
4184 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4185
4186 /*no argument followed by spaces*/
4187 if ('\0' == *inPtr)
4188 {
4189 return -EINVAL;
4190 }
4191
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004192 v = sscanf(inPtr, "%17s", macAddress);
4193 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004194 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4196 "Invalid MAC address or All hex inputs are not read (%d)", v);
4197 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004198 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004199
4200 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4201 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4202 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4203 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4204 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4205 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004206
4207 /* point to the next argument */
4208 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4209 /*no argument after the command*/
4210 if (NULL == inPtr) return -EINVAL;
4211
4212 /*removing empty spaces*/
4213 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4214
4215 /*no argument followed by spaces*/
4216 if ('\0' == *inPtr)
4217 {
4218 return -EINVAL;
4219 }
4220
4221 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004222 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004223 if (1 != v) return -EINVAL;
4224
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004225 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashishc0126762014-02-17 19:30:26 +05304226 if ( v < 0 || tempInt < 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304227 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004228
4229 *pChannel = tempInt;
4230
4231 /* point to the next argument */
4232 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4233 /*no argument after the command*/
4234 if (NULL == inPtr) return -EINVAL;
4235 /*removing empty spaces*/
4236 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4237
4238 /*no argument followed by spaces*/
4239 if ('\0' == *inPtr)
4240 {
4241 return -EINVAL;
4242 }
4243
4244 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004245 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004246 if (1 != v) return -EINVAL;
4247
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004248 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004249 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004250
4251 *pDwellTime = tempInt;
4252
4253 /* point to the next argument */
4254 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4255 /*no argument after the command*/
4256 if (NULL == inPtr) return -EINVAL;
4257 /*removing empty spaces*/
4258 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4259
4260 /*no argument followed by spaces*/
4261 if ('\0' == *inPtr)
4262 {
4263 return -EINVAL;
4264 }
4265
4266 /* find the length of data */
4267 dataEnd = inPtr;
4268 while(('\0' != *dataEnd) )
4269 {
4270 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004271 }
Kiet Lambe150c22013-11-21 16:30:32 +05304272 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004273 if ( *pBufLen <= 0) return -EINVAL;
4274
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004275 /* Allocate the number of bytes based on the number of input characters
4276 whether it is even or odd.
4277 if the number of input characters are even, then we need N/2 byte.
4278 if the number of input characters are odd, then we need do (N+1)/2 to
4279 compensate rounding off.
4280 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4281 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4282 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004283 if (NULL == *pBuf)
4284 {
4285 hddLog(VOS_TRACE_LEVEL_FATAL,
4286 "%s: vos_mem_alloc failed ", __func__);
4287 return -EINVAL;
4288 }
4289
4290 /* the buffer received from the upper layer is character buffer,
4291 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4292 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4293 and f0 in 3rd location */
4294 for (i = 0, j = 0; j < *pBufLen; j += 2)
4295 {
Kiet Lambe150c22013-11-21 16:30:32 +05304296 if( j+1 == *pBufLen)
4297 {
4298 tempByte = hdd_parse_hex(inPtr[j]);
4299 }
4300 else
4301 {
4302 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4303 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004304 (*pBuf)[i++] = tempByte;
4305 }
4306 *pBufLen = i;
4307 return VOS_STATUS_SUCCESS;
4308}
4309
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004310/**---------------------------------------------------------------------------
4311
Srinivas Girigowdade697412013-02-14 16:31:48 -08004312 \brief hdd_parse_channellist() - HDD Parse channel list
4313
4314 This function parses the channel list passed in the format
4315 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004316 if the Number of channels (N) does not match with the actual number of channels passed
4317 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4318 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4319 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4320 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004321
4322 \param - pValue Pointer to input channel list
4323 \param - ChannelList Pointer to local output array to record channel list
4324 \param - pNumChannels Pointer to number of roam scan channels
4325
4326 \return - 0 for success non-zero for failure
4327
4328 --------------------------------------------------------------------------*/
4329VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4330{
4331 tANI_U8 *inPtr = pValue;
4332 int tempInt;
4333 int j = 0;
4334 int v = 0;
4335 char buf[32];
4336
4337 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4338 /*no argument after the command*/
4339 if (NULL == inPtr)
4340 {
4341 return -EINVAL;
4342 }
4343
4344 /*no space after the command*/
4345 else if (SPACE_ASCII_VALUE != *inPtr)
4346 {
4347 return -EINVAL;
4348 }
4349
4350 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004351 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004352
4353 /*no argument followed by spaces*/
4354 if ('\0' == *inPtr)
4355 {
4356 return -EINVAL;
4357 }
4358
4359 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004360 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004361 if (1 != v) return -EINVAL;
4362
Srinivas Girigowdade697412013-02-14 16:31:48 -08004363 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004364 if ((v < 0) ||
4365 (tempInt <= 0) ||
4366 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4367 {
4368 return -EINVAL;
4369 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004370
4371 *pNumChannels = tempInt;
4372
4373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4374 "Number of channels are: %d", *pNumChannels);
4375
4376 for (j = 0; j < (*pNumChannels); j++)
4377 {
4378 /*inPtr pointing to the beginning of first space after number of channels*/
4379 inPtr = strpbrk( inPtr, " " );
4380 /*no channel list after the number of channels argument*/
4381 if (NULL == inPtr)
4382 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004383 if (0 != j)
4384 {
4385 *pNumChannels = j;
4386 return VOS_STATUS_SUCCESS;
4387 }
4388 else
4389 {
4390 return -EINVAL;
4391 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004392 }
4393
4394 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004395 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004396
4397 /*no channel list after the number of channels argument and spaces*/
4398 if ( '\0' == *inPtr )
4399 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004400 if (0 != j)
4401 {
4402 *pNumChannels = j;
4403 return VOS_STATUS_SUCCESS;
4404 }
4405 else
4406 {
4407 return -EINVAL;
4408 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004409 }
4410
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004411 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004412 if (1 != v) return -EINVAL;
4413
Srinivas Girigowdade697412013-02-14 16:31:48 -08004414 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004415 if ((v < 0) ||
4416 (tempInt <= 0) ||
4417 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4418 {
4419 return -EINVAL;
4420 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004421 pChannelList[j] = tempInt;
4422
4423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4424 "Channel %d added to preferred channel list",
4425 pChannelList[j] );
4426 }
4427
Srinivas Girigowdade697412013-02-14 16:31:48 -08004428 return VOS_STATUS_SUCCESS;
4429}
4430
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004431
4432/**---------------------------------------------------------------------------
4433
4434 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4435
4436 This function parses the reasoc command data passed in the format
4437 REASSOC<space><bssid><space><channel>
4438
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004439 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004440 \param - pTargetApBssid Pointer to target Ap bssid
4441 \param - pChannel Pointer to the Target AP channel
4442
4443 \return - 0 for success non-zero for failure
4444
4445 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004446VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4447 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004448{
4449 tANI_U8 *inPtr = pValue;
4450 int tempInt;
4451 int v = 0;
4452 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004453 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004454 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004455
4456 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4457 /*no argument after the command*/
4458 if (NULL == inPtr)
4459 {
4460 return -EINVAL;
4461 }
4462
4463 /*no space after the command*/
4464 else if (SPACE_ASCII_VALUE != *inPtr)
4465 {
4466 return -EINVAL;
4467 }
4468
4469 /*removing empty spaces*/
4470 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4471
4472 /*no argument followed by spaces*/
4473 if ('\0' == *inPtr)
4474 {
4475 return -EINVAL;
4476 }
4477
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004478 v = sscanf(inPtr, "%17s", macAddress);
4479 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004480 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4482 "Invalid MAC address or All hex inputs are not read (%d)", v);
4483 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004484 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004485
4486 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4487 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4488 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4489 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4490 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4491 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004492
4493 /* point to the next argument */
4494 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4495 /*no argument after the command*/
4496 if (NULL == inPtr) return -EINVAL;
4497
4498 /*removing empty spaces*/
4499 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4500
4501 /*no argument followed by spaces*/
4502 if ('\0' == *inPtr)
4503 {
4504 return -EINVAL;
4505 }
4506
4507 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004508 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004509 if (1 != v) return -EINVAL;
4510
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004511 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004512 if ((v < 0) ||
4513 (tempInt <= 0) ||
4514 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4515 {
4516 return -EINVAL;
4517 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004518
4519 *pChannel = tempInt;
4520 return VOS_STATUS_SUCCESS;
4521}
4522
4523#endif
4524
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004525#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004526/**---------------------------------------------------------------------------
4527
4528 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4529
4530 This function parses the SETCCKM IE command
4531 SETCCKMIE<space><ie data>
4532
4533 \param - pValue Pointer to input data
4534 \param - pCckmIe Pointer to output cckm Ie
4535 \param - pCckmIeLen Pointer to output cckm ie length
4536
4537 \return - 0 for success non-zero for failure
4538
4539 --------------------------------------------------------------------------*/
4540VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4541 tANI_U8 *pCckmIeLen)
4542{
4543 tANI_U8 *inPtr = pValue;
4544 tANI_U8 *dataEnd;
4545 int j = 0;
4546 int i = 0;
4547 tANI_U8 tempByte = 0;
4548
4549 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4550 /*no argument after the command*/
4551 if (NULL == inPtr)
4552 {
4553 return -EINVAL;
4554 }
4555
4556 /*no space after the command*/
4557 else if (SPACE_ASCII_VALUE != *inPtr)
4558 {
4559 return -EINVAL;
4560 }
4561
4562 /*removing empty spaces*/
4563 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4564
4565 /*no argument followed by spaces*/
4566 if ('\0' == *inPtr)
4567 {
4568 return -EINVAL;
4569 }
4570
4571 /* find the length of data */
4572 dataEnd = inPtr;
4573 while(('\0' != *dataEnd) )
4574 {
4575 dataEnd++;
4576 ++(*pCckmIeLen);
4577 }
4578 if ( *pCckmIeLen <= 0) return -EINVAL;
4579
4580 /* Allocate the number of bytes based on the number of input characters
4581 whether it is even or odd.
4582 if the number of input characters are even, then we need N/2 byte.
4583 if the number of input characters are odd, then we need do (N+1)/2 to
4584 compensate rounding off.
4585 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4586 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4587 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4588 if (NULL == *pCckmIe)
4589 {
4590 hddLog(VOS_TRACE_LEVEL_FATAL,
4591 "%s: vos_mem_alloc failed ", __func__);
4592 return -EINVAL;
4593 }
4594 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4595 /* the buffer received from the upper layer is character buffer,
4596 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4597 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4598 and f0 in 3rd location */
4599 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4600 {
4601 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4602 (*pCckmIe)[i++] = tempByte;
4603 }
4604 *pCckmIeLen = i;
4605
4606 return VOS_STATUS_SUCCESS;
4607}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004608#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004609
Jeff Johnson295189b2012-06-20 16:38:30 -07004610/**---------------------------------------------------------------------------
4611
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004612 \brief hdd_is_valid_mac_address() - Validate MAC address
4613
4614 This function validates whether the given MAC address is valid or not
4615 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4616 where X is the hexa decimal digit character and separated by ':'
4617 This algorithm works even if MAC address is not separated by ':'
4618
4619 This code checks given input string mac contains exactly 12 hexadecimal digits.
4620 and a separator colon : appears in the input string only after
4621 an even number of hex digits.
4622
4623 \param - pMacAddr pointer to the input MAC address
4624 \return - 1 for valid and 0 for invalid
4625
4626 --------------------------------------------------------------------------*/
4627
4628v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4629{
4630 int xdigit = 0;
4631 int separator = 0;
4632 while (*pMacAddr)
4633 {
4634 if (isxdigit(*pMacAddr))
4635 {
4636 xdigit++;
4637 }
4638 else if (':' == *pMacAddr)
4639 {
4640 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4641 break;
4642
4643 ++separator;
4644 }
4645 else
4646 {
4647 separator = -1;
4648 /* Invalid MAC found */
4649 return 0;
4650 }
4651 ++pMacAddr;
4652 }
4653 return (xdigit == 12 && (separator == 5 || separator == 0));
4654}
4655
4656/**---------------------------------------------------------------------------
4657
Jeff Johnson295189b2012-06-20 16:38:30 -07004658 \brief hdd_open() - HDD Open function
4659
4660 This is called in response to ifconfig up
4661
4662 \param - dev Pointer to net_device structure
4663
4664 \return - 0 for success non-zero for failure
4665
4666 --------------------------------------------------------------------------*/
4667int hdd_open (struct net_device *dev)
4668{
4669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4670 hdd_context_t *pHddCtx;
4671 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4672 VOS_STATUS status;
4673 v_BOOL_t in_standby = TRUE;
4674
4675 if (NULL == pAdapter)
4676 {
4677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304678 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 return -ENODEV;
4680 }
4681
4682 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304683 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4684 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 if (NULL == pHddCtx)
4686 {
4687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004688 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004689 return -ENODEV;
4690 }
4691
4692 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4693 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4694 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004695 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4696 {
4697 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304698 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004699 in_standby = FALSE;
4700 break;
4701 }
4702 else
4703 {
4704 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4705 pAdapterNode = pNext;
4706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004707 }
4708
4709 if (TRUE == in_standby)
4710 {
4711 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4712 {
4713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4714 "wlan out of power save", __func__);
4715 return -EINVAL;
4716 }
4717 }
4718
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004719 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4721 {
4722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004723 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004724 /* Enable TX queues only when we are connected */
4725 netif_tx_start_all_queues(dev);
4726 }
4727
4728 return 0;
4729}
4730
4731int hdd_mon_open (struct net_device *dev)
4732{
4733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4734
4735 if(pAdapter == NULL) {
4736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004737 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004738 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004739 }
4740
4741 netif_start_queue(dev);
4742
4743 return 0;
4744}
4745/**---------------------------------------------------------------------------
4746
4747 \brief hdd_stop() - HDD stop function
4748
4749 This is called in response to ifconfig down
4750
4751 \param - dev Pointer to net_device structure
4752
4753 \return - 0 for success non-zero for failure
4754
4755 --------------------------------------------------------------------------*/
4756
4757int hdd_stop (struct net_device *dev)
4758{
4759 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4760 hdd_context_t *pHddCtx;
4761 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4762 VOS_STATUS status;
4763 v_BOOL_t enter_standby = TRUE;
4764
4765 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004766 if (NULL == pAdapter)
4767 {
4768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304769 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 return -ENODEV;
4771 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304772 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4773 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004774 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4775 if (NULL == pHddCtx)
4776 {
4777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004778 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004779 return -ENODEV;
4780 }
4781
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004782 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004783 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4784 netif_tx_disable(pAdapter->dev);
4785 netif_carrier_off(pAdapter->dev);
4786
4787
4788 /* SoftAP ifaces should never go in power save mode
4789 making sure same here. */
4790 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4791 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004793 )
4794 {
4795 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4797 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004798 EXIT();
4799 return 0;
4800 }
4801
4802 /* Find if any iface is up then
4803 if any iface is up then can't put device to sleep/ power save mode. */
4804 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4805 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4806 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004807 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4808 {
4809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304810 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004811 enter_standby = FALSE;
4812 break;
4813 }
4814 else
4815 {
4816 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4817 pAdapterNode = pNext;
4818 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004819 }
4820
4821 if (TRUE == enter_standby)
4822 {
4823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4824 "entering standby", __func__);
4825 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4826 {
4827 /*log and return success*/
4828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4829 "wlan in power save", __func__);
4830 }
4831 }
4832
4833 EXIT();
4834 return 0;
4835}
4836
4837/**---------------------------------------------------------------------------
4838
4839 \brief hdd_uninit() - HDD uninit function
4840
4841 This is called during the netdev unregister to uninitialize all data
4842associated with the device
4843
4844 \param - dev Pointer to net_device structure
4845
4846 \return - void
4847
4848 --------------------------------------------------------------------------*/
4849static void hdd_uninit (struct net_device *dev)
4850{
4851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4852
4853 ENTER();
4854
4855 do
4856 {
4857 if (NULL == pAdapter)
4858 {
4859 hddLog(VOS_TRACE_LEVEL_FATAL,
4860 "%s: NULL pAdapter", __func__);
4861 break;
4862 }
4863
4864 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4865 {
4866 hddLog(VOS_TRACE_LEVEL_FATAL,
4867 "%s: Invalid magic", __func__);
4868 break;
4869 }
4870
4871 if (NULL == pAdapter->pHddCtx)
4872 {
4873 hddLog(VOS_TRACE_LEVEL_FATAL,
4874 "%s: NULL pHddCtx", __func__);
4875 break;
4876 }
4877
4878 if (dev != pAdapter->dev)
4879 {
4880 hddLog(VOS_TRACE_LEVEL_FATAL,
4881 "%s: Invalid device reference", __func__);
4882 /* we haven't validated all cases so let this go for now */
4883 }
4884
4885 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4886
4887 /* after uninit our adapter structure will no longer be valid */
4888 pAdapter->dev = NULL;
4889 pAdapter->magic = 0;
4890 } while (0);
4891
4892 EXIT();
4893}
4894
4895/**---------------------------------------------------------------------------
4896
4897 \brief hdd_release_firmware() -
4898
4899 This function calls the release firmware API to free the firmware buffer.
4900
4901 \param - pFileName Pointer to the File Name.
4902 pCtx - Pointer to the adapter .
4903
4904
4905 \return - 0 for success, non zero for failure
4906
4907 --------------------------------------------------------------------------*/
4908
4909VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4910{
4911 VOS_STATUS status = VOS_STATUS_SUCCESS;
4912 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4913 ENTER();
4914
4915
4916 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4917
4918 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4919
4920 if(pHddCtx->fw) {
4921 release_firmware(pHddCtx->fw);
4922 pHddCtx->fw = NULL;
4923 }
4924 else
4925 status = VOS_STATUS_E_FAILURE;
4926 }
4927 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
4928 if(pHddCtx->nv) {
4929 release_firmware(pHddCtx->nv);
4930 pHddCtx->nv = NULL;
4931 }
4932 else
4933 status = VOS_STATUS_E_FAILURE;
4934
4935 }
4936
4937 EXIT();
4938 return status;
4939}
4940
4941/**---------------------------------------------------------------------------
4942
4943 \brief hdd_request_firmware() -
4944
4945 This function reads the firmware file using the request firmware
4946 API and returns the the firmware data and the firmware file size.
4947
4948 \param - pfileName - Pointer to the file name.
4949 - pCtx - Pointer to the adapter .
4950 - ppfw_data - Pointer to the pointer of the firmware data.
4951 - pSize - Pointer to the file size.
4952
4953 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
4954
4955 --------------------------------------------------------------------------*/
4956
4957
4958VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
4959{
4960 int status;
4961 VOS_STATUS retval = VOS_STATUS_SUCCESS;
4962 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4963 ENTER();
4964
4965 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
4966
4967 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
4968
4969 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4970 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
4971 __func__, pfileName);
4972 retval = VOS_STATUS_E_FAILURE;
4973 }
4974
4975 else {
4976 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
4977 *pSize = pHddCtx->fw->size;
4978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
4979 __func__, *pSize);
4980 }
4981 }
4982 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
4983
4984 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
4985
4986 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
4987 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
4988 __func__, pfileName);
4989 retval = VOS_STATUS_E_FAILURE;
4990 }
4991
4992 else {
4993 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
4994 *pSize = pHddCtx->nv->size;
4995 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
4996 __func__, *pSize);
4997 }
4998 }
4999
5000 EXIT();
5001 return retval;
5002}
5003/**---------------------------------------------------------------------------
5004 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5005
5006 This is the function invoked by SME to inform the result of a full power
5007 request issued by HDD
5008
5009 \param - callbackcontext - Pointer to cookie
5010 status - result of request
5011
5012 \return - None
5013
5014--------------------------------------------------------------------------*/
5015void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5016{
5017 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5018
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005019 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 if(&pHddCtx->full_pwr_comp_var)
5021 {
5022 complete(&pHddCtx->full_pwr_comp_var);
5023 }
5024}
5025
5026/**---------------------------------------------------------------------------
5027
5028 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5029
5030 This is the function invoked by SME to inform the result of BMPS
5031 request issued by HDD
5032
5033 \param - callbackcontext - Pointer to cookie
5034 status - result of request
5035
5036 \return - None
5037
5038--------------------------------------------------------------------------*/
5039void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5040{
5041
5042 struct completion *completion_var = (struct completion*) callbackContext;
5043
Arif Hussain6d2a3322013-11-17 19:50:10 -08005044 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005045 if(completion_var != NULL)
5046 {
5047 complete(completion_var);
5048 }
5049}
5050
5051/**---------------------------------------------------------------------------
5052
5053 \brief hdd_get_cfg_file_size() -
5054
5055 This function reads the configuration file using the request firmware
5056 API and returns the configuration file size.
5057
5058 \param - pCtx - Pointer to the adapter .
5059 - pFileName - Pointer to the file name.
5060 - pBufSize - Pointer to the buffer size.
5061
5062 \return - 0 for success, non zero for failure
5063
5064 --------------------------------------------------------------------------*/
5065
5066VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5067{
5068 int status;
5069 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5070
5071 ENTER();
5072
5073 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5074
5075 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5076 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5077 status = VOS_STATUS_E_FAILURE;
5078 }
5079 else {
5080 *pBufSize = pHddCtx->fw->size;
5081 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5082 release_firmware(pHddCtx->fw);
5083 pHddCtx->fw = NULL;
5084 }
5085
5086 EXIT();
5087 return VOS_STATUS_SUCCESS;
5088}
5089
5090/**---------------------------------------------------------------------------
5091
5092 \brief hdd_read_cfg_file() -
5093
5094 This function reads the configuration file using the request firmware
5095 API and returns the cfg data and the buffer size of the configuration file.
5096
5097 \param - pCtx - Pointer to the adapter .
5098 - pFileName - Pointer to the file name.
5099 - pBuffer - Pointer to the data buffer.
5100 - pBufSize - Pointer to the buffer size.
5101
5102 \return - 0 for success, non zero for failure
5103
5104 --------------------------------------------------------------------------*/
5105
5106VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5107 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5108{
5109 int status;
5110 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5111
5112 ENTER();
5113
5114 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5115
5116 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5117 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5118 return VOS_STATUS_E_FAILURE;
5119 }
5120 else {
5121 if(*pBufSize != pHddCtx->fw->size) {
5122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5123 "file size", __func__);
5124 release_firmware(pHddCtx->fw);
5125 pHddCtx->fw = NULL;
5126 return VOS_STATUS_E_FAILURE;
5127 }
5128 else {
5129 if(pBuffer) {
5130 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5131 }
5132 release_firmware(pHddCtx->fw);
5133 pHddCtx->fw = NULL;
5134 }
5135 }
5136
5137 EXIT();
5138
5139 return VOS_STATUS_SUCCESS;
5140}
5141
5142/**---------------------------------------------------------------------------
5143
Jeff Johnson295189b2012-06-20 16:38:30 -07005144 \brief hdd_set_mac_address() -
5145
5146 This function sets the user specified mac address using
5147 the command ifconfig wlanX hw ether <mac adress>.
5148
5149 \param - dev - Pointer to the net device.
5150 - addr - Pointer to the sockaddr.
5151 \return - 0 for success, non zero for failure
5152
5153 --------------------------------------------------------------------------*/
5154
5155static int hdd_set_mac_address(struct net_device *dev, void *addr)
5156{
5157 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5158 struct sockaddr *psta_mac_addr = addr;
5159 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5160
5161 ENTER();
5162
5163 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5164
5165#ifdef HDD_SESSIONIZE
5166 // set the MAC address though the STA ID CFG.
5167 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5168 (v_U8_t *)&pAdapter->macAddressCurrent,
5169 sizeof( pAdapter->macAddressCurrent ),
5170 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305171
5172 if(eHAL_STATUS_SUCCESS != halStatus)
5173 {
5174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5175 "%s: failed to set MAC address in CFG", __func__);
5176 }
5177
Jeff Johnson295189b2012-06-20 16:38:30 -07005178#endif
5179
5180 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5181
5182 EXIT();
5183 return halStatus;
5184}
5185
5186tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5187{
5188 int i;
5189 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5190 {
Abhishek Singheb183782014-02-06 13:37:21 +05305191 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005192 break;
5193 }
5194
5195 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5196 return NULL;
5197
5198 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5199 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5200}
5201
5202void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5203{
5204 int i;
5205 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5206 {
5207 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5208 {
5209 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5210 break;
5211 }
5212 }
5213 return;
5214}
5215
5216#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5217 static struct net_device_ops wlan_drv_ops = {
5218 .ndo_open = hdd_open,
5219 .ndo_stop = hdd_stop,
5220 .ndo_uninit = hdd_uninit,
5221 .ndo_start_xmit = hdd_hard_start_xmit,
5222 .ndo_tx_timeout = hdd_tx_timeout,
5223 .ndo_get_stats = hdd_stats,
5224 .ndo_do_ioctl = hdd_ioctl,
5225 .ndo_set_mac_address = hdd_set_mac_address,
5226 .ndo_select_queue = hdd_select_queue,
5227#ifdef WLAN_FEATURE_PACKET_FILTERING
5228#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5229 .ndo_set_rx_mode = hdd_set_multicast_list,
5230#else
5231 .ndo_set_multicast_list = hdd_set_multicast_list,
5232#endif //LINUX_VERSION_CODE
5233#endif
5234 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 static struct net_device_ops wlan_mon_drv_ops = {
5236 .ndo_open = hdd_mon_open,
5237 .ndo_stop = hdd_stop,
5238 .ndo_uninit = hdd_uninit,
5239 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5240 .ndo_tx_timeout = hdd_tx_timeout,
5241 .ndo_get_stats = hdd_stats,
5242 .ndo_do_ioctl = hdd_ioctl,
5243 .ndo_set_mac_address = hdd_set_mac_address,
5244 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005245
5246#endif
5247
5248void hdd_set_station_ops( struct net_device *pWlanDev )
5249{
5250#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005251 pWlanDev->netdev_ops = &wlan_drv_ops;
5252#else
5253 pWlanDev->open = hdd_open;
5254 pWlanDev->stop = hdd_stop;
5255 pWlanDev->uninit = hdd_uninit;
5256 pWlanDev->hard_start_xmit = NULL;
5257 pWlanDev->tx_timeout = hdd_tx_timeout;
5258 pWlanDev->get_stats = hdd_stats;
5259 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005260 pWlanDev->set_mac_address = hdd_set_mac_address;
5261#endif
5262}
5263
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005264static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005265{
5266 struct net_device *pWlanDev = NULL;
5267 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005268 /*
5269 * cfg80211 initialization and registration....
5270 */
5271 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5272
Jeff Johnson295189b2012-06-20 16:38:30 -07005273 if(pWlanDev != NULL)
5274 {
5275
5276 //Save the pointer to the net_device in the HDD adapter
5277 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5278
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5280
5281 pAdapter->dev = pWlanDev;
5282 pAdapter->pHddCtx = pHddCtx;
5283 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5284
5285 init_completion(&pAdapter->session_open_comp_var);
5286 init_completion(&pAdapter->session_close_comp_var);
5287 init_completion(&pAdapter->disconnect_comp_var);
5288 init_completion(&pAdapter->linkup_event_var);
5289 init_completion(&pAdapter->cancel_rem_on_chan_var);
5290 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305291 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5293 init_completion(&pAdapter->offchannel_tx_event);
5294#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005295 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005296#ifdef FEATURE_WLAN_TDLS
5297 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005298 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005299 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305300 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005302 init_completion(&pHddCtx->mc_sus_event_var);
5303 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305304 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005305 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005306 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005307
Rajeev79dbe4c2013-10-05 11:03:42 +05305308#ifdef FEATURE_WLAN_BATCH_SCAN
5309 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5310 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5311 pAdapter->pBatchScanRsp = NULL;
5312 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005313 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005314 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305315 mutex_init(&pAdapter->hdd_batch_scan_lock);
5316#endif
5317
Jeff Johnson295189b2012-06-20 16:38:30 -07005318 pAdapter->isLinkUpSvcNeeded = FALSE;
5319 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5320 //Init the net_device structure
5321 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5322
5323 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5324 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5325 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5326 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5327
5328 hdd_set_station_ops( pAdapter->dev );
5329
5330 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5332 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5333 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 /* set pWlanDev's parent to underlying device */
5335 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5336 }
5337
5338 return pAdapter;
5339}
5340
5341VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5342{
5343 struct net_device *pWlanDev = pAdapter->dev;
5344 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5345 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5346 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5347
5348 if( rtnl_lock_held )
5349 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005350 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5352 {
5353 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5354 return VOS_STATUS_E_FAILURE;
5355 }
5356 }
5357 if (register_netdevice(pWlanDev))
5358 {
5359 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5360 return VOS_STATUS_E_FAILURE;
5361 }
5362 }
5363 else
5364 {
5365 if(register_netdev(pWlanDev))
5366 {
5367 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5368 return VOS_STATUS_E_FAILURE;
5369 }
5370 }
5371 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5372
5373 return VOS_STATUS_SUCCESS;
5374}
5375
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005376static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005377{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005378 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005379
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005380 if (NULL == pAdapter)
5381 {
5382 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5383 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005384 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005385
5386 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5387 {
5388 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5389 return eHAL_STATUS_NOT_INITIALIZED;
5390 }
5391
5392 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5393
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005394#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005395 /* need to make sure all of our scheduled work has completed.
5396 * This callback is called from MC thread context, so it is safe to
5397 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005398 *
5399 * Even though this is called from MC thread context, if there is a faulty
5400 * work item in the system, that can hang this call forever. So flushing
5401 * this global work queue is not safe; and now we make sure that
5402 * individual work queues are stopped correctly. But the cancel work queue
5403 * is a GPL only API, so the proprietary version of the driver would still
5404 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005405 */
5406 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005407#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005408
5409 /* We can be blocked while waiting for scheduled work to be
5410 * flushed, and the adapter structure can potentially be freed, in
5411 * which case the magic will have been reset. So make sure the
5412 * magic is still good, and hence the adapter structure is still
5413 * valid, before signaling completion */
5414 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5415 {
5416 complete(&pAdapter->session_close_comp_var);
5417 }
5418
Jeff Johnson295189b2012-06-20 16:38:30 -07005419 return eHAL_STATUS_SUCCESS;
5420}
5421
5422VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5423{
5424 struct net_device *pWlanDev = pAdapter->dev;
5425 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5426 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5427 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5428 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305429 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005430
5431 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005432 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 //Open a SME session for future operation
5434 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005435 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5437 {
5438 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005439 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 halStatus, halStatus );
5441 status = VOS_STATUS_E_FAILURE;
5442 goto error_sme_open;
5443 }
5444
5445 //Block on a completion variable. Can't wait forever though.
5446 rc = wait_for_completion_interruptible_timeout(
5447 &pAdapter->session_open_comp_var,
5448 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305449 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005450 {
5451 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305452 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 status = VOS_STATUS_E_FAILURE;
5454 goto error_sme_open;
5455 }
5456
5457 // Register wireless extensions
5458 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5459 {
5460 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005461 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 halStatus, halStatus );
5463 status = VOS_STATUS_E_FAILURE;
5464 goto error_register_wext;
5465 }
5466 //Safe to register the hard_start_xmit function again
5467#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5468 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5469#else
5470 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5471#endif
5472
5473 //Set the Connection State to Not Connected
5474 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5475
5476 //Set the default operation channel
5477 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5478
5479 /* Make the default Auth Type as OPEN*/
5480 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5481
5482 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5483 {
5484 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005485 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 status, status );
5487 goto error_init_txrx;
5488 }
5489
5490 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5491
5492 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5493 {
5494 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005495 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 status, status );
5497 goto error_wmm_init;
5498 }
5499
5500 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5501
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005502#ifdef FEATURE_WLAN_TDLS
5503 if(0 != wlan_hdd_tdls_init(pAdapter))
5504 {
5505 status = VOS_STATUS_E_FAILURE;
5506 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5507 goto error_tdls_init;
5508 }
5509 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5510#endif
5511
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 return VOS_STATUS_SUCCESS;
5513
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005514#ifdef FEATURE_WLAN_TDLS
5515error_tdls_init:
5516 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5517 hdd_wmm_adapter_close(pAdapter);
5518#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005519error_wmm_init:
5520 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5521 hdd_deinit_tx_rx(pAdapter);
5522error_init_txrx:
5523 hdd_UnregisterWext(pWlanDev);
5524error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005525 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 {
5527 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005528 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005530 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305532 unsigned long rc;
5533
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305535 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005537 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305538 if (rc <= 0)
5539 hddLog(VOS_TRACE_LEVEL_ERROR,
5540 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 }
5542}
5543error_sme_open:
5544 return status;
5545}
5546
Jeff Johnson295189b2012-06-20 16:38:30 -07005547void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5548{
5549 hdd_cfg80211_state_t *cfgState;
5550
5551 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5552
5553 if( NULL != cfgState->buf )
5554 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305555 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5557 rc = wait_for_completion_interruptible_timeout(
5558 &pAdapter->tx_action_cnf_event,
5559 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305560 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305563 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5564 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 }
5566 }
5567 return;
5568}
Jeff Johnson295189b2012-06-20 16:38:30 -07005569
5570void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5571{
5572 ENTER();
5573 switch ( pAdapter->device_mode )
5574 {
5575 case WLAN_HDD_INFRA_STATION:
5576 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005577 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 {
5579 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5580 {
5581 hdd_deinit_tx_rx( pAdapter );
5582 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5583 }
5584
5585 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5586 {
5587 hdd_wmm_adapter_close( pAdapter );
5588 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5589 }
5590
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005592#ifdef FEATURE_WLAN_TDLS
5593 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5594 {
5595 wlan_hdd_tdls_exit(pAdapter);
5596 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5597 }
5598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005599
5600 break;
5601 }
5602
5603 case WLAN_HDD_SOFTAP:
5604 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305606
5607 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5608 {
5609 hdd_wmm_adapter_close( pAdapter );
5610 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5611 }
5612
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005614
5615 hdd_unregister_hostapd(pAdapter);
5616 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 break;
5619 }
5620
5621 case WLAN_HDD_MONITOR:
5622 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5625 {
5626 hdd_deinit_tx_rx( pAdapter );
5627 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 if(NULL != pAdapterforTx)
5630 {
5631 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5632 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 break;
5634 }
5635
5636
5637 default:
5638 break;
5639 }
5640
5641 EXIT();
5642}
5643
5644void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5645{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005646 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305647
5648 ENTER();
5649 if (NULL == pAdapter)
5650 {
5651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5652 "%s: HDD adapter is Null", __func__);
5653 return;
5654 }
5655
5656 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005657
Rajeev79dbe4c2013-10-05 11:03:42 +05305658#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305659 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5660 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005661 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305662 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5663 )
5664 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005665 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305666 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005667 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5668 {
5669 hdd_deinit_batch_scan(pAdapter);
5670 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305671 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005672 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305673#endif
5674
Jeff Johnson295189b2012-06-20 16:38:30 -07005675 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5676 if( rtnl_held )
5677 {
5678 unregister_netdevice(pWlanDev);
5679 }
5680 else
5681 {
5682 unregister_netdev(pWlanDev);
5683 }
5684 // note that the pAdapter is no longer valid at this point
5685 // since the memory has been reclaimed
5686 }
5687
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305688 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005689}
5690
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005691void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5692{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305693 VOS_STATUS status;
5694 hdd_adapter_t *pAdapter = NULL;
5695 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005696
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305697 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005698
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305699 /*loop through all adapters.*/
5700 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005701 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305702 pAdapter = pAdapterNode->pAdapter;
5703 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5704 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005705
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305706 { // we skip this registration for modes other than STA and P2P client modes.
5707 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5708 pAdapterNode = pNext;
5709 continue;
5710 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005711
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305712 //Apply Dynamic DTIM For P2P
5713 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5714 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5715 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5716 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5717 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5718 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5719 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5720 (eConnectionState_Associated ==
5721 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5722 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5723 {
5724 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005725
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305726 powerRequest.uIgnoreDTIM = 1;
5727 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5728
5729 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5730 {
5731 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5732 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5733 }
5734 else
5735 {
5736 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5737 }
5738
5739 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5740 * specified during Enter/Exit BMPS when LCD off*/
5741 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5742 NULL, eANI_BOOLEAN_FALSE);
5743 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5744 NULL, eANI_BOOLEAN_FALSE);
5745
5746 /* switch to the DTIM specified in cfg.ini */
5747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5748 "Switch to DTIM %d", powerRequest.uListenInterval);
5749 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5750 break;
5751
5752 }
5753
5754 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5755 pAdapterNode = pNext;
5756 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005757}
5758
5759void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5760{
5761 /*Switch back to DTIM 1*/
5762 tSirSetPowerParamsReq powerRequest = { 0 };
5763
5764 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5765 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005766 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005767
5768 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5769 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5770 NULL, eANI_BOOLEAN_FALSE);
5771 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5772 NULL, eANI_BOOLEAN_FALSE);
5773
5774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5775 "Switch to DTIM%d",powerRequest.uListenInterval);
5776 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5777
5778}
5779
Jeff Johnson295189b2012-06-20 16:38:30 -07005780VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5781{
5782 VOS_STATUS status = VOS_STATUS_SUCCESS;
5783
5784 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5785 {
5786 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5787 }
5788
5789 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5790 {
5791 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5792 }
5793
5794 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5795 {
5796 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5797 }
5798
5799 return status;
5800}
5801
5802VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5803{
5804 hdd_adapter_t *pAdapter = NULL;
5805 eHalStatus halStatus;
5806 VOS_STATUS status = VOS_STATUS_E_INVAL;
5807 v_BOOL_t disableBmps = FALSE;
5808 v_BOOL_t disableImps = FALSE;
5809
5810 switch(session_type)
5811 {
5812 case WLAN_HDD_INFRA_STATION:
5813 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 case WLAN_HDD_P2P_CLIENT:
5815 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 //Exit BMPS -> Is Sta/P2P Client is already connected
5817 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5818 if((NULL != pAdapter)&&
5819 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5820 {
5821 disableBmps = TRUE;
5822 }
5823
5824 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5825 if((NULL != pAdapter)&&
5826 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5827 {
5828 disableBmps = TRUE;
5829 }
5830
5831 //Exit both Bmps and Imps incase of Go/SAP Mode
5832 if((WLAN_HDD_SOFTAP == session_type) ||
5833 (WLAN_HDD_P2P_GO == session_type))
5834 {
5835 disableBmps = TRUE;
5836 disableImps = TRUE;
5837 }
5838
5839 if(TRUE == disableImps)
5840 {
5841 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5842 {
5843 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5844 }
5845 }
5846
5847 if(TRUE == disableBmps)
5848 {
5849 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5850 {
5851 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5852
5853 if(eHAL_STATUS_SUCCESS != halStatus)
5854 {
5855 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005856 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 VOS_ASSERT(0);
5858 return status;
5859 }
5860 }
5861
5862 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5863 {
5864 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5865
5866 if(eHAL_STATUS_SUCCESS != halStatus)
5867 {
5868 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005869 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 VOS_ASSERT(0);
5871 return status;
5872 }
5873 }
5874 }
5875
5876 if((TRUE == disableBmps) ||
5877 (TRUE == disableImps))
5878 {
5879 /* Now, get the chip into Full Power now */
5880 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5881 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5882 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5883
5884 if(halStatus != eHAL_STATUS_SUCCESS)
5885 {
5886 if(halStatus == eHAL_STATUS_PMC_PENDING)
5887 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305888 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305890 ret = wait_for_completion_interruptible_timeout(
5891 &pHddCtx->full_pwr_comp_var,
5892 msecs_to_jiffies(1000));
5893 if (ret <= 0)
5894 {
5895 hddLog(VOS_TRACE_LEVEL_ERROR,
5896 "%s: wait on full_pwr_comp_var failed %ld",
5897 __func__, ret);
5898 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 }
5900 else
5901 {
5902 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005903 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 VOS_ASSERT(0);
5905 return status;
5906 }
5907 }
5908
5909 status = VOS_STATUS_SUCCESS;
5910 }
5911
5912 break;
5913 }
5914 return status;
5915}
5916
5917hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005918 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 tANI_U8 rtnl_held )
5920{
5921 hdd_adapter_t *pAdapter = NULL;
5922 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5923 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5924 VOS_STATUS exitbmpsStatus;
5925
Arif Hussain6d2a3322013-11-17 19:50:10 -08005926 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005927
Nirav Shah436658f2014-02-28 17:05:45 +05305928 if(macAddr == NULL)
5929 {
5930 /* Not received valid macAddr */
5931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5932 "%s:Unable to add virtual intf: Not able to get"
5933 "valid mac address",__func__);
5934 return NULL;
5935 }
5936
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 //Disable BMPS incase of Concurrency
5938 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
5939
5940 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
5941 {
5942 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305943 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 VOS_ASSERT(0);
5945 return NULL;
5946 }
5947
5948 switch(session_type)
5949 {
5950 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005952 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 {
5954 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5955
5956 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305957 {
5958 hddLog(VOS_TRACE_LEVEL_FATAL,
5959 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005962
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305963#ifdef FEATURE_WLAN_TDLS
5964 /* A Mutex Lock is introduced while changing/initializing the mode to
5965 * protect the concurrent access for the Adapters by TDLS module.
5966 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05305967 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305968#endif
5969
Jeff Johnsone7245742012-09-05 17:12:55 -07005970 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
5971 NL80211_IFTYPE_P2P_CLIENT:
5972 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07005973
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305975#ifdef FEATURE_WLAN_TDLS
5976 mutex_unlock(&pHddCtx->tdls_lock);
5977#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05305978
5979 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 if( VOS_STATUS_SUCCESS != status )
5981 goto err_free_netdev;
5982
5983 status = hdd_register_interface( pAdapter, rtnl_held );
5984 if( VOS_STATUS_SUCCESS != status )
5985 {
5986 hdd_deinit_adapter(pHddCtx, pAdapter);
5987 goto err_free_netdev;
5988 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305989
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05305990 // Workqueue which gets scheduled in IPv4 notification callback.
5991 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
5992
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305993#ifdef WLAN_NS_OFFLOAD
5994 // Workqueue which gets scheduled in IPv6 notification callback.
5995 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
5996#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 //Stop the Interface TX queue.
5998 netif_tx_disable(pAdapter->dev);
5999 //netif_tx_disable(pWlanDev);
6000 netif_carrier_off(pAdapter->dev);
6001
6002 break;
6003 }
6004
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 case WLAN_HDD_SOFTAP:
6007 {
6008 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6009 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306010 {
6011 hddLog(VOS_TRACE_LEVEL_FATAL,
6012 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306014 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006015
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6017 NL80211_IFTYPE_AP:
6018 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 pAdapter->device_mode = session_type;
6020
6021 status = hdd_init_ap_mode(pAdapter);
6022 if( VOS_STATUS_SUCCESS != status )
6023 goto err_free_netdev;
6024
6025 status = hdd_register_hostapd( pAdapter, rtnl_held );
6026 if( VOS_STATUS_SUCCESS != status )
6027 {
6028 hdd_deinit_adapter(pHddCtx, pAdapter);
6029 goto err_free_netdev;
6030 }
6031
6032 netif_tx_disable(pAdapter->dev);
6033 netif_carrier_off(pAdapter->dev);
6034
6035 hdd_set_conparam( 1 );
6036 break;
6037 }
6038 case WLAN_HDD_MONITOR:
6039 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6041 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306042 {
6043 hddLog(VOS_TRACE_LEVEL_FATAL,
6044 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306046 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006047
6048 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6049 pAdapter->device_mode = session_type;
6050 status = hdd_register_interface( pAdapter, rtnl_held );
6051#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6052 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6053#else
6054 pAdapter->dev->open = hdd_mon_open;
6055 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6056#endif
6057 hdd_init_tx_rx( pAdapter );
6058 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6059 //Set adapter to be used for data tx. It will use either GO or softap.
6060 pAdapter->sessionCtx.monitor.pAdapterForTx =
6061 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6063 {
6064 pAdapter->sessionCtx.monitor.pAdapterForTx =
6065 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6066 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 /* This workqueue will be used to transmit management packet over
6068 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006069 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6070 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6071 return NULL;
6072 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006073
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6075 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 }
6077 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 case WLAN_HDD_FTM:
6079 {
6080 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6081
6082 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306083 {
6084 hddLog(VOS_TRACE_LEVEL_FATAL,
6085 FL("failed to allocate adapter for session %d"), session_type);
6086 return NULL;
6087 }
6088
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6090 * message while loading driver in FTM mode. */
6091 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6092 pAdapter->device_mode = session_type;
6093 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306094
6095 hdd_init_tx_rx( pAdapter );
6096
6097 //Stop the Interface TX queue.
6098 netif_tx_disable(pAdapter->dev);
6099 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 }
6101 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006102 default:
6103 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306104 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6105 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 VOS_ASSERT(0);
6107 return NULL;
6108 }
6109 }
6110
Jeff Johnson295189b2012-06-20 16:38:30 -07006111 if( VOS_STATUS_SUCCESS == status )
6112 {
6113 //Add it to the hdd's session list.
6114 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6115 if( NULL == pHddAdapterNode )
6116 {
6117 status = VOS_STATUS_E_NOMEM;
6118 }
6119 else
6120 {
6121 pHddAdapterNode->pAdapter = pAdapter;
6122 status = hdd_add_adapter_back ( pHddCtx,
6123 pHddAdapterNode );
6124 }
6125 }
6126
6127 if( VOS_STATUS_SUCCESS != status )
6128 {
6129 if( NULL != pAdapter )
6130 {
6131 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6132 pAdapter = NULL;
6133 }
6134 if( NULL != pHddAdapterNode )
6135 {
6136 vos_mem_free( pHddAdapterNode );
6137 }
6138
6139 goto resume_bmps;
6140 }
6141
6142 if(VOS_STATUS_SUCCESS == status)
6143 {
6144 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6145
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006146 //Initialize the WoWL service
6147 if(!hdd_init_wowl(pAdapter))
6148 {
6149 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6150 goto err_free_netdev;
6151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 return pAdapter;
6154
6155err_free_netdev:
6156 free_netdev(pAdapter->dev);
6157 wlan_hdd_release_intf_addr( pHddCtx,
6158 pAdapter->macAddressCurrent.bytes );
6159
6160resume_bmps:
6161 //If bmps disabled enable it
6162 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6163 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306164 if (pHddCtx->hdd_wlan_suspended)
6165 {
6166 hdd_set_pwrparams(pHddCtx);
6167 }
6168 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 }
6170 return NULL;
6171}
6172
6173VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6174 tANI_U8 rtnl_held )
6175{
6176 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6177 VOS_STATUS status;
6178
6179 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6180 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306181 {
6182 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6183 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006184 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306185 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006186
6187 while ( pCurrent->pAdapter != pAdapter )
6188 {
6189 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6190 if( VOS_STATUS_SUCCESS != status )
6191 break;
6192
6193 pCurrent = pNext;
6194 }
6195 pAdapterNode = pCurrent;
6196 if( VOS_STATUS_SUCCESS == status )
6197 {
6198 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6199 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306200
6201#ifdef FEATURE_WLAN_TDLS
6202
6203 /* A Mutex Lock is introduced while changing/initializing the mode to
6204 * protect the concurrent access for the Adapters by TDLS module.
6205 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306206 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306207#endif
6208
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 hdd_remove_adapter( pHddCtx, pAdapterNode );
6210 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006211 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006212
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306213#ifdef FEATURE_WLAN_TDLS
6214 mutex_unlock(&pHddCtx->tdls_lock);
6215#endif
6216
Jeff Johnson295189b2012-06-20 16:38:30 -07006217
6218 /* If there is a single session of STA/P2P client, re-enable BMPS */
6219 if ((!vos_concurrent_sessions_running()) &&
6220 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6221 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6222 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306223 if (pHddCtx->hdd_wlan_suspended)
6224 {
6225 hdd_set_pwrparams(pHddCtx);
6226 }
6227 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 }
6229
6230 return VOS_STATUS_SUCCESS;
6231 }
6232
6233 return VOS_STATUS_E_FAILURE;
6234}
6235
6236VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6237{
6238 hdd_adapter_list_node_t *pHddAdapterNode;
6239 VOS_STATUS status;
6240
6241 ENTER();
6242
6243 do
6244 {
6245 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6246 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6247 {
6248 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6249 vos_mem_free( pHddAdapterNode );
6250 }
6251 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6252
6253 EXIT();
6254
6255 return VOS_STATUS_SUCCESS;
6256}
6257
6258void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6259{
6260 v_U8_t addIE[1] = {0};
6261
6262 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6263 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6264 eANI_BOOLEAN_FALSE) )
6265 {
6266 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006267 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 }
6269
6270 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6271 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6272 eANI_BOOLEAN_FALSE) )
6273 {
6274 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006275 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 }
6277
6278 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6279 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6280 eANI_BOOLEAN_FALSE) )
6281 {
6282 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006283 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 }
6285}
6286
6287VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6288{
6289 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6290 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6291 union iwreq_data wrqu;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306292 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006293
6294 ENTER();
6295
6296 switch(pAdapter->device_mode)
6297 {
6298 case WLAN_HDD_INFRA_STATION:
6299 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006300 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6302 {
6303 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6304 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6305 pAdapter->sessionId,
6306 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6307 else
6308 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6309 pAdapter->sessionId,
6310 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6311 //success implies disconnect command got queued up successfully
6312 if(halStatus == eHAL_STATUS_SUCCESS)
6313 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306314 ret = wait_for_completion_interruptible_timeout(
6315 &pAdapter->disconnect_comp_var,
6316 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6317 if (ret <= 0)
6318 {
6319 hddLog(VOS_TRACE_LEVEL_ERROR,
6320 "%s: wait on disconnect_comp_var failed %ld",
6321 __func__, ret);
6322 }
6323 }
6324 else
6325 {
6326 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6327 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 }
6329 memset(&wrqu, '\0', sizeof(wrqu));
6330 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6331 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6332 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6333 }
6334 else
6335 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306336 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6337 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306339#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306340#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306341 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6342#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306343 if (pAdapter->ipv6_notifier_registered)
6344 {
6345 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6346 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6347 pAdapter->ipv6_notifier_registered = false;
6348 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306349#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306350 if (pAdapter->ipv4_notifier_registered)
6351 {
6352 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6353 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6354 pAdapter->ipv4_notifier_registered = false;
6355 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306356#ifdef WLAN_OPEN_SOURCE
6357 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6360 {
6361 INIT_COMPLETION(pAdapter->session_close_comp_var);
6362 if (eHAL_STATUS_SUCCESS ==
6363 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6364 hdd_smeCloseSessionCallback, pAdapter))
6365 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306366 unsigned long ret;
6367
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306369 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 &pAdapter->session_close_comp_var,
6371 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306372 if ( 0 >= ret)
6373 {
6374 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6375 __func__, ret);
6376 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 }
6378 }
6379
6380 break;
6381
6382 case WLAN_HDD_SOFTAP:
6383 case WLAN_HDD_P2P_GO:
6384 //Any softap specific cleanup here...
6385 mutex_lock(&pHddCtx->sap_lock);
6386 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6387 {
6388 VOS_STATUS status;
6389 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6390
6391 //Stop Bss.
6392 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6393 if (VOS_IS_STATUS_SUCCESS(status))
6394 {
6395 hdd_hostapd_state_t *pHostapdState =
6396 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6397
6398 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6399
6400 if (!VOS_IS_STATUS_SUCCESS(status))
6401 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306402 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6403 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 }
6405 }
6406 else
6407 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006408 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 }
6410 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6411
6412 if (eHAL_STATUS_FAILURE ==
6413 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6414 0, NULL, eANI_BOOLEAN_FALSE))
6415 {
6416 hddLog(LOGE,
6417 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006418 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 }
6420
6421 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6422 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6423 eANI_BOOLEAN_FALSE) )
6424 {
6425 hddLog(LOGE,
6426 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6427 }
6428
6429 // Reset WNI_CFG_PROBE_RSP Flags
6430 wlan_hdd_reset_prob_rspies(pAdapter);
6431 kfree(pAdapter->sessionCtx.ap.beacon);
6432 pAdapter->sessionCtx.ap.beacon = NULL;
6433 }
6434 mutex_unlock(&pHddCtx->sap_lock);
6435 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006436
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006438#ifdef WLAN_OPEN_SOURCE
6439 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6440#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006442
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 default:
6444 break;
6445 }
6446
6447 EXIT();
6448 return VOS_STATUS_SUCCESS;
6449}
6450
6451VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6452{
6453 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6454 VOS_STATUS status;
6455 hdd_adapter_t *pAdapter;
6456
6457 ENTER();
6458
6459 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6460
6461 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6462 {
6463 pAdapter = pAdapterNode->pAdapter;
6464 netif_tx_disable(pAdapter->dev);
6465 netif_carrier_off(pAdapter->dev);
6466
6467 hdd_stop_adapter( pHddCtx, pAdapter );
6468
6469 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6470 pAdapterNode = pNext;
6471 }
6472
6473 EXIT();
6474
6475 return VOS_STATUS_SUCCESS;
6476}
6477
Rajeev Kumarf999e582014-01-09 17:33:29 -08006478
6479#ifdef FEATURE_WLAN_BATCH_SCAN
6480/**---------------------------------------------------------------------------
6481
6482 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6483 structures
6484
6485 \param - pAdapter Pointer to HDD adapter
6486
6487 \return - None
6488
6489 --------------------------------------------------------------------------*/
6490void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6491{
6492 tHddBatchScanRsp *pNode;
6493 tHddBatchScanRsp *pPrev;
6494
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306495 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006496 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306497 hddLog(VOS_TRACE_LEVEL_ERROR,
6498 "%s: Adapter context is Null", __func__);
6499 return;
6500 }
6501
6502 pNode = pAdapter->pBatchScanRsp;
6503 while (pNode)
6504 {
6505 pPrev = pNode;
6506 pNode = pNode->pNext;
6507 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006508 }
6509
6510 pAdapter->pBatchScanRsp = NULL;
6511 pAdapter->numScanList = 0;
6512 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6513 pAdapter->prev_batch_id = 0;
6514
6515 return;
6516}
6517#endif
6518
6519
Jeff Johnson295189b2012-06-20 16:38:30 -07006520VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6521{
6522 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6523 VOS_STATUS status;
6524 hdd_adapter_t *pAdapter;
6525
6526 ENTER();
6527
6528 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6529
6530 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6531 {
6532 pAdapter = pAdapterNode->pAdapter;
6533 netif_tx_disable(pAdapter->dev);
6534 netif_carrier_off(pAdapter->dev);
6535
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006536 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6537
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306539 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6540 {
6541 hdd_wmm_adapter_close( pAdapter );
6542 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006544
Rajeev Kumarf999e582014-01-09 17:33:29 -08006545#ifdef FEATURE_WLAN_BATCH_SCAN
6546 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6547 {
6548 hdd_deinit_batch_scan(pAdapter);
6549 }
6550#endif
6551
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6553 pAdapterNode = pNext;
6554 }
6555
6556 EXIT();
6557
6558 return VOS_STATUS_SUCCESS;
6559}
6560
6561VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6562{
6563 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6564 VOS_STATUS status;
6565 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306566 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006567
6568 ENTER();
6569
6570 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6571
6572 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6573 {
6574 pAdapter = pAdapterNode->pAdapter;
6575
6576 switch(pAdapter->device_mode)
6577 {
6578 case WLAN_HDD_INFRA_STATION:
6579 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006580 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306581
6582 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6583
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 hdd_init_station_mode(pAdapter);
6585 /* Open the gates for HDD to receive Wext commands */
6586 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006587 pHddCtx->scan_info.mScanPending = FALSE;
6588 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006589
6590 //Trigger the initial scan
6591 hdd_wlan_initial_scan(pAdapter);
6592
6593 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306594 if (eConnectionState_Associated == connState ||
6595 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 {
6597 union iwreq_data wrqu;
6598 memset(&wrqu, '\0', sizeof(wrqu));
6599 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6600 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6601 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006602 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006603
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 /* indicate disconnected event to nl80211 */
6605 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6606 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306608 else if (eConnectionState_Connecting == connState)
6609 {
6610 /*
6611 * Indicate connect failure to supplicant if we were in the
6612 * process of connecting
6613 */
6614 cfg80211_connect_result(pAdapter->dev, NULL,
6615 NULL, 0, NULL, 0,
6616 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6617 GFP_KERNEL);
6618 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006619 break;
6620
6621 case WLAN_HDD_SOFTAP:
6622 /* softAP can handle SSR */
6623 break;
6624
6625 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006628 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 break;
6630
6631 case WLAN_HDD_MONITOR:
6632 /* monitor interface start */
6633 break;
6634 default:
6635 break;
6636 }
6637
6638 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6639 pAdapterNode = pNext;
6640 }
6641
6642 EXIT();
6643
6644 return VOS_STATUS_SUCCESS;
6645}
6646
6647VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6648{
6649 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6650 hdd_adapter_t *pAdapter;
6651 VOS_STATUS status;
6652 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306653 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006654
6655 ENTER();
6656
6657 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6658
6659 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6660 {
6661 pAdapter = pAdapterNode->pAdapter;
6662
6663 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6664 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6665 {
6666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6667 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6668
6669 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6670 init_completion(&pAdapter->disconnect_comp_var);
6671 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6672 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6673
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306674 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006675 &pAdapter->disconnect_comp_var,
6676 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306677 if (0 >= ret)
6678 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6679 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006680
6681 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6682 pHddCtx->isAmpAllowed = VOS_FALSE;
6683 sme_RoamConnect(pHddCtx->hHal,
6684 pAdapter->sessionId, &(pWextState->roamProfile),
6685 &roamId);
6686 }
6687
6688 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6689 pAdapterNode = pNext;
6690 }
6691
6692 EXIT();
6693
6694 return VOS_STATUS_SUCCESS;
6695}
6696
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006697void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6698{
6699 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6700 VOS_STATUS status;
6701 hdd_adapter_t *pAdapter;
6702 hdd_station_ctx_t *pHddStaCtx;
6703 hdd_ap_ctx_t *pHddApCtx;
6704 hdd_hostapd_state_t * pHostapdState;
6705 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6706 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6707 const char *p2pMode = "DEV";
6708 const char *ccMode = "Standalone";
6709 int n;
6710
6711 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6712 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6713 {
6714 pAdapter = pAdapterNode->pAdapter;
6715 switch (pAdapter->device_mode) {
6716 case WLAN_HDD_INFRA_STATION:
6717 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6718 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6719 staChannel = pHddStaCtx->conn_info.operationChannel;
6720 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6721 }
6722 break;
6723 case WLAN_HDD_P2P_CLIENT:
6724 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6725 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6726 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6727 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6728 p2pMode = "CLI";
6729 }
6730 break;
6731 case WLAN_HDD_P2P_GO:
6732 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6733 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6734 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6735 p2pChannel = pHddApCtx->operatingChannel;
6736 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6737 }
6738 p2pMode = "GO";
6739 break;
6740 case WLAN_HDD_SOFTAP:
6741 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6742 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6743 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6744 apChannel = pHddApCtx->operatingChannel;
6745 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6746 }
6747 break;
6748 default:
6749 break;
6750 }
6751 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6752 pAdapterNode = pNext;
6753 }
6754 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6755 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6756 }
6757 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6758 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6759 if (p2pChannel > 0) {
6760 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6761 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6762 }
6763 if (apChannel > 0) {
6764 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6765 apChannel, MAC_ADDR_ARRAY(apBssid));
6766 }
6767
6768 if (p2pChannel > 0 && apChannel > 0) {
6769 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6770 }
6771}
6772
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006773bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006774{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006775 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006776}
6777
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006778/* Once SSR is disabled then it cannot be set. */
6779void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006780{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006781 if (HDD_SSR_DISABLED == isSsrRequired)
6782 return;
6783
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 isSsrRequired = value;
6785}
6786
6787VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6788 hdd_adapter_list_node_t** ppAdapterNode)
6789{
6790 VOS_STATUS status;
6791 spin_lock(&pHddCtx->hddAdapters.lock);
6792 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6793 (hdd_list_node_t**) ppAdapterNode );
6794 spin_unlock(&pHddCtx->hddAdapters.lock);
6795 return status;
6796}
6797
6798VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6799 hdd_adapter_list_node_t* pAdapterNode,
6800 hdd_adapter_list_node_t** pNextAdapterNode)
6801{
6802 VOS_STATUS status;
6803 spin_lock(&pHddCtx->hddAdapters.lock);
6804 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6805 (hdd_list_node_t*) pAdapterNode,
6806 (hdd_list_node_t**)pNextAdapterNode );
6807
6808 spin_unlock(&pHddCtx->hddAdapters.lock);
6809 return status;
6810}
6811
6812VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6813 hdd_adapter_list_node_t* pAdapterNode)
6814{
6815 VOS_STATUS status;
6816 spin_lock(&pHddCtx->hddAdapters.lock);
6817 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6818 &pAdapterNode->node );
6819 spin_unlock(&pHddCtx->hddAdapters.lock);
6820 return status;
6821}
6822
6823VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6824 hdd_adapter_list_node_t** ppAdapterNode)
6825{
6826 VOS_STATUS status;
6827 spin_lock(&pHddCtx->hddAdapters.lock);
6828 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6829 (hdd_list_node_t**) ppAdapterNode );
6830 spin_unlock(&pHddCtx->hddAdapters.lock);
6831 return status;
6832}
6833
6834VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6835 hdd_adapter_list_node_t* pAdapterNode)
6836{
6837 VOS_STATUS status;
6838 spin_lock(&pHddCtx->hddAdapters.lock);
6839 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6840 (hdd_list_node_t*) pAdapterNode );
6841 spin_unlock(&pHddCtx->hddAdapters.lock);
6842 return status;
6843}
6844
6845VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6846 hdd_adapter_list_node_t* pAdapterNode)
6847{
6848 VOS_STATUS status;
6849 spin_lock(&pHddCtx->hddAdapters.lock);
6850 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6851 (hdd_list_node_t*) pAdapterNode );
6852 spin_unlock(&pHddCtx->hddAdapters.lock);
6853 return status;
6854}
6855
6856hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6857 tSirMacAddr macAddr )
6858{
6859 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6860 hdd_adapter_t *pAdapter;
6861 VOS_STATUS status;
6862
6863 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6864
6865 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6866 {
6867 pAdapter = pAdapterNode->pAdapter;
6868
6869 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
6870 macAddr, sizeof(tSirMacAddr) ) )
6871 {
6872 return pAdapter;
6873 }
6874 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6875 pAdapterNode = pNext;
6876 }
6877
6878 return NULL;
6879
6880}
6881
6882hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
6883{
6884 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6885 hdd_adapter_t *pAdapter;
6886 VOS_STATUS status;
6887
6888 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6889
6890 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6891 {
6892 pAdapter = pAdapterNode->pAdapter;
6893
6894 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
6895 IFNAMSIZ ) )
6896 {
6897 return pAdapter;
6898 }
6899 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6900 pAdapterNode = pNext;
6901 }
6902
6903 return NULL;
6904
6905}
6906
6907hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
6908{
6909 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6910 hdd_adapter_t *pAdapter;
6911 VOS_STATUS status;
6912
6913 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6914
6915 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6916 {
6917 pAdapter = pAdapterNode->pAdapter;
6918
6919 if( pAdapter && (mode == pAdapter->device_mode) )
6920 {
6921 return pAdapter;
6922 }
6923 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6924 pAdapterNode = pNext;
6925 }
6926
6927 return NULL;
6928
6929}
6930
6931//Remove this function later
6932hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
6933{
6934 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6935 hdd_adapter_t *pAdapter;
6936 VOS_STATUS status;
6937
6938 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6939
6940 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6941 {
6942 pAdapter = pAdapterNode->pAdapter;
6943
6944 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
6945 {
6946 return pAdapter;
6947 }
6948
6949 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6950 pAdapterNode = pNext;
6951 }
6952
6953 return NULL;
6954
6955}
6956
Jeff Johnson295189b2012-06-20 16:38:30 -07006957/**---------------------------------------------------------------------------
6958
6959 \brief hdd_set_monitor_tx_adapter() -
6960
6961 This API initializes the adapter to be used while transmitting on monitor
6962 adapter.
6963
6964 \param - pHddCtx - Pointer to the HDD context.
6965 pAdapter - Adapter that will used for TX. This can be NULL.
6966 \return - None.
6967 --------------------------------------------------------------------------*/
6968void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6969{
6970 hdd_adapter_t *pMonAdapter;
6971
6972 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
6973
6974 if( NULL != pMonAdapter )
6975 {
6976 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
6977 }
6978}
Jeff Johnson295189b2012-06-20 16:38:30 -07006979/**---------------------------------------------------------------------------
6980
6981 \brief hdd_select_queue() -
6982
6983 This API returns the operating channel of the requested device mode
6984
6985 \param - pHddCtx - Pointer to the HDD context.
6986 - mode - Device mode for which operating channel is required
6987 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
6988 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
6989 \return - channel number. "0" id the requested device is not found OR it is not connected.
6990 --------------------------------------------------------------------------*/
6991v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
6992{
6993 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6994 VOS_STATUS status;
6995 hdd_adapter_t *pAdapter;
6996 v_U8_t operatingChannel = 0;
6997
6998 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6999
7000 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7001 {
7002 pAdapter = pAdapterNode->pAdapter;
7003
7004 if( mode == pAdapter->device_mode )
7005 {
7006 switch(pAdapter->device_mode)
7007 {
7008 case WLAN_HDD_INFRA_STATION:
7009 case WLAN_HDD_P2P_CLIENT:
7010 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7011 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7012 break;
7013 case WLAN_HDD_SOFTAP:
7014 case WLAN_HDD_P2P_GO:
7015 /*softap connection info */
7016 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7017 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7018 break;
7019 default:
7020 break;
7021 }
7022
7023 break; //Found the device of interest. break the loop
7024 }
7025
7026 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7027 pAdapterNode = pNext;
7028 }
7029 return operatingChannel;
7030}
7031
7032#ifdef WLAN_FEATURE_PACKET_FILTERING
7033/**---------------------------------------------------------------------------
7034
7035 \brief hdd_set_multicast_list() -
7036
7037 This used to set the multicast address list.
7038
7039 \param - dev - Pointer to the WLAN device.
7040 - skb - Pointer to OS packet (sk_buff).
7041 \return - success/fail
7042
7043 --------------------------------------------------------------------------*/
7044static void hdd_set_multicast_list(struct net_device *dev)
7045{
7046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 int mc_count;
7048 int i = 0;
7049 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307050
7051 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 {
7053 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307054 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 return;
7056 }
7057
7058 if (dev->flags & IFF_ALLMULTI)
7059 {
7060 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007061 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307062 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 }
7064 else
7065 {
7066 mc_count = netdev_mc_count(dev);
7067 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007068 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7070 {
7071 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007072 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307073 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 return;
7075 }
7076
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307077 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078
7079 netdev_for_each_mc_addr(ha, dev) {
7080 if (i == mc_count)
7081 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307082 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7083 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007084 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307086 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 i++;
7088 }
7089 }
7090 return;
7091}
7092#endif
7093
7094/**---------------------------------------------------------------------------
7095
7096 \brief hdd_select_queue() -
7097
7098 This function is registered with the Linux OS for network
7099 core to decide which queue to use first.
7100
7101 \param - dev - Pointer to the WLAN device.
7102 - skb - Pointer to OS packet (sk_buff).
7103 \return - ac, Queue Index/access category corresponding to UP in IP header
7104
7105 --------------------------------------------------------------------------*/
7106v_U16_t hdd_select_queue(struct net_device *dev,
7107 struct sk_buff *skb)
7108{
7109 return hdd_wmm_select_queue(dev, skb);
7110}
7111
7112
7113/**---------------------------------------------------------------------------
7114
7115 \brief hdd_wlan_initial_scan() -
7116
7117 This function triggers the initial scan
7118
7119 \param - pAdapter - Pointer to the HDD adapter.
7120
7121 --------------------------------------------------------------------------*/
7122void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7123{
7124 tCsrScanRequest scanReq;
7125 tCsrChannelInfo channelInfo;
7126 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007127 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7129
7130 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7131 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7132 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7133
7134 if(sme_Is11dSupported(pHddCtx->hHal))
7135 {
7136 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7137 if ( HAL_STATUS_SUCCESS( halStatus ) )
7138 {
7139 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7140 if( !scanReq.ChannelInfo.ChannelList )
7141 {
7142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7143 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007144 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 return;
7146 }
7147 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7148 channelInfo.numOfChannels);
7149 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7150 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007151 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 }
7153
7154 scanReq.scanType = eSIR_PASSIVE_SCAN;
7155 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7156 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7157 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7158 }
7159 else
7160 {
7161 scanReq.scanType = eSIR_ACTIVE_SCAN;
7162 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7163 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7164 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7165 }
7166
7167 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7168 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7169 {
7170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7171 __func__, halStatus );
7172 }
7173
7174 if(sme_Is11dSupported(pHddCtx->hHal))
7175 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7176}
7177
Jeff Johnson295189b2012-06-20 16:38:30 -07007178/**---------------------------------------------------------------------------
7179
7180 \brief hdd_full_power_callback() - HDD full power callback function
7181
7182 This is the function invoked by SME to inform the result of a full power
7183 request issued by HDD
7184
7185 \param - callbackcontext - Pointer to cookie
7186 \param - status - result of request
7187
7188 \return - None
7189
7190 --------------------------------------------------------------------------*/
7191static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7192{
Jeff Johnson72a40512013-12-19 10:14:15 -08007193 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007194
7195 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307196 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 if (NULL == callbackContext)
7199 {
7200 hddLog(VOS_TRACE_LEVEL_ERROR,
7201 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007202 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 return;
7204 }
7205
Jeff Johnson72a40512013-12-19 10:14:15 -08007206 /* there is a race condition that exists between this callback
7207 function and the caller since the caller could time out either
7208 before or while this code is executing. we use a spinlock to
7209 serialize these actions */
7210 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007211
7212 if (POWER_CONTEXT_MAGIC != pContext->magic)
7213 {
7214 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007215 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 hddLog(VOS_TRACE_LEVEL_WARN,
7217 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007218 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 return;
7220 }
7221
Jeff Johnson72a40512013-12-19 10:14:15 -08007222 /* context is valid so caller is still waiting */
7223
7224 /* paranoia: invalidate the magic */
7225 pContext->magic = 0;
7226
7227 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007228 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007229
7230 /* serialization is complete */
7231 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007232}
7233
7234/**---------------------------------------------------------------------------
7235
7236 \brief hdd_wlan_exit() - HDD WLAN exit function
7237
7238 This is the driver exit point (invoked during rmmod)
7239
7240 \param - pHddCtx - Pointer to the HDD Context
7241
7242 \return - None
7243
7244 --------------------------------------------------------------------------*/
7245void hdd_wlan_exit(hdd_context_t *pHddCtx)
7246{
7247 eHalStatus halStatus;
7248 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7249 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307250 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007251 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007252 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 long lrc;
7254
7255 ENTER();
7256
Jeff Johnson88ba7742013-02-27 14:36:02 -08007257 if (VOS_FTM_MODE != hdd_get_conparam())
7258 {
7259 // Unloading, restart logic is no more required.
7260 wlan_hdd_restart_deinit(pHddCtx);
7261 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007262
Jeff Johnson295189b2012-06-20 16:38:30 -07007263 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 {
7267 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7268 WLAN_HDD_INFRA_STATION);
7269 if (pAdapter == NULL)
7270 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7271
7272 if (pAdapter != NULL)
7273 {
7274 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7275 hdd_UnregisterWext(pAdapter->dev);
7276 }
7277 }
7278 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007279
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007281 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307282 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007283 wlan_hdd_ftm_close(pHddCtx);
7284 goto free_hdd_ctx;
7285 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 //Stop the Interface TX queue.
7287 //netif_tx_disable(pWlanDev);
7288 //netif_carrier_off(pWlanDev);
7289
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7291 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307292 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 pAdapter = hdd_get_adapter(pHddCtx,
7294 WLAN_HDD_SOFTAP);
7295 }
7296 else
7297 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307300 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 pAdapter = hdd_get_adapter(pHddCtx,
7302 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007303 if (pAdapter == NULL)
7304 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307307
7308 if(NULL == pAdapter)
7309 {
7310 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7311 goto free_hdd_ctx;
7312 }
7313
Jeff Johnson295189b2012-06-20 16:38:30 -07007314 /* DeRegister with platform driver as client for Suspend/Resume */
7315 vosStatus = hddDeregisterPmOps(pHddCtx);
7316 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7317 {
7318 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7319 VOS_ASSERT(0);
7320 }
7321
7322 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7323 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7324 {
7325 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007327
7328 // Cancel any outstanding scan requests. We are about to close all
7329 // of our adapters, but an adapter structure is what SME passes back
7330 // to our callback function. Hence if there are any outstanding scan
7331 // requests then there is a race condition between when the adapter
7332 // is closed and when the callback is invoked. We try to resolve that
7333 // race condition here by canceling any outstanding scans before we
7334 // close the adapters.
7335 // Note that the scans may be cancelled in an asynchronous manner, so
7336 // ideally there needs to be some kind of synchronization. Rather than
7337 // introduce a new synchronization here, we will utilize the fact that
7338 // we are about to Request Full Power, and since that is synchronized,
7339 // the expectation is that by the time Request Full Power has completed,
7340 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007341 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307342 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007343 else
7344 hddLog(VOS_TRACE_LEVEL_ERROR,
7345 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007346
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007347 //Stop the traffic monitor timer
7348 if ( VOS_TIMER_STATE_RUNNING ==
7349 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7350 {
7351 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7352 }
7353
7354 // Destroy the traffic monitor timer
7355 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7356 &pHddCtx->tx_rx_trafficTmr)))
7357 {
7358 hddLog(VOS_TRACE_LEVEL_ERROR,
7359 "%s: Cannot deallocate Traffic monitor timer", __func__);
7360 }
7361
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 //Disable IMPS/BMPS as we do not want the device to enter any power
7363 //save mode during shutdown
7364 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7365 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7366 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7367
7368 //Ensure that device is in full power as we will touch H/W during vos_Stop
7369 init_completion(&powerContext.completion);
7370 powerContext.magic = POWER_CONTEXT_MAGIC;
7371
7372 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7373 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7374
7375 if (eHAL_STATUS_SUCCESS != halStatus)
7376 {
7377 if (eHAL_STATUS_PMC_PENDING == halStatus)
7378 {
7379 /* request was sent -- wait for the response */
7380 lrc = wait_for_completion_interruptible_timeout(
7381 &powerContext.completion,
7382 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 if (lrc <= 0)
7384 {
7385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007386 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 }
7388 }
7389 else
7390 {
7391 hddLog(VOS_TRACE_LEVEL_ERROR,
7392 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007393 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 /* continue -- need to clean up as much as possible */
7395 }
7396 }
7397
Jeff Johnson72a40512013-12-19 10:14:15 -08007398 /* either we never sent a request, we sent a request and received a
7399 response or we sent a request and timed out. if we never sent a
7400 request or if we sent a request and got a response, we want to
7401 clear the magic out of paranoia. if we timed out there is a
7402 race condition such that the callback function could be
7403 executing at the same time we are. of primary concern is if the
7404 callback function had already verified the "magic" but had not
7405 yet set the completion variable when a timeout occurred. we
7406 serialize these activities by invalidating the magic while
7407 holding a shared spinlock which will cause us to block if the
7408 callback is currently executing */
7409 spin_lock(&hdd_context_lock);
7410 powerContext.magic = 0;
7411 spin_unlock(&hdd_context_lock);
7412
Yue Ma0d4891e2013-08-06 17:01:45 -07007413 hdd_debugfs_exit(pHddCtx);
7414
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 // Unregister the Net Device Notifier
7416 unregister_netdevice_notifier(&hdd_netdev_notifier);
7417
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 hdd_stop_all_adapters( pHddCtx );
7419
Jeff Johnson295189b2012-06-20 16:38:30 -07007420#ifdef WLAN_BTAMP_FEATURE
7421 vosStatus = WLANBAP_Stop(pVosContext);
7422 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7423 {
7424 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7425 "%s: Failed to stop BAP",__func__);
7426 }
7427#endif //WLAN_BTAMP_FEATURE
7428
7429 //Stop all the modules
7430 vosStatus = vos_stop( pVosContext );
7431 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7432 {
7433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7434 "%s: Failed to stop VOSS",__func__);
7435 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7436 }
7437
Jeff Johnson295189b2012-06-20 16:38:30 -07007438 //Assert Deep sleep signal now to put Libra HW in lowest power state
7439 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7440 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7441
7442 //Vote off any PMIC voltage supplies
7443 vos_chipPowerDown(NULL, NULL, NULL);
7444
7445 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7446
Leo Chang59cdc7e2013-07-10 10:08:21 -07007447
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007450
7451 //Close the scheduler before calling vos_close to make sure no thread is
7452 // scheduled after the each module close is called i.e after all the data
7453 // structures are freed.
7454 vosStatus = vos_sched_close( pVosContext );
7455 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7456 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7457 "%s: Failed to close VOSS Scheduler",__func__);
7458 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7459 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007460#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007461#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7462 /* Destroy the wake lock */
7463 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7464#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007465 /* Destroy the wake lock */
7466 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007468
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307469#ifdef CONFIG_ENABLE_LINUX_REG
7470 vosStatus = vos_nv_close();
7471 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7472 {
7473 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7474 "%s: Failed to close NV", __func__);
7475 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7476 }
7477#endif
7478
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 //Close VOSS
7480 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7481 vos_close(pVosContext);
7482
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 //Close Watchdog
7484 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7485 vos_watchdog_close(pVosContext);
7486
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307487 //Clean up HDD Nlink Service
7488 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007489#ifdef WLAN_KD_READY_NOTIFIER
7490 nl_srv_exit(pHddCtx->ptt_pid);
7491#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307492 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007493#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307494
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307495#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
7496 if(pHddCtx->cfg_ini->wlanLoggingEnable)
7497 {
7498 wlan_logging_sock_deactivate_svc();
7499 }
7500#endif
7501
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 /* Cancel the vote for XO Core ON.
7503 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7504 * exited at this point
7505 */
7506 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007507 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7509 {
7510 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7511 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007512 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007513 }
7514
7515 hdd_close_all_adapters( pHddCtx );
7516
7517
7518 //Free up dynamically allocated members inside HDD Adapter
7519 kfree(pHddCtx->cfg_ini);
7520 pHddCtx->cfg_ini= NULL;
7521
7522 /* free the power on lock from platform driver */
7523 if (free_riva_power_on_lock("wlan"))
7524 {
7525 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7526 __func__);
7527 }
7528
Jeff Johnson88ba7742013-02-27 14:36:02 -08007529free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007530 /* FTM mode, WIPHY did not registered
7531 If un-register here, system crash will happen */
7532 if (VOS_FTM_MODE != hdd_get_conparam())
7533 {
7534 wiphy_unregister(wiphy) ;
7535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 if (hdd_is_ssr_required())
7538 {
7539 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007540 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 msleep(5000);
7542 }
7543 hdd_set_ssr_required (VOS_FALSE);
7544}
7545
7546
7547/**---------------------------------------------------------------------------
7548
7549 \brief hdd_update_config_from_nv() - Function to update the contents of
7550 the running configuration with parameters taken from NV storage
7551
7552 \param - pHddCtx - Pointer to the HDD global context
7553
7554 \return - VOS_STATUS_SUCCESS if successful
7555
7556 --------------------------------------------------------------------------*/
7557static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7558{
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 v_BOOL_t itemIsValid = VOS_FALSE;
7560 VOS_STATUS status;
7561 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7562 v_U8_t macLoop;
7563
7564 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7565 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7566 if(status != VOS_STATUS_SUCCESS)
7567 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007568 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007569 return VOS_STATUS_E_FAILURE;
7570 }
7571
7572 if (itemIsValid == VOS_TRUE)
7573 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007574 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7576 VOS_MAX_CONCURRENCY_PERSONA);
7577 if(status != VOS_STATUS_SUCCESS)
7578 {
7579 /* Get MAC from NV fail, not update CFG info
7580 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007581 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007582 return VOS_STATUS_E_FAILURE;
7583 }
7584
7585 /* If first MAC is not valid, treat all others are not valid
7586 * Then all MACs will be got from ini file */
7587 if(vos_is_macaddr_zero(&macFromNV[0]))
7588 {
7589 /* MAC address in NV file is not configured yet */
7590 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7591 return VOS_STATUS_E_INVAL;
7592 }
7593
7594 /* Get MAC address from NV, update CFG info */
7595 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7596 {
7597 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7598 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307599 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 /* This MAC is not valid, skip it
7601 * This MAC will be got from ini file */
7602 }
7603 else
7604 {
7605 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7606 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7607 VOS_MAC_ADDR_SIZE);
7608 }
7609 }
7610 }
7611 else
7612 {
7613 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7614 return VOS_STATUS_E_FAILURE;
7615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007616
Jeff Johnson295189b2012-06-20 16:38:30 -07007617
7618 return VOS_STATUS_SUCCESS;
7619}
7620
7621/**---------------------------------------------------------------------------
7622
7623 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7624
7625 \param - pAdapter - Pointer to the HDD
7626
7627 \return - None
7628
7629 --------------------------------------------------------------------------*/
7630VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7631{
7632 eHalStatus halStatus;
7633 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307634 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007635
Jeff Johnson295189b2012-06-20 16:38:30 -07007636
7637 // Send ready indication to the HDD. This will kick off the MAC
7638 // into a 'running' state and should kick off an initial scan.
7639 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7640 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7641 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307642 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 "code %08d [x%08x]",__func__, halStatus, halStatus );
7644 return VOS_STATUS_E_FAILURE;
7645 }
7646
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307647 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7649 // And RIVA will crash
7650 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7651 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307652 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7653 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7654
7655
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 return VOS_STATUS_SUCCESS;
7657}
7658
Jeff Johnson295189b2012-06-20 16:38:30 -07007659/* wake lock APIs for HDD */
7660void hdd_prevent_suspend(void)
7661{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007662#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007664#else
7665 wcnss_prevent_suspend();
7666#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007667}
7668
7669void hdd_allow_suspend(void)
7670{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007671#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007673#else
7674 wcnss_allow_suspend();
7675#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007676}
7677
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307678void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007679{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007680#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007681 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007682#else
7683 /* Do nothing as there is no API in wcnss for timeout*/
7684#endif
7685}
7686
Jeff Johnson295189b2012-06-20 16:38:30 -07007687/**---------------------------------------------------------------------------
7688
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007689 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7690 information between Host and Riva
7691
7692 This function gets reported version of FW
7693 It also finds the version of Riva headers used to compile the host
7694 It compares the above two and prints a warning if they are different
7695 It gets the SW and HW version string
7696 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7697 indicating the features they support through a bitmap
7698
7699 \param - pHddCtx - Pointer to HDD context
7700
7701 \return - void
7702
7703 --------------------------------------------------------------------------*/
7704
7705void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7706{
7707
7708 tSirVersionType versionCompiled;
7709 tSirVersionType versionReported;
7710 tSirVersionString versionString;
7711 tANI_U8 fwFeatCapsMsgSupported = 0;
7712 VOS_STATUS vstatus;
7713
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007714 memset(&versionCompiled, 0, sizeof(versionCompiled));
7715 memset(&versionReported, 0, sizeof(versionReported));
7716
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007717 /* retrieve and display WCNSS version information */
7718 do {
7719
7720 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7721 &versionCompiled);
7722 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7723 {
7724 hddLog(VOS_TRACE_LEVEL_FATAL,
7725 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007726 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007727 break;
7728 }
7729
7730 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7731 &versionReported);
7732 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7733 {
7734 hddLog(VOS_TRACE_LEVEL_FATAL,
7735 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007736 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007737 break;
7738 }
7739
7740 if ((versionCompiled.major != versionReported.major) ||
7741 (versionCompiled.minor != versionReported.minor) ||
7742 (versionCompiled.version != versionReported.version) ||
7743 (versionCompiled.revision != versionReported.revision))
7744 {
7745 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7746 "Host expected %u.%u.%u.%u\n",
7747 WLAN_MODULE_NAME,
7748 (int)versionReported.major,
7749 (int)versionReported.minor,
7750 (int)versionReported.version,
7751 (int)versionReported.revision,
7752 (int)versionCompiled.major,
7753 (int)versionCompiled.minor,
7754 (int)versionCompiled.version,
7755 (int)versionCompiled.revision);
7756 }
7757 else
7758 {
7759 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7760 WLAN_MODULE_NAME,
7761 (int)versionReported.major,
7762 (int)versionReported.minor,
7763 (int)versionReported.version,
7764 (int)versionReported.revision);
7765 }
7766
7767 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7768 versionString,
7769 sizeof(versionString));
7770 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7771 {
7772 hddLog(VOS_TRACE_LEVEL_FATAL,
7773 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007774 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007775 break;
7776 }
7777
7778 pr_info("%s: WCNSS software version %s\n",
7779 WLAN_MODULE_NAME, versionString);
7780
7781 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7782 versionString,
7783 sizeof(versionString));
7784 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7785 {
7786 hddLog(VOS_TRACE_LEVEL_FATAL,
7787 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007788 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007789 break;
7790 }
7791
7792 pr_info("%s: WCNSS hardware version %s\n",
7793 WLAN_MODULE_NAME, versionString);
7794
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007795 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7796 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007797 send the message only if it the riva is 1.1
7798 minor numbers for different riva branches:
7799 0 -> (1.0)Mainline Build
7800 1 -> (1.1)Mainline Build
7801 2->(1.04) Stability Build
7802 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007803 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007804 ((versionReported.minor>=1) && (versionReported.version>=1)))
7805 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7806 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007807
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007808 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007809 {
7810#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7811 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7812 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7813#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007814 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7815 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7816 {
7817 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7818 }
7819
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007820 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007821 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007822
7823 } while (0);
7824
7825}
7826
7827/**---------------------------------------------------------------------------
7828
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307829 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7830
7831 \param - pHddCtx - Pointer to the hdd context
7832
7833 \return - true if hardware supports 5GHz
7834
7835 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307836boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307837{
7838 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7839 * then hardware support 5Ghz.
7840 */
7841 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7842 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307843 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307844 return true;
7845 }
7846 else
7847 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307849 __func__);
7850 return false;
7851 }
7852}
7853
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307854/**---------------------------------------------------------------------------
7855
7856 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7857 generate function
7858
7859 This is generate the random mac address for WLAN interface
7860
7861 \param - pHddCtx - Pointer to HDD context
7862 idx - Start interface index to get auto
7863 generated mac addr.
7864 mac_addr - Mac address
7865
7866 \return - 0 for success, < 0 for failure
7867
7868 --------------------------------------------------------------------------*/
7869
7870static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
7871 int idx, v_MACADDR_t mac_addr)
7872{
7873 int i;
7874 unsigned int serialno;
7875 serialno = wcnss_get_serial_number();
7876
7877 if (0 != serialno)
7878 {
7879 /* MAC address has 3 bytes of OUI so we have a maximum of 3
7880 bytes of the serial number that can be used to generate
7881 the other 3 bytes of the MAC address. Mask off all but
7882 the lower 3 bytes (this will also make sure we don't
7883 overflow in the next step) */
7884 serialno &= 0x00FFFFFF;
7885
7886 /* we need a unique address for each session */
7887 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
7888
7889 /* autogen other Mac addresses */
7890 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7891 {
7892 /* start with the entire default address */
7893 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
7894 /* then replace the lower 3 bytes */
7895 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
7896 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
7897 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
7898
7899 serialno++;
7900 hddLog(VOS_TRACE_LEVEL_ERROR,
7901 "%s: Derived Mac Addr: "
7902 MAC_ADDRESS_STR, __func__,
7903 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
7904 }
7905
7906 }
7907 else
7908 {
7909 hddLog(LOGE, FL("Failed to Get Serial NO"));
7910 return -1;
7911 }
7912 return 0;
7913}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307914
7915/**---------------------------------------------------------------------------
7916
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05307917 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
7918 completed to flush out the scan results
7919
7920 11d scan is done during driver load and is a passive scan on all
7921 channels supported by the device, 11d scans may find some APs on
7922 frequencies which are forbidden to be used in the regulatory domain
7923 the device is operating in. If these APs are notified to the supplicant
7924 it may try to connect to these APs, thus flush out all the scan results
7925 which are present in SME after 11d scan is done.
7926
7927 \return - eHalStatus
7928
7929 --------------------------------------------------------------------------*/
7930static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
7931 tANI_U32 scanId, eCsrScanStatus status)
7932{
7933 ENTER();
7934
7935 sme_ScanFlushResult(halHandle, 0);
7936
7937 EXIT();
7938
7939 return eHAL_STATUS_SUCCESS;
7940}
7941
7942/**---------------------------------------------------------------------------
7943
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 \brief hdd_wlan_startup() - HDD init function
7945
7946 This is the driver startup code executed once a WLAN device has been detected
7947
7948 \param - dev - Pointer to the underlying device
7949
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007950 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07007951
7952 --------------------------------------------------------------------------*/
7953
7954int hdd_wlan_startup(struct device *dev )
7955{
7956 VOS_STATUS status;
7957 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07007958 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 hdd_context_t *pHddCtx = NULL;
7960 v_CONTEXT_t pVosContext= NULL;
7961#ifdef WLAN_BTAMP_FEATURE
7962 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
7963 WLANBAP_ConfigType btAmpConfig;
7964 hdd_config_t *pConfig;
7965#endif
7966 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307968 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07007969
7970 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 /*
7972 * cfg80211: wiphy allocation
7973 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307974 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007975
7976 if(wiphy == NULL)
7977 {
7978 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007979 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 }
7981
7982 pHddCtx = wiphy_priv(wiphy);
7983
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 //Initialize the adapter context to zeros.
7985 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
7986
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 hdd_prevent_suspend();
7989 pHddCtx->isLoadUnloadInProgress = TRUE;
7990
7991 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
7992
7993 /*Get vos context here bcoz vos_open requires it*/
7994 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
7995
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08007996 if(pVosContext == NULL)
7997 {
7998 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
7999 goto err_free_hdd_context;
8000 }
8001
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 //Save the Global VOSS context in adapter context for future.
8003 pHddCtx->pvosContext = pVosContext;
8004
8005 //Save the adapter context in global context for future.
8006 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8007
Jeff Johnson295189b2012-06-20 16:38:30 -07008008 pHddCtx->parent_dev = dev;
8009
8010 init_completion(&pHddCtx->full_pwr_comp_var);
8011 init_completion(&pHddCtx->standby_comp_var);
8012 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008013 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008014 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308015 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308016 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008017
8018#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008019 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008020#else
8021 init_completion(&pHddCtx->driver_crda_req);
8022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008023
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308024 spin_lock_init(&pHddCtx->schedScan_lock);
8025
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8027
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308028#ifdef FEATURE_WLAN_TDLS
8029 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8030 * invoked by other instances also) to protect the concurrent
8031 * access for the Adapters by TDLS module.
8032 */
8033 mutex_init(&pHddCtx->tdls_lock);
8034#endif
8035
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308036 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 // Load all config first as TL config is needed during vos_open
8038 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8039 if(pHddCtx->cfg_ini == NULL)
8040 {
8041 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8042 goto err_free_hdd_context;
8043 }
8044
8045 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8046
8047 // Read and parse the qcom_cfg.ini file
8048 status = hdd_parse_config_ini( pHddCtx );
8049 if ( VOS_STATUS_SUCCESS != status )
8050 {
8051 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8052 __func__, WLAN_INI_FILE);
8053 goto err_config;
8054 }
Arif Hussaind5218912013-12-05 01:10:55 -08008055#ifdef MEMORY_DEBUG
8056 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8057 vos_mem_init();
8058
8059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8060 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008062
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308063 /* INI has been read, initialise the configuredMcastBcastFilter with
8064 * INI value as this will serve as the default value
8065 */
8066 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8067 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8068 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308069
8070 if (false == hdd_is_5g_supported(pHddCtx))
8071 {
8072 //5Ghz is not supported.
8073 if (1 != pHddCtx->cfg_ini->nBandCapability)
8074 {
8075 hddLog(VOS_TRACE_LEVEL_INFO,
8076 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8077 pHddCtx->cfg_ini->nBandCapability = 1;
8078 }
8079 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308080
8081 /* If SNR Monitoring is enabled, FW has to parse all beacons
8082 * for calcaluting and storing the average SNR, so set Nth beacon
8083 * filter to 1 to enable FW to parse all the beaocons
8084 */
8085 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8086 {
8087 /* The log level is deliberately set to WARN as overriding
8088 * nthBeaconFilter to 1 will increase power cosumption and this
8089 * might just prove helpful to detect the power issue.
8090 */
8091 hddLog(VOS_TRACE_LEVEL_WARN,
8092 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8093 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8094 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308096 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008098 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008100 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8101 {
8102 hddLog(VOS_TRACE_LEVEL_FATAL,
8103 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8104 goto err_config;
8105 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008107
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008108 // Update VOS trace levels based upon the cfg.ini
8109 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8110 pHddCtx->cfg_ini->vosTraceEnableBAP);
8111 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8112 pHddCtx->cfg_ini->vosTraceEnableTL);
8113 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8114 pHddCtx->cfg_ini->vosTraceEnableWDI);
8115 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8116 pHddCtx->cfg_ini->vosTraceEnableHDD);
8117 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8118 pHddCtx->cfg_ini->vosTraceEnableSME);
8119 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8120 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308121 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8122 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008123 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8124 pHddCtx->cfg_ini->vosTraceEnableWDA);
8125 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8126 pHddCtx->cfg_ini->vosTraceEnableSYS);
8127 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8128 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008129 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8130 pHddCtx->cfg_ini->vosTraceEnableSAP);
8131 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8132 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008133
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 // Update WDI trace levels based upon the cfg.ini
8135 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8136 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8137 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8138 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8139 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8140 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8141 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8142 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008143
Jeff Johnson88ba7742013-02-27 14:36:02 -08008144 if (VOS_FTM_MODE == hdd_get_conparam())
8145 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8147 {
8148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8149 goto err_free_hdd_context;
8150 }
8151 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
8152 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008153 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008154
Jeff Johnson88ba7742013-02-27 14:36:02 -08008155 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008156 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8157 {
8158 status = vos_watchdog_open(pVosContext,
8159 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8160
8161 if(!VOS_IS_STATUS_SUCCESS( status ))
8162 {
8163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308164 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 }
8166 }
8167
8168 pHddCtx->isLogpInProgress = FALSE;
8169 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8170
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8172 if(!VOS_IS_STATUS_SUCCESS(status))
8173 {
8174 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 }
8177
Amar Singhala49cbc52013-10-08 18:37:44 -07008178#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008179 /* initialize the NV module. This is required so that
8180 we can initialize the channel information in wiphy
8181 from the NV.bin data. The channel information in
8182 wiphy needs to be initialized before wiphy registration */
8183
8184 status = vos_nv_open();
8185 if (!VOS_IS_STATUS_SUCCESS(status))
8186 {
8187 /* NV module cannot be initialized */
8188 hddLog( VOS_TRACE_LEVEL_FATAL,
8189 "%s: vos_nv_open failed", __func__);
8190 goto err_clkvote;
8191 }
8192
8193 status = vos_init_wiphy_from_nv_bin();
8194 if (!VOS_IS_STATUS_SUCCESS(status))
8195 {
8196 /* NV module cannot be initialized */
8197 hddLog( VOS_TRACE_LEVEL_FATAL,
8198 "%s: vos_init_wiphy failed", __func__);
8199 goto err_vos_nv_close;
8200 }
8201
Amar Singhala49cbc52013-10-08 18:37:44 -07008202#endif
8203
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 status = vos_open( &pVosContext, 0);
8205 if ( !VOS_IS_STATUS_SUCCESS( status ))
8206 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008207 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308208 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 }
8210
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8212
8213 if ( NULL == pHddCtx->hHal )
8214 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008215 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 goto err_vosclose;
8217 }
8218
Mihir Shetee1093ba2014-01-21 20:13:32 +05308219#ifdef CONFIG_ENABLE_LINUX_REG
8220 /* registration of wiphy dev with cfg80211 */
8221 if (0 > wlan_hdd_cfg80211_register(wiphy))
8222 {
8223 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8224 goto err_vosclose;
8225 }
8226
8227 status = wlan_hdd_init_channels(pHddCtx);
8228 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8229 {
8230 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8231 __func__);
8232 goto err_wiphy_unregister;
8233 }
8234#endif
8235
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008236 status = vos_preStart( pHddCtx->pvosContext );
8237 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8238 {
8239 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308240 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008241 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008242
Arif Hussaineaf68602013-12-30 23:10:44 -08008243 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8244 {
8245 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8246 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8247 __func__, enable_dfs_chan_scan);
8248 }
8249 if (0 == enable_11d || 1 == enable_11d)
8250 {
8251 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8253 __func__, enable_11d);
8254 }
8255
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008256 /* Note that the vos_preStart() sequence triggers the cfg download.
8257 The cfg download must occur before we update the SME config
8258 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 status = hdd_set_sme_config( pHddCtx );
8260
8261 if ( VOS_STATUS_SUCCESS != status )
8262 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008263 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308264 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008265 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008266
8267 //Initialize the WMM module
8268 status = hdd_wmm_init(pHddCtx);
8269 if (!VOS_IS_STATUS_SUCCESS(status))
8270 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008271 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308272 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 }
8274
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 /* In the integrated architecture we update the configuration from
8276 the INI file and from NV before vOSS has been started so that
8277 the final contents are available to send down to the cCPU */
8278
8279 // Apply the cfg.ini to cfg.dat
8280 if (FALSE == hdd_update_config_dat(pHddCtx))
8281 {
8282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308283 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 }
8285
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308286 // Get mac addr from platform driver
8287 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8288
8289 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308291 /* Store the mac addr for first interface */
8292 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8293
8294 hddLog(VOS_TRACE_LEVEL_ERROR,
8295 "%s: WLAN Mac Addr: "
8296 MAC_ADDRESS_STR, __func__,
8297 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8298
8299 /* Here, passing Arg2 as 1 because we do not want to change the
8300 last 3 bytes (means non OUI bytes) of first interface mac
8301 addr.
8302 */
8303 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8304 {
8305 hddLog(VOS_TRACE_LEVEL_ERROR,
8306 "%s: Failed to generate wlan interface mac addr "
8307 "using MAC from ini file ", __func__);
8308 }
8309 }
8310 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8311 {
8312 // Apply the NV to cfg.dat
8313 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008314#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8315 /* There was not a valid set of MAC Addresses in NV. See if the
8316 default addresses were modified by the cfg.ini settings. If so,
8317 we'll use them, but if not, we'll autogenerate a set of MAC
8318 addresses based upon the device serial number */
8319
8320 static const v_MACADDR_t default_address =
8321 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008322
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308323 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8324 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008325 {
8326 /* cfg.ini has the default address, invoke autogen logic */
8327
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308328 /* Here, passing Arg2 as 0 because we want to change the
8329 last 3 bytes (means non OUI bytes) of all the interfaces
8330 mac addr.
8331 */
8332 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8333 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308335 hddLog(VOS_TRACE_LEVEL_ERROR,
8336 "%s: Failed to generate wlan interface mac addr "
8337 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8338 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 }
8341 else
8342#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8343 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008344 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 "%s: Invalid MAC address in NV, using MAC from ini file "
8346 MAC_ADDRESS_STR, __func__,
8347 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8348 }
8349 }
8350 {
8351 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308352
8353 /* Set the MAC Address Currently this is used by HAL to
8354 * add self sta. Remove this once self sta is added as
8355 * part of session open.
8356 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8358 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8359 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308360
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 if (!HAL_STATUS_SUCCESS( halStatus ))
8362 {
8363 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8364 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308365 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 }
8367 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008368
8369 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8370 Note: Firmware image will be read and downloaded inside vos_start API */
8371 status = vos_start( pHddCtx->pvosContext );
8372 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8373 {
8374 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308375 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 }
8377
Leo Chang6cec3e22014-01-21 15:33:49 -08008378#ifdef FEATURE_WLAN_CH_AVOID
8379 /* Plug in avoid channel notification callback
8380 * This should happen before ADD_SELF_STA
8381 * FW will send first IND with ADD_SELF_STA REQ from host */
8382 sme_AddChAvoidCallback(pHddCtx->hHal,
8383 hdd_hostapd_ch_avoid_cb);
8384#endif /* FEATURE_WLAN_CH_AVOID */
8385
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008386 /* Exchange capability info between Host and FW and also get versioning info from FW */
8387 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008388
8389 status = hdd_post_voss_start_config( pHddCtx );
8390 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8391 {
8392 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8393 __func__);
8394 goto err_vosstop;
8395 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008396
8397#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308398 wlan_hdd_cfg80211_update_reg_info( wiphy );
8399
8400 /* registration of wiphy dev with cfg80211 */
8401 if (0 > wlan_hdd_cfg80211_register(wiphy))
8402 {
8403 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8404 goto err_vosstop;
8405 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008407
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8409 {
8410 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8411 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8412 }
8413 else
8414 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8416 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8417 if (pAdapter != NULL)
8418 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308419 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308421 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8422 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8423 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008424
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308425 /* Generate the P2P Device Address. This consists of the device's
8426 * primary MAC address with the locally administered bit set.
8427 */
8428 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008429 }
8430 else
8431 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308432 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8433 if (p2p_dev_addr != NULL)
8434 {
8435 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8436 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8437 }
8438 else
8439 {
8440 hddLog(VOS_TRACE_LEVEL_FATAL,
8441 "%s: Failed to allocate mac_address for p2p_device",
8442 __func__);
8443 goto err_close_adapter;
8444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008446
8447 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8448 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8449 if ( NULL == pP2pAdapter )
8450 {
8451 hddLog(VOS_TRACE_LEVEL_FATAL,
8452 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008453 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008454 goto err_close_adapter;
8455 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008456 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008458
8459 if( pAdapter == NULL )
8460 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8462 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008464
Arif Hussain66559122013-11-21 10:11:40 -08008465 if (country_code)
8466 {
8467 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008468 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008469 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8470#ifndef CONFIG_ENABLE_LINUX_REG
8471 hdd_checkandupdate_phymode(pAdapter, country_code);
8472#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008473 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8474 (void *)(tSmeChangeCountryCallback)
8475 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008476 country_code,
8477 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308478 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008479 if (eHAL_STATUS_SUCCESS == ret)
8480 {
Arif Hussaincb607082013-12-20 11:57:42 -08008481 ret = wait_for_completion_interruptible_timeout(
8482 &pAdapter->change_country_code,
8483 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8484
8485 if (0 >= ret)
8486 {
8487 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8488 "%s: SME while setting country code timed out", __func__);
8489 }
Arif Hussain66559122013-11-21 10:11:40 -08008490 }
8491 else
8492 {
Arif Hussaincb607082013-12-20 11:57:42 -08008493 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8494 "%s: SME Change Country code from module param fail ret=%d",
8495 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008496 }
8497 }
8498
Jeff Johnson295189b2012-06-20 16:38:30 -07008499#ifdef WLAN_BTAMP_FEATURE
8500 vStatus = WLANBAP_Open(pVosContext);
8501 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8502 {
8503 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8504 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008505 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008506 }
8507
8508 vStatus = BSL_Init(pVosContext);
8509 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8510 {
8511 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8512 "%s: Failed to Init BSL",__func__);
8513 goto err_bap_close;
8514 }
8515 vStatus = WLANBAP_Start(pVosContext);
8516 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8517 {
8518 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8519 "%s: Failed to start TL",__func__);
8520 goto err_bap_close;
8521 }
8522
8523 pConfig = pHddCtx->cfg_ini;
8524 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8525 status = WLANBAP_SetConfig(&btAmpConfig);
8526
8527#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008528
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008529#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8530 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8531 {
8532 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8533 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8534 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8535 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8536 }
8537#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008538#ifdef FEATURE_WLAN_SCAN_PNO
8539 /*SME must send channel update configuration to RIVA*/
8540 sme_UpdateChannelConfig(pHddCtx->hHal);
8541#endif
8542
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308543 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8544
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 /* Register with platform driver as client for Suspend/Resume */
8546 status = hddRegisterPmOps(pHddCtx);
8547 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8548 {
8549 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8550#ifdef WLAN_BTAMP_FEATURE
8551 goto err_bap_stop;
8552#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008553 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008554#endif //WLAN_BTAMP_FEATURE
8555 }
8556
Yue Ma0d4891e2013-08-06 17:01:45 -07008557 /* Open debugfs interface */
8558 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8559 {
8560 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8561 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008562 }
8563
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 /* Register TM level change handler function to the platform */
8565 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8566 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8567 {
8568 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8569 goto err_unregister_pmops;
8570 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008571
8572 /* register for riva power on lock to platform driver */
8573 if (req_riva_power_on_lock("wlan"))
8574 {
8575 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8576 __func__);
8577 goto err_unregister_pmops;
8578 }
8579
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 // register net device notifier for device change notification
8581 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8582
8583 if(ret < 0)
8584 {
8585 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8586 goto err_free_power_on_lock;
8587 }
8588
8589 //Initialize the nlink service
8590 if(nl_srv_init() != 0)
8591 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308592 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 goto err_reg_netdev;
8594 }
8595
Leo Chang4ce1cc52013-10-21 18:27:15 -07008596#ifdef WLAN_KD_READY_NOTIFIER
8597 pHddCtx->kd_nl_init = 1;
8598#endif /* WLAN_KD_READY_NOTIFIER */
8599
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 //Initialize the BTC service
8601 if(btc_activate_service(pHddCtx) != 0)
8602 {
8603 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8604 goto err_nl_srv;
8605 }
8606
8607#ifdef PTT_SOCK_SVC_ENABLE
8608 //Initialize the PTT service
8609 if(ptt_sock_activate_svc(pHddCtx) != 0)
8610 {
8611 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8612 goto err_nl_srv;
8613 }
8614#endif
8615
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308616#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8617 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8618 {
8619 if(wlan_logging_sock_activate_svc(
8620 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8621 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8622 {
8623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8624 " failed", __func__);
8625 goto err_nl_srv;
8626 }
8627 }
8628#endif
8629
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008631 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008633 /* Action frame registered in one adapter which will
8634 * applicable to all interfaces
8635 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008636 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008638
8639 mutex_init(&pHddCtx->sap_lock);
8640
8641 pHddCtx->isLoadUnloadInProgress = FALSE;
8642
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008643#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008644#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8645 /* Initialize the wake lcok */
8646 wake_lock_init(&pHddCtx->rx_wake_lock,
8647 WAKE_LOCK_SUSPEND,
8648 "qcom_rx_wakelock");
8649#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008650 /* Initialize the wake lcok */
8651 wake_lock_init(&pHddCtx->sap_wake_lock,
8652 WAKE_LOCK_SUSPEND,
8653 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008654#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008655
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008656 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8657 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008658
8659 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8660 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308661#ifndef CONFIG_ENABLE_LINUX_REG
8662 /*updating wiphy so that regulatory user hints can be processed*/
8663 if (wiphy)
8664 {
8665 regulatory_hint(wiphy, "00");
8666 }
8667#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008668 // Initialize the restart logic
8669 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308670
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008671 //Register the traffic monitor timer now
8672 if ( pHddCtx->cfg_ini->dynSplitscan)
8673 {
8674 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8675 VOS_TIMER_TYPE_SW,
8676 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8677 (void *)pHddCtx);
8678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 goto success;
8680
8681err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008682#ifdef WLAN_KD_READY_NOTIFIER
8683 nl_srv_exit(pHddCtx->ptt_pid);
8684#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008686#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008687err_reg_netdev:
8688 unregister_netdevice_notifier(&hdd_netdev_notifier);
8689
8690err_free_power_on_lock:
8691 free_riva_power_on_lock("wlan");
8692
8693err_unregister_pmops:
8694 hddDevTmUnregisterNotifyCallback(pHddCtx);
8695 hddDeregisterPmOps(pHddCtx);
8696
Yue Ma0d4891e2013-08-06 17:01:45 -07008697 hdd_debugfs_exit(pHddCtx);
8698
Jeff Johnson295189b2012-06-20 16:38:30 -07008699#ifdef WLAN_BTAMP_FEATURE
8700err_bap_stop:
8701 WLANBAP_Stop(pVosContext);
8702#endif
8703
8704#ifdef WLAN_BTAMP_FEATURE
8705err_bap_close:
8706 WLANBAP_Close(pVosContext);
8707#endif
8708
Jeff Johnson295189b2012-06-20 16:38:30 -07008709err_close_adapter:
8710 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008711
8712#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308713 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008715
8716err_vosstop:
8717 vos_stop(pVosContext);
8718
Mihir Shetee1093ba2014-01-21 20:13:32 +05308719err_wiphy_unregister:
8720#ifdef CONFIG_ENABLE_LINUX_REG
8721 wiphy_unregister(wiphy);
8722#endif
8723
Amar Singhala49cbc52013-10-08 18:37:44 -07008724err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 status = vos_sched_close( pVosContext );
8726 if (!VOS_IS_STATUS_SUCCESS(status)) {
8727 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8728 "%s: Failed to close VOSS Scheduler", __func__);
8729 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8730 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008731 vos_close(pVosContext );
8732
Amar Singhal0a402232013-10-11 20:57:16 -07008733err_vos_nv_close:
8734
c_hpothue6a36282014-03-19 12:27:38 +05308735#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008736 vos_nv_close();
8737
Jeff Johnson295189b2012-06-20 16:38:30 -07008738err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05308739#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008740 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008741
8742err_wdclose:
8743 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8744 vos_watchdog_close(pVosContext);
8745
Jeff Johnson295189b2012-06-20 16:38:30 -07008746err_config:
8747 kfree(pHddCtx->cfg_ini);
8748 pHddCtx->cfg_ini= NULL;
8749
8750err_free_hdd_context:
8751 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 wiphy_free(wiphy) ;
8753 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 VOS_BUG(1);
8755
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008756 if (hdd_is_ssr_required())
8757 {
8758 /* WDI timeout had happened during load, so SSR is needed here */
8759 subsystem_restart("wcnss");
8760 msleep(5000);
8761 }
8762 hdd_set_ssr_required (VOS_FALSE);
8763
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008764 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008765
8766success:
8767 EXIT();
8768 return 0;
8769}
8770
8771/**---------------------------------------------------------------------------
8772
Jeff Johnson32d95a32012-09-10 13:15:23 -07008773 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008774
Jeff Johnson32d95a32012-09-10 13:15:23 -07008775 This is the driver entry point - called in different timeline depending
8776 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008777
8778 \param - None
8779
8780 \return - 0 for success, non zero for failure
8781
8782 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008783static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008784{
8785 VOS_STATUS status;
8786 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 struct device *dev = NULL;
8788 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008789#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8790 int max_retries = 0;
8791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008792
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308793#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8794 vos_wconn_trace_init();
8795#endif
8796
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 ENTER();
8798
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008799#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008802
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308803 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8805 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8806
8807 //Power Up Libra WLAN card first if not already powered up
8808 status = vos_chipPowerUp(NULL,NULL,NULL);
8809 if (!VOS_IS_STATUS_SUCCESS(status))
8810 {
8811 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8812 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308813#ifdef WLAN_OPEN_SOURCE
8814 wake_lock_destroy(&wlan_wake_lock);
8815#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008816 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008817 }
8818
Jeff Johnson295189b2012-06-20 16:38:30 -07008819#ifdef ANI_BUS_TYPE_PCI
8820
8821 dev = wcnss_wlan_get_device();
8822
8823#endif // ANI_BUS_TYPE_PCI
8824
8825#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008826
8827#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8828 /* wait until WCNSS driver downloads NV */
8829 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8830 msleep(1000);
8831 }
8832 if (max_retries >= 5) {
8833 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308834#ifdef WLAN_OPEN_SOURCE
8835 wake_lock_destroy(&wlan_wake_lock);
8836#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008837 return -ENODEV;
8838 }
8839#endif
8840
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 dev = wcnss_wlan_get_device();
8842#endif // ANI_BUS_TYPE_PLATFORM
8843
8844
8845 do {
8846 if (NULL == dev) {
8847 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8848 ret_status = -1;
8849 break;
8850 }
8851
Jeff Johnson295189b2012-06-20 16:38:30 -07008852#ifdef TIMER_MANAGER
8853 vos_timer_manager_init();
8854#endif
8855
8856 /* Preopen VOSS so that it is ready to start at least SAL */
8857 status = vos_preOpen(&pVosContext);
8858
8859 if (!VOS_IS_STATUS_SUCCESS(status))
8860 {
8861 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8862 ret_status = -1;
8863 break;
8864 }
8865
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008866#ifndef MODULE
8867 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
8868 */
8869 hdd_set_conparam((v_UINT_t)con_mode);
8870#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008871
8872 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008873 if (hdd_wlan_startup(dev))
8874 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008876 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 vos_preClose( &pVosContext );
8878 ret_status = -1;
8879 break;
8880 }
8881
8882 /* Cancel the vote for XO Core ON
8883 * This is done here for safety purposes in case we re-initialize without turning
8884 * it OFF in any error scenario.
8885 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008886 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008888 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8890 {
8891 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008892 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 }
8894 } while (0);
8895
8896 if (0 != ret_status)
8897 {
8898 //Assert Deep sleep signal now to put Libra HW in lowest power state
8899 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
8900 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
8901
8902 //Vote off any PMIC voltage supplies
8903 vos_chipPowerDown(NULL, NULL, NULL);
8904#ifdef TIMER_MANAGER
8905 vos_timer_exit();
8906#endif
8907#ifdef MEMORY_DEBUG
8908 vos_mem_exit();
8909#endif
8910
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008911#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008913#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
8915 }
8916 else
8917 {
8918 //Send WLAN UP indication to Nlink Service
8919 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
8920
8921 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 }
8923
8924 EXIT();
8925
8926 return ret_status;
8927}
8928
Jeff Johnson32d95a32012-09-10 13:15:23 -07008929/**---------------------------------------------------------------------------
8930
8931 \brief hdd_module_init() - Init Function
8932
8933 This is the driver entry point (invoked when module is loaded using insmod)
8934
8935 \param - None
8936
8937 \return - 0 for success, non zero for failure
8938
8939 --------------------------------------------------------------------------*/
8940#ifdef MODULE
8941static int __init hdd_module_init ( void)
8942{
8943 return hdd_driver_init();
8944}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008945#else /* #ifdef MODULE */
8946static int __init hdd_module_init ( void)
8947{
8948 /* Driver initialization is delayed to fwpath_changed_handler */
8949 return 0;
8950}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008951#endif /* #ifdef MODULE */
8952
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
8954/**---------------------------------------------------------------------------
8955
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008956 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008957
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008958 This is the driver exit point (invoked when module is unloaded using rmmod
8959 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07008960
8961 \param - None
8962
8963 \return - None
8964
8965 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008966static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008967{
8968 hdd_context_t *pHddCtx = NULL;
8969 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308970 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008971
8972 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
8973
8974 //Get the global vos context
8975 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8976
8977 if(!pVosContext)
8978 {
8979 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
8980 goto done;
8981 }
8982
8983 //Get the HDD context.
8984 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
8985
8986 if(!pHddCtx)
8987 {
8988 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
8989 }
8990 else
8991 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308992 INIT_COMPLETION(pHddCtx->ssr_comp_var);
8993
8994 if (pHddCtx->isLogpInProgress)
8995 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308997 "%s:SSR in Progress; block rmmod !!!", __func__);
8998 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
8999 msecs_to_jiffies(30000));
9000 if(!rc)
9001 {
9002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9003 "%s:SSR timedout, fatal error", __func__);
9004 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009005 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009007
9008 pHddCtx->isLoadUnloadInProgress = TRUE;
9009 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9010
9011 //Do all the cleanup before deregistering the driver
9012 hdd_wlan_exit(pHddCtx);
9013 }
9014
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 vos_preClose( &pVosContext );
9016
9017#ifdef TIMER_MANAGER
9018 vos_timer_exit();
9019#endif
9020#ifdef MEMORY_DEBUG
9021 vos_mem_exit();
9022#endif
9023
Gopichand Nakkalad0774962013-05-24 11:32:21 +05309024#ifdef WCONN_TRACE_KMSG_LOG_BUFF
9025 vos_wconn_trace_exit();
9026#endif
9027
Jeff Johnson295189b2012-06-20 16:38:30 -07009028done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009029#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009031#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9033}
9034
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009035/**---------------------------------------------------------------------------
9036
9037 \brief hdd_module_exit() - Exit function
9038
9039 This is the driver exit point (invoked when module is unloaded using rmmod)
9040
9041 \param - None
9042
9043 \return - None
9044
9045 --------------------------------------------------------------------------*/
9046static void __exit hdd_module_exit(void)
9047{
9048 hdd_driver_exit();
9049}
9050
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009051#ifdef MODULE
9052static int fwpath_changed_handler(const char *kmessage,
9053 struct kernel_param *kp)
9054{
Jeff Johnson76052702013-04-16 13:55:05 -07009055 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009056}
9057
9058static int con_mode_handler(const char *kmessage,
9059 struct kernel_param *kp)
9060{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009061 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009062}
9063#else /* #ifdef MODULE */
9064/**---------------------------------------------------------------------------
9065
Jeff Johnson76052702013-04-16 13:55:05 -07009066 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009067
Jeff Johnson76052702013-04-16 13:55:05 -07009068 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009069 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009070 - invoked when module parameter fwpath is modified from userspace to signal
9071 initializing the WLAN driver or when con_mode is modified from userspace
9072 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009073
9074 \return - 0 for success, non zero for failure
9075
9076 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009077static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009078{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009079 int ret_status;
9080
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009081 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009082 ret_status = hdd_driver_init();
9083 wlan_hdd_inited = ret_status ? 0 : 1;
9084 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009085 }
9086
9087 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009088
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009089 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009090
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009091 ret_status = hdd_driver_init();
9092 wlan_hdd_inited = ret_status ? 0 : 1;
9093 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009094}
9095
Jeff Johnson295189b2012-06-20 16:38:30 -07009096/**---------------------------------------------------------------------------
9097
Jeff Johnson76052702013-04-16 13:55:05 -07009098 \brief fwpath_changed_handler() - Handler Function
9099
9100 Handle changes to the fwpath parameter
9101
9102 \return - 0 for success, non zero for failure
9103
9104 --------------------------------------------------------------------------*/
9105static int fwpath_changed_handler(const char *kmessage,
9106 struct kernel_param *kp)
9107{
9108 int ret;
9109
9110 ret = param_set_copystring(kmessage, kp);
9111 if (0 == ret)
9112 ret = kickstart_driver();
9113 return ret;
9114}
9115
9116/**---------------------------------------------------------------------------
9117
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009118 \brief con_mode_handler() -
9119
9120 Handler function for module param con_mode when it is changed by userspace
9121 Dynamically linked - do nothing
9122 Statically linked - exit and init driver, as in rmmod and insmod
9123
Jeff Johnson76052702013-04-16 13:55:05 -07009124 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009125
Jeff Johnson76052702013-04-16 13:55:05 -07009126 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009127
9128 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009129static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009130{
Jeff Johnson76052702013-04-16 13:55:05 -07009131 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009132
Jeff Johnson76052702013-04-16 13:55:05 -07009133 ret = param_set_int(kmessage, kp);
9134 if (0 == ret)
9135 ret = kickstart_driver();
9136 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009137}
9138#endif /* #ifdef MODULE */
9139
9140/**---------------------------------------------------------------------------
9141
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 \brief hdd_get_conparam() -
9143
9144 This is the driver exit point (invoked when module is unloaded using rmmod)
9145
9146 \param - None
9147
9148 \return - tVOS_CON_MODE
9149
9150 --------------------------------------------------------------------------*/
9151tVOS_CON_MODE hdd_get_conparam ( void )
9152{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009153#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009155#else
9156 return (tVOS_CON_MODE)curr_con_mode;
9157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009158}
9159void hdd_set_conparam ( v_UINT_t newParam )
9160{
9161 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009162#ifndef MODULE
9163 curr_con_mode = con_mode;
9164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009165}
9166/**---------------------------------------------------------------------------
9167
9168 \brief hdd_softap_sta_deauth() - function
9169
9170 This to take counter measure to handle deauth req from HDD
9171
9172 \param - pAdapter - Pointer to the HDD
9173
9174 \param - enable - boolean value
9175
9176 \return - None
9177
9178 --------------------------------------------------------------------------*/
9179
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009180VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009181{
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009183 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009184
9185 ENTER();
9186
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009187 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9188 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009189
9190 //Ignore request to deauth bcmc station
9191 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009192 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009193
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009194 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009195
9196 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009197 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009198}
9199
9200/**---------------------------------------------------------------------------
9201
9202 \brief hdd_softap_sta_disassoc() - function
9203
9204 This to take counter measure to handle deauth req from HDD
9205
9206 \param - pAdapter - Pointer to the HDD
9207
9208 \param - enable - boolean value
9209
9210 \return - None
9211
9212 --------------------------------------------------------------------------*/
9213
9214void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9215{
9216 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9217
9218 ENTER();
9219
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309220 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009221
9222 //Ignore request to disassoc bcmc station
9223 if( pDestMacAddress[0] & 0x1 )
9224 return;
9225
9226 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9227}
9228
9229void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9230{
9231 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9232
9233 ENTER();
9234
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309235 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009236
9237 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9238}
9239
Jeff Johnson295189b2012-06-20 16:38:30 -07009240/**---------------------------------------------------------------------------
9241 *
9242 * \brief hdd_get__concurrency_mode() -
9243 *
9244 *
9245 * \param - None
9246 *
9247 * \return - CONCURRENCY MODE
9248 *
9249 * --------------------------------------------------------------------------*/
9250tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9251{
9252 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9253 hdd_context_t *pHddCtx;
9254
9255 if (NULL != pVosContext)
9256 {
9257 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9258 if (NULL != pHddCtx)
9259 {
9260 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9261 }
9262 }
9263
9264 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009265 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 return VOS_STA;
9267}
9268
9269/* Decide whether to allow/not the apps power collapse.
9270 * Allow apps power collapse if we are in connected state.
9271 * if not, allow only if we are in IMPS */
9272v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9273{
9274 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009275 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009276 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9278 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9279 hdd_adapter_t *pAdapter = NULL;
9280 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009281 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009282
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9284 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009285
Yathish9f22e662012-12-10 14:21:35 -08009286 concurrent_state = hdd_get_concurrency_mode();
9287
9288#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9289 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9290 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9291 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9292 return TRUE;
9293#endif
9294
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 /*loop through all adapters. TBD fix for Concurrency */
9296 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9297 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9298 {
9299 pAdapter = pAdapterNode->pAdapter;
9300 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9301 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9302 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009303 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009305 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009306 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9307 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009309 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009310 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9311 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 return FALSE;
9313 }
9314 }
9315 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9316 pAdapterNode = pNext;
9317 }
9318 return TRUE;
9319}
9320
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009321/* Decides whether to send suspend notification to Riva
9322 * if any adapter is in BMPS; then it is required */
9323v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9324{
9325 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9326 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9327
9328 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9329 {
9330 return TRUE;
9331 }
9332 return FALSE;
9333}
9334
Jeff Johnson295189b2012-06-20 16:38:30 -07009335void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9336{
9337 switch(mode)
9338 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009339 case VOS_STA_MODE:
9340 case VOS_P2P_CLIENT_MODE:
9341 case VOS_P2P_GO_MODE:
9342 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009343 pHddCtx->concurrency_mode |= (1 << mode);
9344 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 break;
9346 default:
9347 break;
9348
9349 }
9350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9351 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9352}
9353
9354
9355void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9356{
9357 switch(mode)
9358 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009359 case VOS_STA_MODE:
9360 case VOS_P2P_CLIENT_MODE:
9361 case VOS_P2P_GO_MODE:
9362 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 pHddCtx->no_of_sessions[mode]--;
9364 if (!(pHddCtx->no_of_sessions[mode]))
9365 pHddCtx->concurrency_mode &= (~(1 << mode));
9366 break;
9367 default:
9368 break;
9369 }
9370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9371 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9372}
9373
Jeff Johnsone7245742012-09-05 17:12:55 -07009374/**---------------------------------------------------------------------------
9375 *
9376 * \brief wlan_hdd_restart_init
9377 *
9378 * This function initalizes restart timer/flag. An internal function.
9379 *
9380 * \param - pHddCtx
9381 *
9382 * \return - None
9383 *
9384 * --------------------------------------------------------------------------*/
9385
9386static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9387{
9388 /* Initialize */
9389 pHddCtx->hdd_restart_retries = 0;
9390 atomic_set(&pHddCtx->isRestartInProgress, 0);
9391 vos_timer_init(&pHddCtx->hdd_restart_timer,
9392 VOS_TIMER_TYPE_SW,
9393 wlan_hdd_restart_timer_cb,
9394 pHddCtx);
9395}
9396/**---------------------------------------------------------------------------
9397 *
9398 * \brief wlan_hdd_restart_deinit
9399 *
9400 * This function cleans up the resources used. An internal function.
9401 *
9402 * \param - pHddCtx
9403 *
9404 * \return - None
9405 *
9406 * --------------------------------------------------------------------------*/
9407
9408static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9409{
9410
9411 VOS_STATUS vos_status;
9412 /* Block any further calls */
9413 atomic_set(&pHddCtx->isRestartInProgress, 1);
9414 /* Cleanup */
9415 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9416 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309417 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009418 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9419 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309420 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009421
9422}
9423
9424/**---------------------------------------------------------------------------
9425 *
9426 * \brief wlan_hdd_framework_restart
9427 *
9428 * This function uses a cfg80211 API to start a framework initiated WLAN
9429 * driver module unload/load.
9430 *
9431 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9432 *
9433 *
9434 * \param - pHddCtx
9435 *
9436 * \return - VOS_STATUS_SUCCESS: Success
9437 * VOS_STATUS_E_EMPTY: Adapter is Empty
9438 * VOS_STATUS_E_NOMEM: No memory
9439
9440 * --------------------------------------------------------------------------*/
9441
9442static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9443{
9444 VOS_STATUS status = VOS_STATUS_SUCCESS;
9445 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009446 int len = (sizeof (struct ieee80211_mgmt));
9447 struct ieee80211_mgmt *mgmt = NULL;
9448
9449 /* Prepare the DEAUTH managment frame with reason code */
9450 mgmt = kzalloc(len, GFP_KERNEL);
9451 if(mgmt == NULL)
9452 {
9453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9454 "%s: memory allocation failed (%d bytes)", __func__, len);
9455 return VOS_STATUS_E_NOMEM;
9456 }
9457 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009458
9459 /* Iterate over all adapters/devices */
9460 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9461 do
9462 {
9463 if( (status == VOS_STATUS_SUCCESS) &&
9464 pAdapterNode &&
9465 pAdapterNode->pAdapter)
9466 {
9467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9468 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9469 pAdapterNode->pAdapter->dev->name,
9470 pAdapterNode->pAdapter->device_mode,
9471 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009472 /*
9473 * CFG80211 event to restart the driver
9474 *
9475 * 'cfg80211_send_unprot_deauth' sends a
9476 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9477 * of SME(Linux Kernel) state machine.
9478 *
9479 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9480 * the driver.
9481 *
9482 */
9483
9484 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009485 }
9486 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9487 pAdapterNode = pNext;
9488 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9489
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009490
9491 /* Free the allocated management frame */
9492 kfree(mgmt);
9493
Jeff Johnsone7245742012-09-05 17:12:55 -07009494 /* Retry until we unload or reach max count */
9495 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9496 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9497
9498 return status;
9499
9500}
9501/**---------------------------------------------------------------------------
9502 *
9503 * \brief wlan_hdd_restart_timer_cb
9504 *
9505 * Restart timer callback. An internal function.
9506 *
9507 * \param - User data:
9508 *
9509 * \return - None
9510 *
9511 * --------------------------------------------------------------------------*/
9512
9513void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9514{
9515 hdd_context_t *pHddCtx = usrDataForCallback;
9516 wlan_hdd_framework_restart(pHddCtx);
9517 return;
9518
9519}
9520
9521
9522/**---------------------------------------------------------------------------
9523 *
9524 * \brief wlan_hdd_restart_driver
9525 *
9526 * This function sends an event to supplicant to restart the WLAN driver.
9527 *
9528 * This function is called from vos_wlanRestart.
9529 *
9530 * \param - pHddCtx
9531 *
9532 * \return - VOS_STATUS_SUCCESS: Success
9533 * VOS_STATUS_E_EMPTY: Adapter is Empty
9534 * VOS_STATUS_E_ALREADY: Request already in progress
9535
9536 * --------------------------------------------------------------------------*/
9537VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9538{
9539 VOS_STATUS status = VOS_STATUS_SUCCESS;
9540
9541 /* A tight check to make sure reentrancy */
9542 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9543 {
9544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9545 "%s: WLAN restart is already in progress", __func__);
9546
9547 return VOS_STATUS_E_ALREADY;
9548 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009549 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009550#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009551 wcnss_reset_intr();
9552#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009553
Jeff Johnsone7245742012-09-05 17:12:55 -07009554 return status;
9555}
9556
Mihir Shetee1093ba2014-01-21 20:13:32 +05309557/**---------------------------------------------------------------------------
9558 *
9559 * \brief wlan_hdd_init_channels
9560 *
9561 * This function is used to initialize the channel list in CSR
9562 *
9563 * This function is called from hdd_wlan_startup
9564 *
9565 * \param - pHddCtx: HDD context
9566 *
9567 * \return - VOS_STATUS_SUCCESS: Success
9568 * VOS_STATUS_E_FAULT: Failure reported by SME
9569
9570 * --------------------------------------------------------------------------*/
9571static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9572{
9573 eHalStatus status;
9574
9575 status = sme_InitChannels(pHddCtx->hHal);
9576 if (HAL_STATUS_SUCCESS(status))
9577 {
9578 return VOS_STATUS_SUCCESS;
9579 }
9580 else
9581 {
9582 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9583 __func__, status);
9584 return VOS_STATUS_E_FAULT;
9585 }
9586}
9587
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009588/*
9589 * API to find if there is any STA or P2P-Client is connected
9590 */
9591VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9592{
9593 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9594}
Jeff Johnsone7245742012-09-05 17:12:55 -07009595
Jeff Johnson295189b2012-06-20 16:38:30 -07009596//Register the module init/exit functions
9597module_init(hdd_module_init);
9598module_exit(hdd_module_exit);
9599
9600MODULE_LICENSE("Dual BSD/GPL");
9601MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9602MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9603
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009604module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9605 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009606
Jeff Johnson76052702013-04-16 13:55:05 -07009607module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009608 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009609
9610module_param(enable_dfs_chan_scan, int,
9611 S_IRUSR | S_IRGRP | S_IROTH);
9612
9613module_param(enable_11d, int,
9614 S_IRUSR | S_IRGRP | S_IROTH);
9615
9616module_param(country_code, charp,
9617 S_IRUSR | S_IRGRP | S_IROTH);