blob: 28e009af7412f4b662f2df0abbd5469d10a2e220 [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 Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
37 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
38
39 Qualcomm Confidential and Proprietary.
40
41 ========================================================================*/
42
43/**=========================================================================
44
45 EDIT HISTORY FOR FILE
46
47
48 This section contains comments describing changes made to the module.
49 Notice that changes are listed in reverse chronological order.
50
51
52 $Header:$ $DateTime: $ $Author: $
53
54
55 when who what, where, why
56 -------- --- --------------------------------------------------------
57 04/5/09 Shailender Created module.
58 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
59 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
60 ==========================================================================*/
61
62/*--------------------------------------------------------------------------
63 Include Files
64 ------------------------------------------------------------------------*/
65//#include <wlan_qct_driver.h>
66#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <vos_api.h>
68#include <vos_sched.h>
69#include <vos_power.h>
70#include <linux/etherdevice.h>
71#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070072#ifdef ANI_BUS_TYPE_PLATFORM
73#include <linux/wcnss_wlan.h>
74#endif //ANI_BUS_TYPE_PLATFORM
75#ifdef ANI_BUS_TYPE_PCI
76#include "wcnss_wlan.h"
77#endif /* ANI_BUS_TYPE_PCI */
78#include <wlan_hdd_tx_rx.h>
79#include <palTimer.h>
80#include <wniApi.h>
81#include <wlan_nlink_srv.h>
82#include <wlan_btc_svc.h>
83#include <wlan_hdd_cfg.h>
84#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053085#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070086#include <wlan_hdd_wowl.h>
87#include <wlan_hdd_misc.h>
88#include <wlan_hdd_wext.h>
89#ifdef WLAN_BTAMP_FEATURE
90#include <bap_hdd_main.h>
91#include <bapInternal.h>
92#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053093#include "wlan_hdd_trace.h"
94#include "vos_types.h"
95#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include <linux/wireless.h>
97#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053098#include <linux/inetdevice.h>
99#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "wlan_hdd_cfg80211.h"
101#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700103int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include "sapApi.h"
105#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700106#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
108#include <soc/qcom/subsystem_restart.h>
109#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530111#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include <wlan_hdd_hostapd.h>
113#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_hdd_dev_pwr.h"
116#ifdef WLAN_BTAMP_FEATURE
117#include "bap_hdd_misc.h"
118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700120#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800121#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530122#ifdef FEATURE_WLAN_TDLS
123#include "wlan_hdd_tdls.h"
124#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700125#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700126
127#ifdef MODULE
128#define WLAN_MODULE_NAME module_name(THIS_MODULE)
129#else
130#define WLAN_MODULE_NAME "wlan"
131#endif
132
133#ifdef TIMER_MANAGER
134#define TIMER_MANAGER_STR " +TIMER_MANAGER"
135#else
136#define TIMER_MANAGER_STR ""
137#endif
138
139#ifdef MEMORY_DEBUG
140#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
141#else
142#define MEMORY_DEBUG_STR ""
143#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530144#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700145/* the Android framework expects this param even though we don't use it */
146#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700147static char fwpath_buffer[BUF_LEN];
148static struct kparam_string fwpath = {
149 .string = fwpath_buffer,
150 .maxlen = BUF_LEN,
151};
Arif Hussain66559122013-11-21 10:11:40 -0800152
153static char *country_code;
154static int enable_11d = -1;
155static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530156static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800157
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700159static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161
Jeff Johnsone7245742012-09-05 17:12:55 -0700162/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800163 * spinlock for synchronizing asynchronous request/response
164 * (full description of use in wlan_hdd_main.h)
165 */
166DEFINE_SPINLOCK(hdd_context_lock);
167
168/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700169 * The rate at which the driver sends RESTART event to supplicant
170 * once the function 'vos_wlanRestart()' is called
171 *
172 */
173#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
174#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700175
176/*
177 * Size of Driver command strings from upper layer
178 */
179#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
180#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
181
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800182#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700183#define TID_MIN_VALUE 0
184#define TID_MAX_VALUE 15
185static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
186 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800187static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
188 tCsrEseBeaconReq *pEseBcnReq);
189#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530191static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530192/*
193 * Maximum buffer size used for returning the data back to user space
194 */
195#define WLAN_MAX_BUF_SIZE 1024
196#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700197
c_hpothu92367912014-05-01 15:18:17 +0530198//wait time for beacon miss rate.
199#define BCN_MISS_RATE_TIME 500
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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800223#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800224void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
225static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700226static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
228 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700229static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
230 tANI_U8 *pTargetApBssid,
231 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800232#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Jeff Johnson295189b2012-06-20 16:38:30 -0700255static int hdd_netdev_notifier_call(struct notifier_block * nb,
256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
356struct notifier_block hdd_netdev_notifier = {
357 .notifier_call = hdd_netdev_notifier_call,
358};
359
360/*---------------------------------------------------------------------------
361 * Function definitions
362 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700363void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
364void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700366static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700367#ifndef MODULE
368/* current con_mode - used only for statically linked driver
369 * con_mode is changed by userspace to indicate a mode change which will
370 * result in calling the module exit and init functions. The module
371 * exit function will clean up based on the value of con_mode prior to it
372 * being changed by userspace. So curr_con_mode records the current con_mode
373 * for exit when con_mode becomes the next mode for init
374 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700375static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700376#endif
377
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800378/**---------------------------------------------------------------------------
379
380 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
381
382 Called immediately after the cfg.ini is read in order to configure
383 the desired trace levels.
384
385 \param - moduleId - module whose trace level is being configured
386 \param - bitmask - bitmask of log levels to be enabled
387
388 \return - void
389
390 --------------------------------------------------------------------------*/
391static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
392{
393 wpt_tracelevel level;
394
395 /* if the bitmask is the default value, then a bitmask was not
396 specified in cfg.ini, so leave the logging level alone (it
397 will remain at the "compiled in" default value) */
398 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
399 {
400 return;
401 }
402
403 /* a mask was specified. start by disabling all logging */
404 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
405
406 /* now cycle through the bitmask until all "set" bits are serviced */
407 level = VOS_TRACE_LEVEL_FATAL;
408 while (0 != bitmask)
409 {
410 if (bitmask & 1)
411 {
412 vos_trace_setValue(moduleId, level, 1);
413 }
414 level++;
415 bitmask >>= 1;
416 }
417}
418
419
Jeff Johnson295189b2012-06-20 16:38:30 -0700420/**---------------------------------------------------------------------------
421
422 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
423
424 Called immediately after the cfg.ini is read in order to configure
425 the desired trace levels in the WDI.
426
427 \param - moduleId - module whose trace level is being configured
428 \param - bitmask - bitmask of log levels to be enabled
429
430 \return - void
431
432 --------------------------------------------------------------------------*/
433static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
434{
435 wpt_tracelevel level;
436
437 /* if the bitmask is the default value, then a bitmask was not
438 specified in cfg.ini, so leave the logging level alone (it
439 will remain at the "compiled in" default value) */
440 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
441 {
442 return;
443 }
444
445 /* a mask was specified. start by disabling all logging */
446 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
447
448 /* now cycle through the bitmask until all "set" bits are serviced */
449 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
450 while (0 != bitmask)
451 {
452 if (bitmask & 1)
453 {
454 wpalTraceSetLevel(moduleId, level, 1);
455 }
456 level++;
457 bitmask >>= 1;
458 }
459}
Jeff Johnson295189b2012-06-20 16:38:30 -0700460
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530461/*
462 * FUNCTION: wlan_hdd_validate_context
463 * This function is used to check the HDD context
464 */
465int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
466{
467 ENTER();
468
469 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
470 {
471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
472 "%s: HDD context is Null", __func__);
473 return -ENODEV;
474 }
475
476 if (pHddCtx->isLogpInProgress)
477 {
478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
479 "%s: LOGP in Progress. Ignore!!!", __func__);
480 return -EAGAIN;
481 }
482
Mihir Shete18156292014-03-11 15:38:30 +0530483 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530484 {
485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
486 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
487 return -EAGAIN;
488 }
489 return 0;
490}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700491#ifdef CONFIG_ENABLE_LINUX_REG
492void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
493{
494 hdd_adapter_t *pAdapter = NULL;
495 hdd_station_ctx_t *pHddStaCtx = NULL;
496 eCsrPhyMode phyMode;
497 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700499 if (NULL == pHddCtx)
500 {
501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
502 "HDD Context is null !!");
503 return ;
504 }
505
506 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
507 if (NULL == pAdapter)
508 {
509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
510 "pAdapter is null !!");
511 return ;
512 }
513
514 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
515 if (NULL == pHddStaCtx)
516 {
517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
518 "pHddStaCtx is null !!");
519 return ;
520 }
521
522 cfg_param = pHddCtx->cfg_ini;
523 if (NULL == cfg_param)
524 {
525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
526 "cfg_params not available !!");
527 return ;
528 }
529
530 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
531
532 if (!pHddCtx->isVHT80Allowed)
533 {
534 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
535 (eCSR_DOT11_MODE_11ac == phyMode) ||
536 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
537 {
538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
539 "Setting phymode to 11n!!");
540 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
541 }
542 }
543 else
544 {
545 /*New country Supports 11ac as well resetting value back from .ini*/
546 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
547 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
548 return ;
549 }
550
551 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
552 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
553 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
554 {
555 VOS_STATUS vosStatus;
556
557 // need to issue a disconnect to CSR.
558 INIT_COMPLETION(pAdapter->disconnect_comp_var);
559 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
560 pAdapter->sessionId,
561 eCSR_DISCONNECT_REASON_UNSPECIFIED );
562
563 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530564 {
565 long ret;
566
567 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700568 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530569 if (0 >= ret)
570 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
571 ret);
572 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700573
574 }
575}
576#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530577void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
578{
579 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
580 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
581 hdd_config_t *cfg_param;
582 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530583 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530584
585 if (NULL == pHddCtx)
586 {
587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
588 "HDD Context is null !!");
589 return ;
590 }
591
592 cfg_param = pHddCtx->cfg_ini;
593
594 if (NULL == cfg_param)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
597 "cfg_params not available !!");
598 return ;
599 }
600
601 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
602
603 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
604 {
605 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
606 (eCSR_DOT11_MODE_11ac == phyMode) ||
607 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
610 "Setting phymode to 11n!!");
611 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
612 }
613 }
614 else
615 {
616 /*New country Supports 11ac as well resetting value back from .ini*/
617 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
618 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
619 return ;
620 }
621
622 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
623 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
624 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
625 {
626 VOS_STATUS vosStatus;
627
628 // need to issue a disconnect to CSR.
629 INIT_COMPLETION(pAdapter->disconnect_comp_var);
630 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
631 pAdapter->sessionId,
632 eCSR_DISCONNECT_REASON_UNSPECIFIED );
633
634 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530635 {
636 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530637 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530638 if (ret <= 0)
639 {
640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
641 "wait on disconnect_comp_var is failed %ld", ret);
642 }
643 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530644
645 }
646}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700647#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530648
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700649void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
650{
651 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
652 hdd_config_t *cfg_param;
653
654 if (NULL == pHddCtx)
655 {
656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
657 "HDD Context is null !!");
658 return ;
659 }
660
661 cfg_param = pHddCtx->cfg_ini;
662
663 if (NULL == cfg_param)
664 {
665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
666 "cfg_params not available !!");
667 return ;
668 }
669
670 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
671 {
672 /*New country doesn't support DFS */
673 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
674 }
675 else
676 {
677 /*New country Supports DFS as well resetting value back from .ini*/
678 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
679 }
680
681}
682
Rajeev79dbe4c2013-10-05 11:03:42 +0530683#ifdef FEATURE_WLAN_BATCH_SCAN
684
685/**---------------------------------------------------------------------------
686
687 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
688 input string
689
690 This function extracts assigned integer from string in below format:
691 "STRING=10" : extracts integer 10 from this string
692
693 \param - pInPtr Pointer to input string
694 \param - base Base for string to int conversion(10 for decimal 16 for hex)
695 \param - pOutPtr Pointer to variable in which extracted integer needs to be
696 assigned
697 \param - pLastArg to tell whether it is last arguement in input string or
698 not
699
700 \return - NULL for failure cases
701 pointer to next arguement in input string for success cases
702 --------------------------------------------------------------------------*/
703static tANI_U8 *
704hdd_extract_assigned_int_from_str
705(
706 tANI_U8 *pInPtr,
707 tANI_U8 base,
708 tANI_U32 *pOutPtr,
709 tANI_U8 *pLastArg
710)
711{
712 int tempInt;
713 int v = 0;
714 char buf[32];
715 int val = 0;
716 *pLastArg = FALSE;
717
718 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
719 if (NULL == pInPtr)
720 {
721 return NULL;
722 }
723
724 pInPtr++;
725
726 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
727
728 val = sscanf(pInPtr, "%32s ", buf);
729 if (val < 0 && val > strlen(pInPtr))
730 {
731 return NULL;
732 }
733 pInPtr += val;
734 v = kstrtos32(buf, base, &tempInt);
735 if (v < 0)
736 {
737 return NULL;
738 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800739 if (tempInt < 0)
740 {
741 tempInt = 0;
742 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530743 *pOutPtr = tempInt;
744
745 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
746 if (NULL == pInPtr)
747 {
748 *pLastArg = TRUE;
749 return NULL;
750 }
751 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
752
753 return pInPtr;
754}
755
756/**---------------------------------------------------------------------------
757
758 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
759 input string
760
761 This function extracts assigned character from string in below format:
762 "STRING=A" : extracts char 'A' from this string
763
764 \param - pInPtr Pointer to input string
765 \param - pOutPtr Pointer to variable in which extracted char needs to be
766 assigned
767 \param - pLastArg to tell whether it is last arguement in input string or
768 not
769
770 \return - NULL for failure cases
771 pointer to next arguement in input string for success cases
772 --------------------------------------------------------------------------*/
773static tANI_U8 *
774hdd_extract_assigned_char_from_str
775(
776 tANI_U8 *pInPtr,
777 tANI_U8 *pOutPtr,
778 tANI_U8 *pLastArg
779)
780{
781 *pLastArg = FALSE;
782
783 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
784 if (NULL == pInPtr)
785 {
786 return NULL;
787 }
788
789 pInPtr++;
790
791 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
792
793 *pOutPtr = *pInPtr;
794
795 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
796 if (NULL == pInPtr)
797 {
798 *pLastArg = TRUE;
799 return NULL;
800 }
801 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
802
803 return pInPtr;
804}
805
806
807/**---------------------------------------------------------------------------
808
809 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
810
811 This function parses set batch scan command in below format:
812 WLS_BATCHING_SET <space> followed by below arguements
813 "SCANFREQ=XX" : Optional defaults to 30 sec
814 "MSCAN=XX" : Required number of scans to attempt to batch
815 "BESTN=XX" : Best Network (RSSI) defaults to 16
816 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
817 A. implies only 5 GHz , B. implies only 2.4GHz
818 "RTT=X" : optional defaults to 0
819 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
820 error
821
822 For example input commands:
823 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
824 translated into set batch scan with following parameters:
825 a) Frequence 60 seconds
826 b) Batch 10 scans together
827 c) Best RSSI to be 20
828 d) 5GHz band only
829 e) RTT is equal to 0
830
831 \param - pValue Pointer to input channel list
832 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
833
834 \return - 0 for success non-zero for failure
835
836 --------------------------------------------------------------------------*/
837static int
838hdd_parse_set_batchscan_command
839(
840 tANI_U8 *pValue,
841 tSirSetBatchScanReq *pHddSetBatchScanReq
842)
843{
844 tANI_U8 *inPtr = pValue;
845 tANI_U8 val = 0;
846 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800847 tANI_U32 nScanFreq;
848 tANI_U32 nMscan;
849 tANI_U32 nBestN;
850 tANI_U8 ucRfBand;
851 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800852 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530853
854 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800855 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
856 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
857 nRtt = 0;
858 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530859
860 /*go to space after WLS_BATCHING_SET command*/
861 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
862 /*no argument after the command*/
863 if (NULL == inPtr)
864 {
865 return -EINVAL;
866 }
867
868 /*no space after the command*/
869 else if (SPACE_ASCII_VALUE != *inPtr)
870 {
871 return -EINVAL;
872 }
873
874 /*removing empty spaces*/
875 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
876
877 /*no argument followed by spaces*/
878 if ('\0' == *inPtr)
879 {
880 return -EINVAL;
881 }
882
883 /*check and parse SCANFREQ*/
884 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
885 {
886 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800887 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800888
Rajeev Kumarc933d982013-11-18 20:04:20 -0800889 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800890 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800891 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800892 }
893
Rajeev79dbe4c2013-10-05 11:03:42 +0530894 if ( (NULL == inPtr) || (TRUE == lastArg))
895 {
896 return -EINVAL;
897 }
898 }
899
900 /*check and parse MSCAN*/
901 if ((strncmp(inPtr, "MSCAN", 5) == 0))
902 {
903 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800904 &nMscan, &lastArg);
905
906 if (0 == nMscan)
907 {
908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
909 "invalid MSCAN=%d", nMscan);
910 return -EINVAL;
911 }
912
Rajeev79dbe4c2013-10-05 11:03:42 +0530913 if (TRUE == lastArg)
914 {
915 goto done;
916 }
917 else if (NULL == inPtr)
918 {
919 return -EINVAL;
920 }
921 }
922 else
923 {
924 return -EINVAL;
925 }
926
927 /*check and parse BESTN*/
928 if ((strncmp(inPtr, "BESTN", 5) == 0))
929 {
930 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932
Rajeev Kumarc933d982013-11-18 20:04:20 -0800933 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800935 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800936 }
937
Rajeev79dbe4c2013-10-05 11:03:42 +0530938 if (TRUE == lastArg)
939 {
940 goto done;
941 }
942 else if (NULL == inPtr)
943 {
944 return -EINVAL;
945 }
946 }
947
948 /*check and parse CHANNEL*/
949 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
950 {
951 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800952
Rajeev79dbe4c2013-10-05 11:03:42 +0530953 if (('A' == val) || ('a' == val))
954 {
c_hpothuebf89732014-02-25 13:00:24 +0530955 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530956 }
957 else if (('B' == val) || ('b' == val))
958 {
c_hpothuebf89732014-02-25 13:00:24 +0530959 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530960 }
961 else
962 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800963 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
964 }
965
966 if (TRUE == lastArg)
967 {
968 goto done;
969 }
970 else if (NULL == inPtr)
971 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530972 return -EINVAL;
973 }
974 }
975
976 /*check and parse RTT*/
977 if ((strncmp(inPtr, "RTT", 3) == 0))
978 {
979 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800980 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530981 if (TRUE == lastArg)
982 {
983 goto done;
984 }
985 if (NULL == inPtr)
986 {
987 return -EINVAL;
988 }
989 }
990
991
992done:
993
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800994 pHddSetBatchScanReq->scanFrequency = nScanFreq;
995 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
996 pHddSetBatchScanReq->bestNetwork = nBestN;
997 pHddSetBatchScanReq->rfBand = ucRfBand;
998 pHddSetBatchScanReq->rtt = nRtt;
999
Rajeev79dbe4c2013-10-05 11:03:42 +05301000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1001 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1002 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1003 pHddSetBatchScanReq->scanFrequency,
1004 pHddSetBatchScanReq->numberOfScansToBatch,
1005 pHddSetBatchScanReq->bestNetwork,
1006 pHddSetBatchScanReq->rfBand,
1007 pHddSetBatchScanReq->rtt);
1008
1009 return 0;
1010}/*End of hdd_parse_set_batchscan_command*/
1011
1012/**---------------------------------------------------------------------------
1013
1014 \brief hdd_set_batch_scan_req_callback () - This function is called after
1015 receiving set batch scan response from FW and it saves set batch scan
1016 response data FW to HDD context and sets the completion event on
1017 which hdd_ioctl is waiting
1018
1019 \param - callbackContext Pointer to HDD adapter
1020 \param - pRsp Pointer to set batch scan response data received from FW
1021
1022 \return - nothing
1023
1024 --------------------------------------------------------------------------*/
1025static void hdd_set_batch_scan_req_callback
1026(
1027 void *callbackContext,
1028 tSirSetBatchScanRsp *pRsp
1029)
1030{
1031 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1032 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1033
1034 /*sanity check*/
1035 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1036 {
1037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1038 "%s: Invalid pAdapter magic", __func__);
1039 VOS_ASSERT(0);
1040 return;
1041 }
1042 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1043
1044 /*save set batch scan response*/
1045 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1046
1047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1048 "Received set batch scan rsp from FW with nScansToBatch=%d",
1049 pHddSetBatchScanRsp->nScansToBatch);
1050
1051 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1052 complete(&pAdapter->hdd_set_batch_scan_req_var);
1053
1054 return;
1055}/*End of hdd_set_batch_scan_req_callback*/
1056
1057
1058/**---------------------------------------------------------------------------
1059
1060 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1061 info in hdd batch scan response queue
1062
1063 \param - pAdapter Pointer to hdd adapter
1064 \param - pAPMetaInfo Pointer to access point meta info
1065 \param - scanId scan ID of batch scan response
1066 \param - isLastAp tells whether AP is last AP in batch scan response or not
1067
1068 \return - nothing
1069
1070 --------------------------------------------------------------------------*/
1071static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1072 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1073{
1074 tHddBatchScanRsp *pHead;
1075 tHddBatchScanRsp *pNode;
1076 tHddBatchScanRsp *pPrev;
1077 tHddBatchScanRsp *pTemp;
1078 tANI_U8 ssidLen;
1079
1080 /*head of hdd batch scan response queue*/
1081 pHead = pAdapter->pBatchScanRsp;
1082
1083 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1084 if (NULL == pNode)
1085 {
1086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1087 "%s: Could not allocate memory", __func__);
1088 VOS_ASSERT(0);
1089 return;
1090 }
1091
1092 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1093 sizeof(pNode->ApInfo.bssid));
1094 ssidLen = strlen(pApMetaInfo->ssid);
1095 if (SIR_MAX_SSID_SIZE < ssidLen)
1096 {
1097 /*invalid scan result*/
1098 vos_mem_free(pNode);
1099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1101 return;
1102 }
1103 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1104 /*null terminate ssid*/
1105 pNode->ApInfo.ssid[ssidLen] = '\0';
1106 pNode->ApInfo.ch = pApMetaInfo->ch;
1107 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1108 pNode->ApInfo.age = pApMetaInfo->timestamp;
1109 pNode->ApInfo.batchId = scanId;
1110 pNode->ApInfo.isLastAp = isLastAp;
1111
1112 pNode->pNext = NULL;
1113 if (NULL == pHead)
1114 {
1115 pAdapter->pBatchScanRsp = pNode;
1116 }
1117 else
1118 {
1119 pTemp = pHead;
1120 while (NULL != pTemp)
1121 {
1122 pPrev = pTemp;
1123 pTemp = pTemp->pNext;
1124 }
1125 pPrev->pNext = pNode;
1126 }
1127
1128 return;
1129}/*End of hdd_populate_batch_scan_rsp_queue*/
1130
1131/**---------------------------------------------------------------------------
1132
1133 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1134 receiving batch scan response indication from FW. It saves get batch scan
1135 response data in HDD batch scan response queue. This callback sets the
1136 completion event on which hdd_ioctl is waiting only after getting complete
1137 batch scan response data from FW
1138
1139 \param - callbackContext Pointer to HDD adapter
1140 \param - pRsp Pointer to get batch scan response data received from FW
1141
1142 \return - nothing
1143
1144 --------------------------------------------------------------------------*/
1145static void hdd_batch_scan_result_ind_callback
1146(
1147 void *callbackContext,
1148 void *pRsp
1149)
1150{
1151 v_BOOL_t isLastAp;
1152 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001153 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301154 tANI_U32 numberScanList;
1155 tANI_U32 nextScanListOffset;
1156 tANI_U32 nextApMetaInfoOffset;
1157 hdd_adapter_t* pAdapter;
1158 tpSirBatchScanList pScanList;
1159 tpSirBatchScanNetworkInfo pApMetaInfo;
1160 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1161 tSirSetBatchScanReq *pReq;
1162
1163 pAdapter = (hdd_adapter_t *)callbackContext;
1164 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001165 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301166 {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1168 "%s: Invalid pAdapter magic", __func__);
1169 VOS_ASSERT(0);
1170 return;
1171 }
1172
1173 /*initialize locals*/
1174 pReq = &pAdapter->hddSetBatchScanReq;
1175 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1176 isLastAp = FALSE;
1177 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001178 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301179 numberScanList = 0;
1180 nextScanListOffset = 0;
1181 nextApMetaInfoOffset = 0;
1182 pScanList = NULL;
1183 pApMetaInfo = NULL;
1184
1185 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1186 {
1187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1188 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1189 isLastAp = TRUE;
1190 goto done;
1191 }
1192
1193 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1195 "Batch scan rsp: numberScalList %d", numberScanList);
1196
1197 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1198 {
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1200 "%s: numberScanList %d", __func__, numberScanList);
1201 isLastAp = TRUE;
1202 goto done;
1203 }
1204
1205 while (numberScanList)
1206 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001207 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301208 nextScanListOffset);
1209 if (NULL == pScanList)
1210 {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1212 "%s: pScanList is %p", __func__, pScanList);
1213 isLastAp = TRUE;
1214 goto done;
1215 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001216 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001218 "Batch scan rsp: numApMetaInfo %d scanId %d",
1219 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301220
1221 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1222 {
1223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1224 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1225 isLastAp = TRUE;
1226 goto done;
1227 }
1228
Rajeev Kumarce651e42013-10-21 18:57:15 -07001229 /*Initialize next AP meta info offset for next scan list*/
1230 nextApMetaInfoOffset = 0;
1231
Rajeev79dbe4c2013-10-05 11:03:42 +05301232 while (numApMetaInfo)
1233 {
1234 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1235 nextApMetaInfoOffset);
1236 if (NULL == pApMetaInfo)
1237 {
1238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1239 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1240 isLastAp = TRUE;
1241 goto done;
1242 }
1243 /*calculate AP age*/
1244 pApMetaInfo->timestamp =
1245 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1246
1247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001248 "%s: bssId "MAC_ADDRESS_STR
1249 " ch %d rssi %d timestamp %d", __func__,
1250 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1251 pApMetaInfo->ch, pApMetaInfo->rssi,
1252 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301253
1254 /*mark last AP in batch scan response*/
1255 if ((TRUE == pBatchScanRsp->isLastResult) &&
1256 (1 == numberScanList) && (1 == numApMetaInfo))
1257 {
1258 isLastAp = TRUE;
1259 }
1260
1261 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1262 /*store batch scan repsonse in hdd queue*/
1263 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1264 pScanList->scanId, isLastAp);
1265 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1266
1267 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1268 numApMetaInfo--;
1269 }
1270
Rajeev Kumarce651e42013-10-21 18:57:15 -07001271 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1272 + (sizeof(tSirBatchScanNetworkInfo)
1273 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301274 numberScanList--;
1275 }
1276
1277done:
1278
1279 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1280 requested from hdd_ioctl*/
1281 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1282 (TRUE == isLastAp))
1283 {
1284 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1285 complete(&pAdapter->hdd_get_batch_scan_req_var);
1286 }
1287
1288 return;
1289}/*End of hdd_batch_scan_result_ind_callback*/
1290
1291/**---------------------------------------------------------------------------
1292
1293 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1294 response as per batch scan FR request format by putting proper markers
1295
1296 \param - pDest pointer to destination buffer
1297 \param - cur_len current length
1298 \param - tot_len total remaining size which can be written to user space
1299 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1300 \param - pAdapter Pointer to HDD adapter
1301
1302 \return - ret no of characters written
1303
1304 --------------------------------------------------------------------------*/
1305static tANI_U32
1306hdd_format_batch_scan_rsp
1307(
1308 tANI_U8 *pDest,
1309 tANI_U32 cur_len,
1310 tANI_U32 tot_len,
1311 tHddBatchScanRsp *pApMetaInfo,
1312 hdd_adapter_t* pAdapter
1313)
1314{
1315 tANI_U32 ret = 0;
1316 tANI_U32 rem_len = 0;
1317 tANI_U8 temp_len = 0;
1318 tANI_U8 temp_total_len = 0;
1319 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1320 tANI_U8 *pTemp = temp;
1321
1322 /*Batch scan reponse needs to be returned to user space in
1323 following format:
1324 "scancount=X\n" where X is the number of scans in current batch
1325 batch
1326 "trunc\n" optional present if current scan truncated
1327 "bssid=XX:XX:XX:XX:XX:XX\n"
1328 "ssid=XXXX\n"
1329 "freq=X\n" frequency in Mhz
1330 "level=XX\n"
1331 "age=X\n" ms
1332 "dist=X\n" cm (-1 if not available)
1333 "errror=X\n" (-1if not available)
1334 "====\n" (end of ap marker)
1335 "####\n" (end of scan marker)
1336 "----\n" (end of results)*/
1337 /*send scan result in above format to user space based on
1338 available length*/
1339 /*The GET response may have more data than the driver can return in its
1340 buffer. In that case the buffer should be filled to the nearest complete
1341 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1342 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1343 The final buffer should end with "----\n"*/
1344
1345 /*sanity*/
1346 if (cur_len > tot_len)
1347 {
1348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1349 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1350 return 0;
1351 }
1352 else
1353 {
1354 rem_len = (tot_len - cur_len);
1355 }
1356
1357 /*end scan marker*/
1358 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1359 {
1360 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1361 pTemp += temp_len;
1362 temp_total_len += temp_len;
1363 }
1364
1365 /*bssid*/
1366 temp_len = snprintf(pTemp, sizeof(temp),
1367 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1368 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1369 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1370 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1371 pTemp += temp_len;
1372 temp_total_len += temp_len;
1373
1374 /*ssid*/
1375 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1376 pApMetaInfo->ApInfo.ssid);
1377 pTemp += temp_len;
1378 temp_total_len += temp_len;
1379
1380 /*freq*/
1381 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001382 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301383 pTemp += temp_len;
1384 temp_total_len += temp_len;
1385
1386 /*level*/
1387 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1388 pApMetaInfo->ApInfo.rssi);
1389 pTemp += temp_len;
1390 temp_total_len += temp_len;
1391
1392 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001393 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301394 pApMetaInfo->ApInfo.age);
1395 pTemp += temp_len;
1396 temp_total_len += temp_len;
1397
1398 /*dist*/
1399 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1400 pTemp += temp_len;
1401 temp_total_len += temp_len;
1402
1403 /*error*/
1404 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1405 pTemp += temp_len;
1406 temp_total_len += temp_len;
1407
1408 /*end AP marker*/
1409 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1410 pTemp += temp_len;
1411 temp_total_len += temp_len;
1412
1413 /*last AP in batch scan response*/
1414 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1415 {
1416 /*end scan marker*/
1417 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1418 pTemp += temp_len;
1419 temp_total_len += temp_len;
1420
1421 /*end batch scan result marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001425
Rajeev79dbe4c2013-10-05 11:03:42 +05301426 }
1427
1428 if (temp_total_len < rem_len)
1429 {
1430 ret = temp_total_len + 1;
1431 strlcpy(pDest, temp, ret);
1432 pAdapter->isTruncated = FALSE;
1433 }
1434 else
1435 {
1436 pAdapter->isTruncated = TRUE;
1437 if (rem_len >= strlen("%%%%"))
1438 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001439 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301440 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001441 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301442 {
1443 ret = 0;
1444 }
1445 }
1446
1447 return ret;
1448
1449}/*End of hdd_format_batch_scan_rsp*/
1450
1451/**---------------------------------------------------------------------------
1452
1453 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1454 buffer starting with head of hdd batch scan response queue
1455
1456 \param - pAdapter Pointer to HDD adapter
1457 \param - pDest Pointer to user data buffer
1458 \param - cur_len current offset in user buffer
1459 \param - rem_len remaining no of bytes in user buffer
1460
1461 \return - number of bytes written in user buffer
1462
1463 --------------------------------------------------------------------------*/
1464
1465tANI_U32 hdd_populate_user_batch_scan_rsp
1466(
1467 hdd_adapter_t* pAdapter,
1468 tANI_U8 *pDest,
1469 tANI_U32 cur_len,
1470 tANI_U32 rem_len
1471)
1472{
1473 tHddBatchScanRsp *pHead;
1474 tHddBatchScanRsp *pPrev;
1475 tANI_U32 len;
1476
Rajeev79dbe4c2013-10-05 11:03:42 +05301477 pAdapter->isTruncated = FALSE;
1478
1479 /*head of hdd batch scan response queue*/
1480 pHead = pAdapter->pBatchScanRsp;
1481 while (pHead)
1482 {
1483 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1484 pAdapter);
1485 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001486 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301487 cur_len += len;
1488 if(TRUE == pAdapter->isTruncated)
1489 {
1490 /*result is truncated return rest of scan rsp in next req*/
1491 cur_len = rem_len;
1492 break;
1493 }
1494 pPrev = pHead;
1495 pHead = pHead->pNext;
1496 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001497 if (TRUE == pPrev->ApInfo.isLastAp)
1498 {
1499 pAdapter->prev_batch_id = 0;
1500 }
1501 else
1502 {
1503 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1504 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301505 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001506 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301507 }
1508
1509 return cur_len;
1510}/*End of hdd_populate_user_batch_scan_rsp*/
1511
1512/**---------------------------------------------------------------------------
1513
1514 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1515 scan response data from HDD queue to user space
1516 It does following in detail:
1517 a) if HDD has enough data in its queue then it 1st copies data to user
1518 space and then send get batch scan indication message to FW. In this
1519 case it does not wait on any event and batch scan response data will
1520 be populated in HDD response queue in MC thread context after receiving
1521 indication from FW
1522 b) else send get batch scan indication message to FW and wait on an event
1523 which will be set once HDD receives complete batch scan response from
1524 FW and then this function returns batch scan response to user space
1525
1526 \param - pAdapter Pointer to HDD adapter
1527 \param - pPrivData Pointer to priv_data
1528
1529 \return - 0 for success -EFAULT for failure
1530
1531 --------------------------------------------------------------------------*/
1532
1533int hdd_return_batch_scan_rsp_to_user
1534(
1535 hdd_adapter_t* pAdapter,
1536 hdd_priv_data_t *pPrivData,
1537 tANI_U8 *command
1538)
1539{
1540 tANI_U8 *pDest;
1541 tANI_U32 count = 0;
1542 tANI_U32 len = 0;
1543 tANI_U32 cur_len = 0;
1544 tANI_U32 rem_len = 0;
1545 eHalStatus halStatus;
1546 unsigned long rc;
1547 tSirTriggerBatchScanResultInd *pReq;
1548
1549 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1550 pReq->param = 0;/*batch scan client*/
1551 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1552 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1553
1554 cur_len = pPrivData->used_len;
1555 if (pPrivData->total_len > pPrivData->used_len)
1556 {
1557 rem_len = pPrivData->total_len - pPrivData->used_len;
1558 }
1559 else
1560 {
1561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1562 "%s: Invalid user data buffer total_len %d used_len %d",
1563 __func__, pPrivData->total_len, pPrivData->used_len);
1564 return -EFAULT;
1565 }
1566
1567 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1568 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1569 cur_len, rem_len);
1570 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1571
1572 /*enough scan result available in cache to return to user space or
1573 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001574 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301575 {
1576 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1577 halStatus = sme_TriggerBatchScanResultInd(
1578 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1579 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1580 pAdapter);
1581 if ( eHAL_STATUS_SUCCESS == halStatus )
1582 {
1583 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1584 {
1585 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1586 rc = wait_for_completion_timeout(
1587 &pAdapter->hdd_get_batch_scan_req_var,
1588 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1589 if (0 == rc)
1590 {
1591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1592 "%s: Timeout waiting to fetch batch scan rsp from fw",
1593 __func__);
1594 return -EFAULT;
1595 }
1596 }
1597
1598 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001599 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301600 pDest += len;
1601 cur_len += len;
1602
1603 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1604 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1605 cur_len, rem_len);
1606 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1607
1608 count = 0;
1609 len = (len - pPrivData->used_len);
1610 pDest = (command + pPrivData->used_len);
1611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001612 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 while(count < len)
1614 {
1615 printk("%c", *(pDest + count));
1616 count++;
1617 }
1618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1619 "%s: copy %d data to user buffer", __func__, len);
1620 if (copy_to_user(pPrivData->buf, pDest, len))
1621 {
1622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1623 "%s: failed to copy data to user buffer", __func__);
1624 return -EFAULT;
1625 }
1626 }
1627 else
1628 {
1629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1630 "sme_GetBatchScanScan returned failure halStatus %d",
1631 halStatus);
1632 return -EINVAL;
1633 }
1634 }
1635 else
1636 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301637 count = 0;
1638 len = (len - pPrivData->used_len);
1639 pDest = (command + pPrivData->used_len);
1640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001641 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301642 while(count < len)
1643 {
1644 printk("%c", *(pDest + count));
1645 count++;
1646 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1648 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301649 if (copy_to_user(pPrivData->buf, pDest, len))
1650 {
1651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1652 "%s: failed to copy data to user buffer", __func__);
1653 return -EFAULT;
1654 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 }
1656
1657 return 0;
1658} /*End of hdd_return_batch_scan_rsp_to_user*/
1659
Rajeev Kumar8b373292014-01-08 20:36:55 -08001660
1661/**---------------------------------------------------------------------------
1662
1663 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1664 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1665 WLS_BATCHING VERSION
1666 WLS_BATCHING SET
1667 WLS_BATCHING GET
1668 WLS_BATCHING STOP
1669
1670 \param - pAdapter Pointer to HDD adapter
1671 \param - pPrivdata Pointer to priv_data
1672 \param - command Pointer to command
1673
1674 \return - 0 for success -EFAULT for failure
1675
1676 --------------------------------------------------------------------------*/
1677
1678int hdd_handle_batch_scan_ioctl
1679(
1680 hdd_adapter_t *pAdapter,
1681 hdd_priv_data_t *pPrivdata,
1682 tANI_U8 *command
1683)
1684{
1685 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001686 hdd_context_t *pHddCtx;
1687
1688 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1689 ret = wlan_hdd_validate_context(pHddCtx);
1690 if (ret)
1691 {
1692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1693 "%s: HDD context is not valid!", __func__);
1694 goto exit;
1695 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001696
1697 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1698 {
1699 char extra[32];
1700 tANI_U8 len = 0;
1701 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1702
1703 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1704 {
1705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1706 "%s: Batch scan feature is not supported by FW", __func__);
1707 ret = -EINVAL;
1708 goto exit;
1709 }
1710
1711 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1712 version);
1713 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1714 {
1715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1716 "%s: failed to copy data to user buffer", __func__);
1717 ret = -EFAULT;
1718 goto exit;
1719 }
1720 ret = HDD_BATCH_SCAN_VERSION;
1721 }
1722 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1723 {
1724 int status;
1725 tANI_U8 *value = (command + 16);
1726 eHalStatus halStatus;
1727 unsigned long rc;
1728 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1729 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1730
1731 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1732 {
1733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1734 "%s: Batch scan feature is not supported by FW", __func__);
1735 ret = -EINVAL;
1736 goto exit;
1737 }
1738
1739 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1740 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1741 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1742 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1743 {
1744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301745 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001746 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301747 hdd_device_modetoString(pAdapter->device_mode),
1748 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001749 ret = -EINVAL;
1750 goto exit;
1751 }
1752
1753 status = hdd_parse_set_batchscan_command(value, pReq);
1754 if (status)
1755 {
1756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1757 "Invalid WLS_BATCHING SET command");
1758 ret = -EINVAL;
1759 goto exit;
1760 }
1761
1762
1763 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1764 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1765 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1766 pAdapter);
1767
1768 if ( eHAL_STATUS_SUCCESS == halStatus )
1769 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301770 char extra[32];
1771 tANI_U8 len = 0;
1772 tANI_U8 mScan = 0;
1773
Rajeev Kumar8b373292014-01-08 20:36:55 -08001774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1775 "sme_SetBatchScanReq returned success halStatus %d",
1776 halStatus);
1777 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1778 {
1779 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1780 rc = wait_for_completion_timeout(
1781 &pAdapter->hdd_set_batch_scan_req_var,
1782 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1783 if (0 == rc)
1784 {
1785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1786 "%s: Timeout waiting for set batch scan to complete",
1787 __func__);
1788 ret = -EINVAL;
1789 goto exit;
1790 }
1791 }
1792 if ( !pRsp->nScansToBatch )
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1795 "%s: Received set batch scan failure response from FW",
1796 __func__);
1797 ret = -EINVAL;
1798 goto exit;
1799 }
1800 /*As per the Batch Scan Framework API we should return the MIN of
1801 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301802 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001803
1804 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1805
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1807 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301808 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1809 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1810 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1811 {
1812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1813 "%s: failed to copy MSCAN value to user buffer", __func__);
1814 ret = -EFAULT;
1815 goto exit;
1816 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001817 }
1818 else
1819 {
1820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1821 "sme_SetBatchScanReq returned failure halStatus %d",
1822 halStatus);
1823 ret = -EINVAL;
1824 goto exit;
1825 }
1826 }
1827 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1828 {
1829 eHalStatus halStatus;
1830 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1831 pInd->param = 0;
1832
1833 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1834 {
1835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1836 "%s: Batch scan feature is not supported by FW", __func__);
1837 ret = -EINVAL;
1838 goto exit;
1839 }
1840
1841 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1842 {
1843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1844 "Batch scan is not yet enabled batch scan state %d",
1845 pAdapter->batchScanState);
1846 ret = -EINVAL;
1847 goto exit;
1848 }
1849
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001850 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1851 hdd_deinit_batch_scan(pAdapter);
1852 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1853
Rajeev Kumar8b373292014-01-08 20:36:55 -08001854 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1855
1856 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1857 pAdapter->sessionId);
1858 if ( eHAL_STATUS_SUCCESS == halStatus )
1859 {
1860 ret = 0;
1861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1862 "sme_StopBatchScanInd returned success halStatus %d",
1863 halStatus);
1864 }
1865 else
1866 {
1867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1868 "sme_StopBatchScanInd returned failure halStatus %d",
1869 halStatus);
1870 ret = -EINVAL;
1871 goto exit;
1872 }
1873 }
1874 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1875 {
1876 tANI_U32 remain_len;
1877
1878 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "%s: Batch scan feature is not supported by FW", __func__);
1882 ret = -EINVAL;
1883 goto exit;
1884 }
1885
1886 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1887 {
1888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1889 "Batch scan is not yet enabled could not return results"
1890 "Batch Scan state %d",
1891 pAdapter->batchScanState);
1892 ret = -EINVAL;
1893 goto exit;
1894 }
1895
1896 pPrivdata->used_len = 16;
1897 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1898 if (remain_len < pPrivdata->total_len)
1899 {
1900 /*Clear previous batch scan response data if any*/
1901 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1902 }
1903 else
1904 {
1905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1906 "Invalid total length from user space can't fetch batch"
1907 " scan response total_len %d used_len %d remain len %d",
1908 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1909 ret = -EINVAL;
1910 goto exit;
1911 }
1912 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1913 }
1914
1915exit:
1916
1917 return ret;
1918}
1919
1920
Rajeev79dbe4c2013-10-05 11:03:42 +05301921#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1922
c_hpothu92367912014-05-01 15:18:17 +05301923static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1924{
c_hpothu39eb1e32014-06-26 16:31:50 +05301925 bcnMissRateContext_t *pCBCtx;
1926
1927 if (NULL == data)
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1930 return;
1931 }
c_hpothu92367912014-05-01 15:18:17 +05301932
1933 /* there is a race condition that exists between this callback
1934 function and the caller since the caller could time out either
1935 before or while this code is executing. we use a spinlock to
1936 serialize these actions */
1937 spin_lock(&hdd_context_lock);
1938
c_hpothu39eb1e32014-06-26 16:31:50 +05301939 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301940 gbcnMissRate = -1;
1941
c_hpothu39eb1e32014-06-26 16:31:50 +05301942 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301943 {
1944 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301945 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301946 spin_unlock(&hdd_context_lock);
1947 return ;
1948 }
1949
1950 if (VOS_STATUS_SUCCESS == status)
1951 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301953 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301954 else
1955 {
1956 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1957 }
1958
c_hpothu92367912014-05-01 15:18:17 +05301959 complete(&(pCBCtx->completion));
1960 spin_unlock(&hdd_context_lock);
1961
1962 return;
1963}
1964
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301965static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1966{
1967 int ret = 0;
1968
1969 if (!pCfg || !command || !extra || !len)
1970 {
1971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1972 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1973 ret = -EINVAL;
1974 return ret;
1975 }
1976
1977 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1978 {
1979 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1980 (int)pCfg->nActiveMaxChnTime);
1981 return ret;
1982 }
1983 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1984 {
1985 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1986 (int)pCfg->nActiveMinChnTime);
1987 return ret;
1988 }
1989 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1990 {
1991 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1992 (int)pCfg->nPassiveMaxChnTime);
1993 return ret;
1994 }
1995 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
1996 {
1997 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
1998 (int)pCfg->nPassiveMinChnTime);
1999 return ret;
2000 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302001 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2002 {
2003 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2004 (int)pCfg->nActiveMaxChnTime);
2005 return ret;
2006 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302007 else
2008 {
2009 ret = -EINVAL;
2010 }
2011
2012 return ret;
2013}
2014
2015static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2016{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302017 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302018 hdd_config_t *pCfg;
2019 tANI_U8 *value = command;
2020 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302021 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302022
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302023 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2024 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302025 {
2026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2027 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2028 ret = -EINVAL;
2029 return ret;
2030 }
2031
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302032 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2033 sme_GetConfigParam(hHal, &smeConfig);
2034
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302035 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2036 {
2037 value = value + 24;
2038 temp = kstrtou32(value, 10, &val);
2039 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2040 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2041 {
2042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2043 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2044 ret = -EFAULT;
2045 return ret;
2046 }
2047 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302048 smeConfig.csrConfig.nActiveMaxChnTime = val;
2049 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302050 }
2051 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2052 {
2053 value = value + 24;
2054 temp = kstrtou32(value, 10, &val);
2055 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2056 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2057 {
2058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2059 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2060 ret = -EFAULT;
2061 return ret;
2062 }
2063 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302064 smeConfig.csrConfig.nActiveMinChnTime = val;
2065 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302066 }
2067 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2068 {
2069 value = value + 25;
2070 temp = kstrtou32(value, 10, &val);
2071 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2072 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2073 {
2074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2075 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2076 ret = -EFAULT;
2077 return ret;
2078 }
2079 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302080 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2081 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302082 }
2083 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2084 {
2085 value = value + 25;
2086 temp = kstrtou32(value, 10, &val);
2087 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2088 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2089 {
2090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2091 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2092 ret = -EFAULT;
2093 return ret;
2094 }
2095 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 smeConfig.csrConfig.nPassiveMinChnTime = val;
2097 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302099 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2100 {
2101 value = value + 13;
2102 temp = kstrtou32(value, 10, &val);
2103 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2104 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2105 {
2106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2107 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2108 ret = -EFAULT;
2109 return ret;
2110 }
2111 pCfg->nActiveMaxChnTime = val;
2112 smeConfig.csrConfig.nActiveMaxChnTime = val;
2113 sme_UpdateConfig(hHal, &smeConfig);
2114 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302115 else
2116 {
2117 ret = -EINVAL;
2118 }
2119
2120 return ret;
2121}
2122
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002123static int hdd_driver_command(hdd_adapter_t *pAdapter,
2124 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002125{
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 hdd_priv_data_t priv_data;
2127 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002128 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002129
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002130 /*
2131 * Note that valid pointers are provided by caller
2132 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002133
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002134 /* copy to local struct to avoid numerous changes to legacy code */
2135 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002136
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002137 if (priv_data.total_len <= 0 ||
2138 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002139 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002140 hddLog(VOS_TRACE_LEVEL_WARN,
2141 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2142 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002143 ret = -EINVAL;
2144 goto exit;
2145 }
2146
2147 /* Allocate +1 for '\0' */
2148 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002149 if (!command)
2150 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002151 hddLog(VOS_TRACE_LEVEL_ERROR,
2152 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 ret = -ENOMEM;
2154 goto exit;
2155 }
2156
2157 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2158 {
2159 ret = -EFAULT;
2160 goto exit;
2161 }
2162
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002163 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002164 command[priv_data.total_len] = '\0';
2165
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002166 /* at one time the following block of code was conditional. braces
2167 * have been retained to avoid re-indenting the legacy code
2168 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002169 {
2170 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2171
2172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002173 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002174
2175 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2176 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302177 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2178 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2179 pAdapter->sessionId, (unsigned)
2180 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2181 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2182 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2183 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002184 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2185 sizeof(tSirMacAddr)))
2186 {
2187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002188 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002189 ret = -EFAULT;
2190 }
2191 }
Amar Singhal0974e402013-02-12 14:27:46 -08002192 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 {
Amar Singhal0974e402013-02-12 14:27:46 -08002194 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002195
Jeff Johnson295189b2012-06-20 16:38:30 -07002196 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002197
2198 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002201 "%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 -07002202 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002203 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302204 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302205 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002206 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002207 }
Kiet Lamf040f472013-11-20 21:15:23 +05302208 else if(strncmp(command, "SETWMMPS", 8) == 0)
2209 {
2210 tANI_U8 *ptr = command;
2211 ret = hdd_wmmps_helper(pAdapter, ptr);
2212 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002213 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2214 {
2215 char *country_code;
2216
2217 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002218
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002219 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002220 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002221#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302222 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002223#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002224 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2225 (void *)(tSmeChangeCountryCallback)
2226 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302227 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002228 if (eHAL_STATUS_SUCCESS == ret)
2229 {
2230 ret = wait_for_completion_interruptible_timeout(
2231 &pAdapter->change_country_code,
2232 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2233 if (0 >= ret)
2234 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302236 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002237 }
2238 }
2239 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002240 {
2241 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002242 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002243 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002244 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002245
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002246 }
2247 /*
2248 command should be a string having format
2249 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2250 */
Amar Singhal0974e402013-02-12 14:27:46 -08002251 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002252 {
Amar Singhal0974e402013-02-12 14:27:46 -08002253 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002254
2255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002256 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002257
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002258 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002259 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002260 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2261 {
2262 int suspend = 0;
2263 tANI_U8 *ptr = (tANI_U8*)command + 15;
2264
2265 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302266 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2267 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2268 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002269 hdd_set_wlan_suspend_mode(suspend);
2270 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002271#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2272 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2273 {
2274 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002275 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002276 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2277 eHalStatus status = eHAL_STATUS_SUCCESS;
2278
2279 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2280 value = value + 15;
2281
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002282 /* Convert the value from ascii to integer */
2283 ret = kstrtos8(value, 10, &rssi);
2284 if (ret < 0)
2285 {
2286 /* If the input value is greater than max value of datatype, then also
2287 kstrtou8 fails */
2288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2289 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002290 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002291 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2292 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2293 ret = -EINVAL;
2294 goto exit;
2295 }
2296
Srinivas Girigowdade697412013-02-14 16:31:48 -08002297 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002298
Srinivas Girigowdade697412013-02-14 16:31:48 -08002299 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2300 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2301 {
2302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2303 "Neighbor lookup threshold value %d is out of range"
2304 " (Min: %d Max: %d)", lookUpThreshold,
2305 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2306 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2307 ret = -EINVAL;
2308 goto exit;
2309 }
2310
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302311 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2312 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2313 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2315 "%s: Received Command to Set Roam trigger"
2316 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2317
2318 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2319 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2320 if (eHAL_STATUS_SUCCESS != status)
2321 {
2322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2323 "%s: Failed to set roam trigger, try again", __func__);
2324 ret = -EPERM;
2325 goto exit;
2326 }
2327
2328 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302329 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002330 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2331 }
2332 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2333 {
2334 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2335 int rssi = (-1) * lookUpThreshold;
2336 char extra[32];
2337 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302338 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2339 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2340 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002341 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002342 if (copy_to_user(priv_data.buf, &extra, len + 1))
2343 {
2344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2345 "%s: failed to copy data to user buffer", __func__);
2346 ret = -EFAULT;
2347 goto exit;
2348 }
2349 }
2350 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2351 {
2352 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002353 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002354 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002355
Srinivas Girigowdade697412013-02-14 16:31:48 -08002356 /* input refresh period is in terms of seconds */
2357 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2358 value = value + 18;
2359 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002360 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361 if (ret < 0)
2362 {
2363 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002364 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002366 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002367 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002368 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2369 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002370 ret = -EINVAL;
2371 goto exit;
2372 }
2373
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002374 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2375 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002376 {
2377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002378 "Roam scan period value %d is out of range"
2379 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002380 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2381 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002382 ret = -EINVAL;
2383 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302384 }
2385 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2386 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2387 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002388 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002389
2390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2391 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002392 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002393
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002394 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2395 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002396 }
2397 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2398 {
2399 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2400 char extra[32];
2401 tANI_U8 len = 0;
2402
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2404 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2405 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002406 len = scnprintf(extra, sizeof(extra), "%s %d",
2407 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002408 /* Returned value is in units of seconds */
2409 if (copy_to_user(priv_data.buf, &extra, len + 1))
2410 {
2411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2412 "%s: failed to copy data to user buffer", __func__);
2413 ret = -EFAULT;
2414 goto exit;
2415 }
2416 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002417 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2418 {
2419 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002420 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002421 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002422
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002423 /* input refresh period is in terms of seconds */
2424 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2425 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002426
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002427 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002428 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002429 if (ret < 0)
2430 {
2431 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002432 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002434 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002435 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002436 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2437 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2438 ret = -EINVAL;
2439 goto exit;
2440 }
2441
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002442 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2443 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2444 {
2445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2446 "Neighbor scan results refresh period value %d is out of range"
2447 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2448 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2449 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2450 ret = -EINVAL;
2451 goto exit;
2452 }
2453 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2454
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2456 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002457 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002458
2459 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2460 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2461 }
2462 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2463 {
2464 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2465 char extra[32];
2466 tANI_U8 len = 0;
2467
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002468 len = scnprintf(extra, sizeof(extra), "%s %d",
2469 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002470 /* Returned value is in units of seconds */
2471 if (copy_to_user(priv_data.buf, &extra, len + 1))
2472 {
2473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2474 "%s: failed to copy data to user buffer", __func__);
2475 ret = -EFAULT;
2476 goto exit;
2477 }
2478 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002479#ifdef FEATURE_WLAN_LFR
2480 /* SETROAMMODE */
2481 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2482 {
2483 tANI_U8 *value = command;
2484 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2485
2486 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2487 value = value + SIZE_OF_SETROAMMODE + 1;
2488
2489 /* Convert the value from ascii to integer */
2490 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2491 if (ret < 0)
2492 {
2493 /* If the input value is greater than max value of datatype, then also
2494 kstrtou8 fails */
2495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2496 "%s: kstrtou8 failed range [%d - %d]", __func__,
2497 CFG_LFR_FEATURE_ENABLED_MIN,
2498 CFG_LFR_FEATURE_ENABLED_MAX);
2499 ret = -EINVAL;
2500 goto exit;
2501 }
2502 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2503 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2504 {
2505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2506 "Roam Mode value %d is out of range"
2507 " (Min: %d Max: %d)", roamMode,
2508 CFG_LFR_FEATURE_ENABLED_MIN,
2509 CFG_LFR_FEATURE_ENABLED_MAX);
2510 ret = -EINVAL;
2511 goto exit;
2512 }
2513
2514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2515 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2516 /*
2517 * Note that
2518 * SETROAMMODE 0 is to enable LFR while
2519 * SETROAMMODE 1 is to disable LFR, but
2520 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2521 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2522 */
2523 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2524 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2525 else
2526 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2527
2528 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2529 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2530 }
2531 /* GETROAMMODE */
2532 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2533 {
2534 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2535 char extra[32];
2536 tANI_U8 len = 0;
2537
2538 /*
2539 * roamMode value shall be inverted because the sementics is different.
2540 */
2541 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2542 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2543 else
2544 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2545
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002546 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002547 if (copy_to_user(priv_data.buf, &extra, len + 1))
2548 {
2549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2550 "%s: failed to copy data to user buffer", __func__);
2551 ret = -EFAULT;
2552 goto exit;
2553 }
2554 }
2555#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002556#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002557#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002558 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2559 {
2560 tANI_U8 *value = command;
2561 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2562
2563 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2564 value = value + 13;
2565 /* Convert the value from ascii to integer */
2566 ret = kstrtou8(value, 10, &roamRssiDiff);
2567 if (ret < 0)
2568 {
2569 /* If the input value is greater than max value of datatype, then also
2570 kstrtou8 fails */
2571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2572 "%s: kstrtou8 failed range [%d - %d]", __func__,
2573 CFG_ROAM_RSSI_DIFF_MIN,
2574 CFG_ROAM_RSSI_DIFF_MAX);
2575 ret = -EINVAL;
2576 goto exit;
2577 }
2578
2579 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2580 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2581 {
2582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2583 "Roam rssi diff value %d is out of range"
2584 " (Min: %d Max: %d)", roamRssiDiff,
2585 CFG_ROAM_RSSI_DIFF_MIN,
2586 CFG_ROAM_RSSI_DIFF_MAX);
2587 ret = -EINVAL;
2588 goto exit;
2589 }
2590
2591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2592 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2593
2594 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2595 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2596 }
2597 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2598 {
2599 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2600 char extra[32];
2601 tANI_U8 len = 0;
2602
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2604 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2605 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002606 len = scnprintf(extra, sizeof(extra), "%s %d",
2607 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002608 if (copy_to_user(priv_data.buf, &extra, len + 1))
2609 {
2610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2611 "%s: failed to copy data to user buffer", __func__);
2612 ret = -EFAULT;
2613 goto exit;
2614 }
2615 }
2616#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002617#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002618 else if (strncmp(command, "GETBAND", 7) == 0)
2619 {
2620 int band = -1;
2621 char extra[32];
2622 tANI_U8 len = 0;
2623 hdd_getBand_helper(pHddCtx, &band);
2624
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2626 TRACE_CODE_HDD_GETBAND_IOCTL,
2627 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002628 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002629 if (copy_to_user(priv_data.buf, &extra, len + 1))
2630 {
2631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2632 "%s: failed to copy data to user buffer", __func__);
2633 ret = -EFAULT;
2634 goto exit;
2635 }
2636 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002637 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2638 {
2639 tANI_U8 *value = command;
2640 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2641 tANI_U8 numChannels = 0;
2642 eHalStatus status = eHAL_STATUS_SUCCESS;
2643
2644 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2645 if (eHAL_STATUS_SUCCESS != status)
2646 {
2647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2648 "%s: Failed to parse channel list information", __func__);
2649 ret = -EINVAL;
2650 goto exit;
2651 }
2652
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302653 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2654 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2655 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002656 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2657 {
2658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2659 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2660 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2661 ret = -EINVAL;
2662 goto exit;
2663 }
2664 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2665 numChannels);
2666 if (eHAL_STATUS_SUCCESS != status)
2667 {
2668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2669 "%s: Failed to update channel list information", __func__);
2670 ret = -EINVAL;
2671 goto exit;
2672 }
2673 }
2674 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2675 {
2676 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2677 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002678 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002679 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002680 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002681
2682 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2683 ChannelList, &numChannels ))
2684 {
2685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2686 "%s: failed to get roam scan channel list", __func__);
2687 ret = -EFAULT;
2688 goto exit;
2689 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302690 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2691 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2692 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002693 /* output channel list is of the format
2694 [Number of roam scan channels][Channel1][Channel2]... */
2695 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002696 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002697 for (j = 0; (j < numChannels); j++)
2698 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002699 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2700 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002701 }
2702
2703 if (copy_to_user(priv_data.buf, &extra, len + 1))
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "%s: failed to copy data to user buffer", __func__);
2707 ret = -EFAULT;
2708 goto exit;
2709 }
2710 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002711 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2712 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002713 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002714 char extra[32];
2715 tANI_U8 len = 0;
2716
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002717 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002718 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002719 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002720 hdd_is_okc_mode_enabled(pHddCtx) &&
2721 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2722 {
2723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002724 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002725 " hence this operation is not permitted!", __func__);
2726 ret = -EPERM;
2727 goto exit;
2728 }
2729
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002730 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002731 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002732 if (copy_to_user(priv_data.buf, &extra, len + 1))
2733 {
2734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2735 "%s: failed to copy data to user buffer", __func__);
2736 ret = -EFAULT;
2737 goto exit;
2738 }
2739 }
2740 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2741 {
2742 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2743 char extra[32];
2744 tANI_U8 len = 0;
2745
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002746 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002747 then this operation is not permitted (return FAILURE) */
2748 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002749 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002750 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2751 {
2752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002753 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002754 " hence this operation is not permitted!", __func__);
2755 ret = -EPERM;
2756 goto exit;
2757 }
2758
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002759 len = scnprintf(extra, sizeof(extra), "%s %d",
2760 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002761 if (copy_to_user(priv_data.buf, &extra, len + 1))
2762 {
2763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2764 "%s: failed to copy data to user buffer", __func__);
2765 ret = -EFAULT;
2766 goto exit;
2767 }
2768 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002769 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002770 {
2771 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2772 char extra[32];
2773 tANI_U8 len = 0;
2774
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002775 len = scnprintf(extra, sizeof(extra), "%s %d",
2776 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002777 if (copy_to_user(priv_data.buf, &extra, len + 1))
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2780 "%s: failed to copy data to user buffer", __func__);
2781 ret = -EFAULT;
2782 goto exit;
2783 }
2784 }
2785 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2786 {
2787 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2788 char extra[32];
2789 tANI_U8 len = 0;
2790
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002791 len = scnprintf(extra, sizeof(extra), "%s %d",
2792 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002793 if (copy_to_user(priv_data.buf, &extra, len + 1))
2794 {
2795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2796 "%s: failed to copy data to user buffer", __func__);
2797 ret = -EFAULT;
2798 goto exit;
2799 }
2800 }
2801 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2802 {
2803 tANI_U8 *value = command;
2804 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2805
2806 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2807 value = value + 26;
2808 /* Convert the value from ascii to integer */
2809 ret = kstrtou8(value, 10, &minTime);
2810 if (ret < 0)
2811 {
2812 /* If the input value is greater than max value of datatype, then also
2813 kstrtou8 fails */
2814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2815 "%s: kstrtou8 failed range [%d - %d]", __func__,
2816 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2817 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2818 ret = -EINVAL;
2819 goto exit;
2820 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002821 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2822 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2823 {
2824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2825 "scan min channel time value %d is out of range"
2826 " (Min: %d Max: %d)", minTime,
2827 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2828 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2829 ret = -EINVAL;
2830 goto exit;
2831 }
2832
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302833 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2834 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2835 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2837 "%s: Received Command to change channel min time = %d", __func__, minTime);
2838
2839 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2840 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2841 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002842 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2843 {
2844 tANI_U8 *value = command;
2845 tANI_U8 channel = 0;
2846 tANI_U8 dwellTime = 0;
2847 tANI_U8 bufLen = 0;
2848 tANI_U8 *buf = NULL;
2849 tSirMacAddr targetApBssid;
2850 eHalStatus status = eHAL_STATUS_SUCCESS;
2851 struct ieee80211_channel chan;
2852 tANI_U8 finalLen = 0;
2853 tANI_U8 *finalBuf = NULL;
2854 tANI_U8 temp = 0;
2855 u64 cookie;
2856 hdd_station_ctx_t *pHddStaCtx = NULL;
2857 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2858
2859 /* if not associated, no need to send action frame */
2860 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2861 {
2862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2863 ret = -EINVAL;
2864 goto exit;
2865 }
2866
2867 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2868 &dwellTime, &buf, &bufLen);
2869 if (eHAL_STATUS_SUCCESS != status)
2870 {
2871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2872 "%s: Failed to parse send action frame data", __func__);
2873 ret = -EINVAL;
2874 goto exit;
2875 }
2876
2877 /* if the target bssid is different from currently associated AP,
2878 then no need to send action frame */
2879 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2880 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2881 {
2882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2883 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002884 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002885 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002886 goto exit;
2887 }
2888
2889 /* if the channel number is different from operating channel then
2890 no need to send action frame */
2891 if (channel != pHddStaCtx->conn_info.operationChannel)
2892 {
2893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2894 "%s: channel(%d) is different from operating channel(%d)",
2895 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2896 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002897 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002898 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002899 goto exit;
2900 }
2901 chan.center_freq = sme_ChnToFreq(channel);
2902
2903 finalLen = bufLen + 24;
2904 finalBuf = vos_mem_malloc(finalLen);
2905 if (NULL == finalBuf)
2906 {
2907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2908 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002909 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002910 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002911 goto exit;
2912 }
2913 vos_mem_zero(finalBuf, finalLen);
2914
2915 /* Fill subtype */
2916 temp = SIR_MAC_MGMT_ACTION << 4;
2917 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2918
2919 /* Fill type */
2920 temp = SIR_MAC_MGMT_FRAME;
2921 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2922
2923 /* Fill destination address (bssid of the AP) */
2924 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2925
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002926 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002927 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2928
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002929 /* Fill BSSID (AP mac address) */
2930 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002931
2932 /* Fill received buffer from 24th address */
2933 vos_mem_copy(finalBuf + 24, buf, bufLen);
2934
Jeff Johnson11c33152013-04-16 17:52:40 -07002935 /* done with the parsed buffer */
2936 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002937 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002938
DARAM SUDHA39eede62014-02-12 11:16:40 +05302939 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2941 &(pAdapter->wdev),
2942#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002943 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002944#endif
2945 &chan, 0,
2946#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2947 NL80211_CHAN_HT20, 1,
2948#endif
2949 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002950 1, &cookie );
2951 vos_mem_free(finalBuf);
2952 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002953 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2954 {
2955 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2956 char extra[32];
2957 tANI_U8 len = 0;
2958
2959 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002960 len = scnprintf(extra, sizeof(extra), "%s %d",
2961 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302962 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2963 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2964 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002965 if (copy_to_user(priv_data.buf, &extra, len + 1))
2966 {
2967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2968 "%s: failed to copy data to user buffer", __func__);
2969 ret = -EFAULT;
2970 goto exit;
2971 }
2972 }
2973 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2974 {
2975 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002976 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002977
2978 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2979 value = value + 19;
2980 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002981 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002982 if (ret < 0)
2983 {
2984 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002985 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002987 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002988 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2989 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2990 ret = -EINVAL;
2991 goto exit;
2992 }
2993
2994 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2995 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2996 {
2997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2998 "lfr mode value %d is out of range"
2999 " (Min: %d Max: %d)", maxTime,
3000 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3001 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3002 ret = -EINVAL;
3003 goto exit;
3004 }
3005
3006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3007 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3008
3009 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3010 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3011 }
3012 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3013 {
3014 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3015 char extra[32];
3016 tANI_U8 len = 0;
3017
3018 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003019 len = scnprintf(extra, sizeof(extra), "%s %d",
3020 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003021 if (copy_to_user(priv_data.buf, &extra, len + 1))
3022 {
3023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3024 "%s: failed to copy data to user buffer", __func__);
3025 ret = -EFAULT;
3026 goto exit;
3027 }
3028 }
3029 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3030 {
3031 tANI_U8 *value = command;
3032 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3033
3034 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3035 value = value + 16;
3036 /* Convert the value from ascii to integer */
3037 ret = kstrtou16(value, 10, &val);
3038 if (ret < 0)
3039 {
3040 /* If the input value is greater than max value of datatype, then also
3041 kstrtou16 fails */
3042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3043 "%s: kstrtou16 failed range [%d - %d]", __func__,
3044 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3045 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3046 ret = -EINVAL;
3047 goto exit;
3048 }
3049
3050 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3051 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3052 {
3053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3054 "scan home time value %d is out of range"
3055 " (Min: %d Max: %d)", val,
3056 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3057 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3058 ret = -EINVAL;
3059 goto exit;
3060 }
3061
3062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3063 "%s: Received Command to change scan home time = %d", __func__, val);
3064
3065 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3066 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3067 }
3068 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3069 {
3070 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3071 char extra[32];
3072 tANI_U8 len = 0;
3073
3074 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003075 len = scnprintf(extra, sizeof(extra), "%s %d",
3076 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003077 if (copy_to_user(priv_data.buf, &extra, len + 1))
3078 {
3079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3080 "%s: failed to copy data to user buffer", __func__);
3081 ret = -EFAULT;
3082 goto exit;
3083 }
3084 }
3085 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3086 {
3087 tANI_U8 *value = command;
3088 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3089
3090 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3091 value = value + 17;
3092 /* Convert the value from ascii to integer */
3093 ret = kstrtou8(value, 10, &val);
3094 if (ret < 0)
3095 {
3096 /* If the input value is greater than max value of datatype, then also
3097 kstrtou8 fails */
3098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3099 "%s: kstrtou8 failed range [%d - %d]", __func__,
3100 CFG_ROAM_INTRA_BAND_MIN,
3101 CFG_ROAM_INTRA_BAND_MAX);
3102 ret = -EINVAL;
3103 goto exit;
3104 }
3105
3106 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3107 (val > CFG_ROAM_INTRA_BAND_MAX))
3108 {
3109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3110 "intra band mode value %d is out of range"
3111 " (Min: %d Max: %d)", val,
3112 CFG_ROAM_INTRA_BAND_MIN,
3113 CFG_ROAM_INTRA_BAND_MAX);
3114 ret = -EINVAL;
3115 goto exit;
3116 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3118 "%s: Received Command to change intra band = %d", __func__, val);
3119
3120 pHddCtx->cfg_ini->nRoamIntraBand = val;
3121 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3122 }
3123 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3124 {
3125 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3126 char extra[32];
3127 tANI_U8 len = 0;
3128
3129 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003130 len = scnprintf(extra, sizeof(extra), "%s %d",
3131 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003132 if (copy_to_user(priv_data.buf, &extra, len + 1))
3133 {
3134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3135 "%s: failed to copy data to user buffer", __func__);
3136 ret = -EFAULT;
3137 goto exit;
3138 }
3139 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003140 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3141 {
3142 tANI_U8 *value = command;
3143 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3144
3145 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3146 value = value + 15;
3147 /* Convert the value from ascii to integer */
3148 ret = kstrtou8(value, 10, &nProbes);
3149 if (ret < 0)
3150 {
3151 /* If the input value is greater than max value of datatype, then also
3152 kstrtou8 fails */
3153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3154 "%s: kstrtou8 failed range [%d - %d]", __func__,
3155 CFG_ROAM_SCAN_N_PROBES_MIN,
3156 CFG_ROAM_SCAN_N_PROBES_MAX);
3157 ret = -EINVAL;
3158 goto exit;
3159 }
3160
3161 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3162 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3163 {
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "NProbes value %d is out of range"
3166 " (Min: %d Max: %d)", nProbes,
3167 CFG_ROAM_SCAN_N_PROBES_MIN,
3168 CFG_ROAM_SCAN_N_PROBES_MAX);
3169 ret = -EINVAL;
3170 goto exit;
3171 }
3172
3173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3174 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3175
3176 pHddCtx->cfg_ini->nProbes = nProbes;
3177 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3178 }
3179 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3180 {
3181 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3182 char extra[32];
3183 tANI_U8 len = 0;
3184
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003185 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003186 if (copy_to_user(priv_data.buf, &extra, len + 1))
3187 {
3188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3189 "%s: failed to copy data to user buffer", __func__);
3190 ret = -EFAULT;
3191 goto exit;
3192 }
3193 }
3194 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3195 {
3196 tANI_U8 *value = command;
3197 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3198
3199 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3200 /* input value is in units of msec */
3201 value = value + 20;
3202 /* Convert the value from ascii to integer */
3203 ret = kstrtou16(value, 10, &homeAwayTime);
3204 if (ret < 0)
3205 {
3206 /* If the input value is greater than max value of datatype, then also
3207 kstrtou8 fails */
3208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3209 "%s: kstrtou8 failed range [%d - %d]", __func__,
3210 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3211 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3212 ret = -EINVAL;
3213 goto exit;
3214 }
3215
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003216 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3217 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "homeAwayTime value %d is out of range"
3221 " (Min: %d Max: %d)", homeAwayTime,
3222 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3223 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3224 ret = -EINVAL;
3225 goto exit;
3226 }
3227
3228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3229 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003230 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3231 {
3232 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3233 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3234 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003235 }
3236 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3237 {
3238 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3239 char extra[32];
3240 tANI_U8 len = 0;
3241
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003242 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003243 if (copy_to_user(priv_data.buf, &extra, len + 1))
3244 {
3245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3246 "%s: failed to copy data to user buffer", __func__);
3247 ret = -EFAULT;
3248 goto exit;
3249 }
3250 }
3251 else if (strncmp(command, "REASSOC", 7) == 0)
3252 {
3253 tANI_U8 *value = command;
3254 tANI_U8 channel = 0;
3255 tSirMacAddr targetApBssid;
3256 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003257#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3258 tCsrHandoffRequest handoffInfo;
3259#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003260 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003261 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3262
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003263 /* if not associated, no need to proceed with reassoc */
3264 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3265 {
3266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3267 ret = -EINVAL;
3268 goto exit;
3269 }
3270
3271 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3272 if (eHAL_STATUS_SUCCESS != status)
3273 {
3274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3275 "%s: Failed to parse reassoc command data", __func__);
3276 ret = -EINVAL;
3277 goto exit;
3278 }
3279
3280 /* if the target bssid is same as currently associated AP,
3281 then no need to proceed with reassoc */
3282 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3283 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3284 {
3285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3286 ret = -EINVAL;
3287 goto exit;
3288 }
3289
3290 /* Check channel number is a valid channel number */
3291 if(VOS_STATUS_SUCCESS !=
3292 wlan_hdd_validate_operation_channel(pAdapter, channel))
3293 {
3294 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003295 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003296 return -EINVAL;
3297 }
3298
3299 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003300#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3301 handoffInfo.channel = channel;
3302 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3303 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3304#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003305 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003306 else if (strncmp(command, "SETWESMODE", 10) == 0)
3307 {
3308 tANI_U8 *value = command;
3309 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3310
3311 /* Move pointer to ahead of SETWESMODE<delimiter> */
3312 value = value + 11;
3313 /* Convert the value from ascii to integer */
3314 ret = kstrtou8(value, 10, &wesMode);
3315 if (ret < 0)
3316 {
3317 /* If the input value is greater than max value of datatype, then also
3318 kstrtou8 fails */
3319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3320 "%s: kstrtou8 failed range [%d - %d]", __func__,
3321 CFG_ENABLE_WES_MODE_NAME_MIN,
3322 CFG_ENABLE_WES_MODE_NAME_MAX);
3323 ret = -EINVAL;
3324 goto exit;
3325 }
3326
3327 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3328 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "WES Mode value %d is out of range"
3332 " (Min: %d Max: %d)", wesMode,
3333 CFG_ENABLE_WES_MODE_NAME_MIN,
3334 CFG_ENABLE_WES_MODE_NAME_MAX);
3335 ret = -EINVAL;
3336 goto exit;
3337 }
3338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3339 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3340
3341 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3342 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3343 }
3344 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3345 {
3346 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3347 char extra[32];
3348 tANI_U8 len = 0;
3349
Arif Hussain826d9412013-11-12 16:44:54 -08003350 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003351 if (copy_to_user(priv_data.buf, &extra, len + 1))
3352 {
3353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3354 "%s: failed to copy data to user buffer", __func__);
3355 ret = -EFAULT;
3356 goto exit;
3357 }
3358 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003359#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003360#ifdef FEATURE_WLAN_LFR
3361 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3362 {
3363 tANI_U8 *value = command;
3364 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3365
3366 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3367 value = value + 12;
3368 /* Convert the value from ascii to integer */
3369 ret = kstrtou8(value, 10, &lfrMode);
3370 if (ret < 0)
3371 {
3372 /* If the input value is greater than max value of datatype, then also
3373 kstrtou8 fails */
3374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3375 "%s: kstrtou8 failed range [%d - %d]", __func__,
3376 CFG_LFR_FEATURE_ENABLED_MIN,
3377 CFG_LFR_FEATURE_ENABLED_MAX);
3378 ret = -EINVAL;
3379 goto exit;
3380 }
3381
3382 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3383 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3384 {
3385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3386 "lfr mode value %d is out of range"
3387 " (Min: %d Max: %d)", lfrMode,
3388 CFG_LFR_FEATURE_ENABLED_MIN,
3389 CFG_LFR_FEATURE_ENABLED_MAX);
3390 ret = -EINVAL;
3391 goto exit;
3392 }
3393
3394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3395 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3396
3397 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3398 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3399 }
3400#endif
3401#ifdef WLAN_FEATURE_VOWIFI_11R
3402 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3403 {
3404 tANI_U8 *value = command;
3405 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3406
3407 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3408 value = value + 18;
3409 /* Convert the value from ascii to integer */
3410 ret = kstrtou8(value, 10, &ft);
3411 if (ret < 0)
3412 {
3413 /* If the input value is greater than max value of datatype, then also
3414 kstrtou8 fails */
3415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3416 "%s: kstrtou8 failed range [%d - %d]", __func__,
3417 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3418 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3419 ret = -EINVAL;
3420 goto exit;
3421 }
3422
3423 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3424 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3425 {
3426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3427 "ft mode value %d is out of range"
3428 " (Min: %d Max: %d)", ft,
3429 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3430 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3431 ret = -EINVAL;
3432 goto exit;
3433 }
3434
3435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3436 "%s: Received Command to change ft mode = %d", __func__, ft);
3437
3438 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3439 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3440 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303441
3442 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3443 {
3444 tANI_U8 *value = command;
3445 tSirMacAddr targetApBssid;
3446 tANI_U8 trigger = 0;
3447 eHalStatus status = eHAL_STATUS_SUCCESS;
3448 hdd_station_ctx_t *pHddStaCtx = NULL;
3449 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3450
3451 /* if not associated, no need to proceed with reassoc */
3452 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3453 {
3454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3455 ret = -EINVAL;
3456 goto exit;
3457 }
3458
3459 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3460 if (eHAL_STATUS_SUCCESS != status)
3461 {
3462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3463 "%s: Failed to parse reassoc command data", __func__);
3464 ret = -EINVAL;
3465 goto exit;
3466 }
3467
3468 /* if the target bssid is same as currently associated AP,
3469 then no need to proceed with reassoc */
3470 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3471 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3472 {
3473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3474 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3475 __func__);
3476 ret = -EINVAL;
3477 goto exit;
3478 }
3479
3480 /* Proceed with scan/roam */
3481 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3482 &targetApBssid[0],
3483 (tSmeFastRoamTrigger)(trigger));
3484 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003485#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003486#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003487 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3488 {
3489 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003490 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003491
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003492 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003493 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003494 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003495 hdd_is_okc_mode_enabled(pHddCtx) &&
3496 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3497 {
3498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003499 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003500 " hence this operation is not permitted!", __func__);
3501 ret = -EPERM;
3502 goto exit;
3503 }
3504
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003505 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3506 value = value + 11;
3507 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003508 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003509 if (ret < 0)
3510 {
3511 /* If the input value is greater than max value of datatype, then also
3512 kstrtou8 fails */
3513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3514 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003515 CFG_ESE_FEATURE_ENABLED_MIN,
3516 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003517 ret = -EINVAL;
3518 goto exit;
3519 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003520 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3521 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003522 {
3523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003524 "Ese mode value %d is out of range"
3525 " (Min: %d Max: %d)", eseMode,
3526 CFG_ESE_FEATURE_ENABLED_MIN,
3527 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003528 ret = -EINVAL;
3529 goto exit;
3530 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003532 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003533
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003534 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3535 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003536 }
3537#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003538 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3539 {
3540 tANI_U8 *value = command;
3541 tANI_BOOLEAN roamScanControl = 0;
3542
3543 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3544 value = value + 19;
3545 /* Convert the value from ascii to integer */
3546 ret = kstrtou8(value, 10, &roamScanControl);
3547 if (ret < 0)
3548 {
3549 /* If the input value is greater than max value of datatype, then also
3550 kstrtou8 fails */
3551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3552 "%s: kstrtou8 failed ", __func__);
3553 ret = -EINVAL;
3554 goto exit;
3555 }
3556
3557 if (0 != roamScanControl)
3558 {
3559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3560 "roam scan control invalid value = %d",
3561 roamScanControl);
3562 ret = -EINVAL;
3563 goto exit;
3564 }
3565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3566 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3567
3568 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3569 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003570#ifdef FEATURE_WLAN_OKC
3571 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3572 {
3573 tANI_U8 *value = command;
3574 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3575
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003576 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003577 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003578 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003579 hdd_is_okc_mode_enabled(pHddCtx) &&
3580 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3581 {
3582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003584 " hence this operation is not permitted!", __func__);
3585 ret = -EPERM;
3586 goto exit;
3587 }
3588
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003589 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3590 value = value + 11;
3591 /* Convert the value from ascii to integer */
3592 ret = kstrtou8(value, 10, &okcMode);
3593 if (ret < 0)
3594 {
3595 /* If the input value is greater than max value of datatype, then also
3596 kstrtou8 fails */
3597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3598 "%s: kstrtou8 failed range [%d - %d]", __func__,
3599 CFG_OKC_FEATURE_ENABLED_MIN,
3600 CFG_OKC_FEATURE_ENABLED_MAX);
3601 ret = -EINVAL;
3602 goto exit;
3603 }
3604
3605 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3606 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3607 {
3608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3609 "Okc mode value %d is out of range"
3610 " (Min: %d Max: %d)", okcMode,
3611 CFG_OKC_FEATURE_ENABLED_MIN,
3612 CFG_OKC_FEATURE_ENABLED_MAX);
3613 ret = -EINVAL;
3614 goto exit;
3615 }
3616
3617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3618 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3619
3620 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3621 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003622#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003623 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3624 {
3625 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3626 char extra[32];
3627 tANI_U8 len = 0;
3628
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003629 len = scnprintf(extra, sizeof(extra), "%s %d",
3630 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003631 if (copy_to_user(priv_data.buf, &extra, len + 1))
3632 {
3633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3634 "%s: failed to copy data to user buffer", __func__);
3635 ret = -EFAULT;
3636 goto exit;
3637 }
3638 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303639#ifdef WLAN_FEATURE_PACKET_FILTERING
3640 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3641 {
3642 tANI_U8 filterType = 0;
3643 tANI_U8 *value = command;
3644
3645 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3646 value = value + 22;
3647
3648 /* Convert the value from ascii to integer */
3649 ret = kstrtou8(value, 10, &filterType);
3650 if (ret < 0)
3651 {
3652 /* If the input value is greater than max value of datatype,
3653 * then also kstrtou8 fails
3654 */
3655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3656 "%s: kstrtou8 failed range ", __func__);
3657 ret = -EINVAL;
3658 goto exit;
3659 }
3660
3661 if (filterType != 0 && filterType != 1)
3662 {
3663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3664 "%s: Accepted Values are 0 and 1 ", __func__);
3665 ret = -EINVAL;
3666 goto exit;
3667 }
3668 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3669 pAdapter->sessionId);
3670 }
3671#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303672 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3673 {
Kiet Lamad161252014-07-22 11:23:32 -07003674 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303675 int ret;
3676
Kiet Lamad161252014-07-22 11:23:32 -07003677 dhcpPhase = command + 11;
3678 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303679 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003681 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303682
3683 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003684
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303685 ret = wlan_hdd_scan_abort(pAdapter);
3686 if (ret < 0)
3687 {
3688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3689 FL("failed to abort existing scan %d"), ret);
3690 }
3691
Kiet Lamad161252014-07-22 11:23:32 -07003692 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3693 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303694 }
Kiet Lamad161252014-07-22 11:23:32 -07003695 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303696 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003698 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303699
3700 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003701
3702 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3703 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303704 }
3705 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003706 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3707 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3709 FL("making default scan to ACTIVE"));
3710 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003711 }
3712 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3713 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 FL("making default scan to PASSIVE"));
3716 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003717 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303718 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3719 {
3720 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3721 char extra[32];
3722 tANI_U8 len = 0;
3723
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303724 memset(extra, 0, sizeof(extra));
3725 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3726 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303727 {
3728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3729 "%s: failed to copy data to user buffer", __func__);
3730 ret = -EFAULT;
3731 goto exit;
3732 }
3733 ret = len;
3734 }
3735 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3736 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303737 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303738 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003739 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3740 {
3741 tANI_U8 filterType = 0;
3742 tANI_U8 *value;
3743 value = command + 9;
3744
3745 /* Convert the value from ascii to integer */
3746 ret = kstrtou8(value, 10, &filterType);
3747 if (ret < 0)
3748 {
3749 /* If the input value is greater than max value of datatype,
3750 * then also kstrtou8 fails
3751 */
3752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3753 "%s: kstrtou8 failed range ", __func__);
3754 ret = -EINVAL;
3755 goto exit;
3756 }
3757 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3758 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3759 {
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3761 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3762 " 2-Sink ", __func__);
3763 ret = -EINVAL;
3764 goto exit;
3765 }
3766 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3767 pHddCtx->drvr_miracast = filterType;
3768 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303769 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003770 }
Leo Chang614d2072013-08-22 14:59:44 -07003771 else if (strncmp(command, "SETMCRATE", 9) == 0)
3772 {
Leo Chang614d2072013-08-22 14:59:44 -07003773 tANI_U8 *value = command;
3774 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003775 tSirRateUpdateInd *rateUpdate;
3776 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003777
3778 /* Only valid for SAP mode */
3779 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3780 {
3781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3782 "%s: SAP mode is not running", __func__);
3783 ret = -EFAULT;
3784 goto exit;
3785 }
3786
3787 /* Move pointer to ahead of SETMCRATE<delimiter> */
3788 /* input value is in units of hundred kbps */
3789 value = value + 10;
3790 /* Convert the value from ascii to integer, decimal base */
3791 ret = kstrtouint(value, 10, &targetRate);
3792
Leo Chang1f98cbd2013-10-17 15:03:52 -07003793 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3794 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003795 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003796 hddLog(VOS_TRACE_LEVEL_ERROR,
3797 "%s: SETMCRATE indication alloc fail", __func__);
3798 ret = -EFAULT;
3799 goto exit;
3800 }
3801 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3802
3803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3804 "MC Target rate %d", targetRate);
3805 /* Ignore unicast */
3806 rateUpdate->ucastDataRate = -1;
3807 rateUpdate->mcastDataRate24GHz = targetRate;
3808 rateUpdate->mcastDataRate5GHz = targetRate;
3809 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3810 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3811 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3812 if (eHAL_STATUS_SUCCESS != status)
3813 {
3814 hddLog(VOS_TRACE_LEVEL_ERROR,
3815 "%s: SET_MC_RATE failed", __func__);
3816 vos_mem_free(rateUpdate);
3817 ret = -EFAULT;
3818 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003819 }
3820 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303821#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003822 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303823 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003824 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303825 }
3826#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003827#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003828 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3829 {
3830 tANI_U8 *value = command;
3831 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3832 tANI_U8 numChannels = 0;
3833 eHalStatus status = eHAL_STATUS_SUCCESS;
3834
3835 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3836 if (eHAL_STATUS_SUCCESS != status)
3837 {
3838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3839 "%s: Failed to parse channel list information", __func__);
3840 ret = -EINVAL;
3841 goto exit;
3842 }
3843
3844 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3845 {
3846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3848 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3849 ret = -EINVAL;
3850 goto exit;
3851 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003852 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003853 ChannelList,
3854 numChannels);
3855 if (eHAL_STATUS_SUCCESS != status)
3856 {
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3858 "%s: Failed to update channel list information", __func__);
3859 ret = -EINVAL;
3860 goto exit;
3861 }
3862 }
3863 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3864 {
3865 tANI_U8 *value = command;
3866 char extra[128] = {0};
3867 int len = 0;
3868 tANI_U8 tid = 0;
3869 hdd_station_ctx_t *pHddStaCtx = NULL;
3870 tAniTrafStrmMetrics tsmMetrics;
3871 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3872
3873 /* if not associated, return error */
3874 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3875 {
3876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3877 ret = -EINVAL;
3878 goto exit;
3879 }
3880
3881 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3882 value = value + 12;
3883 /* Convert the value from ascii to integer */
3884 ret = kstrtou8(value, 10, &tid);
3885 if (ret < 0)
3886 {
3887 /* If the input value is greater than max value of datatype, then also
3888 kstrtou8 fails */
3889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3890 "%s: kstrtou8 failed range [%d - %d]", __func__,
3891 TID_MIN_VALUE,
3892 TID_MAX_VALUE);
3893 ret = -EINVAL;
3894 goto exit;
3895 }
3896
3897 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3898 {
3899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3900 "tid value %d is out of range"
3901 " (Min: %d Max: %d)", tid,
3902 TID_MIN_VALUE,
3903 TID_MAX_VALUE);
3904 ret = -EINVAL;
3905 goto exit;
3906 }
3907
3908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3909 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3910
3911 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3912 {
3913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 "%s: failed to get tsm stats", __func__);
3915 ret = -EFAULT;
3916 goto exit;
3917 }
3918
3919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3920 "UplinkPktQueueDly(%d)\n"
3921 "UplinkPktQueueDlyHist[0](%d)\n"
3922 "UplinkPktQueueDlyHist[1](%d)\n"
3923 "UplinkPktQueueDlyHist[2](%d)\n"
3924 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303925 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003926 "UplinkPktLoss(%d)\n"
3927 "UplinkPktCount(%d)\n"
3928 "RoamingCount(%d)\n"
3929 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3930 tsmMetrics.UplinkPktQueueDlyHist[0],
3931 tsmMetrics.UplinkPktQueueDlyHist[1],
3932 tsmMetrics.UplinkPktQueueDlyHist[2],
3933 tsmMetrics.UplinkPktQueueDlyHist[3],
3934 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3935 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3936
3937 /* Output TSM stats is of the format
3938 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3939 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003940 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003941 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3942 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3943 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3944 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3945 tsmMetrics.RoamingDly);
3946
3947 if (copy_to_user(priv_data.buf, &extra, len + 1))
3948 {
3949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3950 "%s: failed to copy data to user buffer", __func__);
3951 ret = -EFAULT;
3952 goto exit;
3953 }
3954 }
3955 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3956 {
3957 tANI_U8 *value = command;
3958 tANI_U8 *cckmIe = NULL;
3959 tANI_U8 cckmIeLen = 0;
3960 eHalStatus status = eHAL_STATUS_SUCCESS;
3961
3962 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3963 if (eHAL_STATUS_SUCCESS != status)
3964 {
3965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3966 "%s: Failed to parse cckm ie data", __func__);
3967 ret = -EINVAL;
3968 goto exit;
3969 }
3970
3971 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3972 {
3973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3974 "%s: CCKM Ie input length is more than max[%d]", __func__,
3975 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003976 vos_mem_free(cckmIe);
3977 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003978 ret = -EINVAL;
3979 goto exit;
3980 }
3981 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003982 vos_mem_free(cckmIe);
3983 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003984 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003985 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3986 {
3987 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003988 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003989 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003990
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003991 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003992 if (eHAL_STATUS_SUCCESS != status)
3993 {
3994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003995 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003996 ret = -EINVAL;
3997 goto exit;
3998 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003999 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4000 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4001 hdd_indicateEseBcnReportNoResults (pAdapter,
4002 eseBcnReq.bcnReq[0].measurementToken,
4003 0x02, //BIT(1) set for measurement done
4004 0); // no BSS
4005 goto exit;
4006 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004007
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004008 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4009 if (eHAL_STATUS_SUCCESS != status)
4010 {
4011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4012 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4013 ret = -EINVAL;
4014 goto exit;
4015 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004016 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004017#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304018 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4019 {
4020 eHalStatus status;
4021 char buf[32], len;
4022 long waitRet;
4023 bcnMissRateContext_t getBcnMissRateCtx;
4024
4025 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4026
4027 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4028 {
4029 hddLog(VOS_TRACE_LEVEL_WARN,
4030 FL("GETBCNMISSRATE: STA is not in connected state"));
4031 ret = -1;
4032 goto exit;
4033 }
4034
4035 init_completion(&(getBcnMissRateCtx.completion));
4036 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4037
4038 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4039 pAdapter->sessionId,
4040 (void *)getBcnMissRateCB,
4041 (void *)(&getBcnMissRateCtx));
4042 if( eHAL_STATUS_SUCCESS != status)
4043 {
4044 hddLog(VOS_TRACE_LEVEL_INFO,
4045 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4046 ret = -EINVAL;
4047 goto exit;
4048 }
4049
4050 waitRet = wait_for_completion_interruptible_timeout
4051 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4052 if(waitRet <= 0)
4053 {
4054 hddLog(VOS_TRACE_LEVEL_ERROR,
4055 FL("failed to wait on bcnMissRateComp %d"), ret);
4056
4057 //Make magic number to zero so that callback is not called.
4058 spin_lock(&hdd_context_lock);
4059 getBcnMissRateCtx.magic = 0x0;
4060 spin_unlock(&hdd_context_lock);
4061 ret = -EINVAL;
4062 goto exit;
4063 }
4064
4065 hddLog(VOS_TRACE_LEVEL_INFO,
4066 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4067
4068 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4069 if (copy_to_user(priv_data.buf, &buf, len + 1))
4070 {
4071 hddLog(VOS_TRACE_LEVEL_ERROR,
4072 "%s: failed to copy data to user buffer", __func__);
4073 ret = -EFAULT;
4074 goto exit;
4075 }
4076 ret = len;
4077 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004078 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4080 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4081 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004082 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4083 __func__, command);
4084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 }
4086exit:
4087 if (command)
4088 {
4089 kfree(command);
4090 }
4091 return ret;
4092}
4093
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004094#ifdef CONFIG_COMPAT
4095static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4096{
4097 struct {
4098 compat_uptr_t buf;
4099 int used_len;
4100 int total_len;
4101 } compat_priv_data;
4102 hdd_priv_data_t priv_data;
4103 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004104
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004105 /*
4106 * Note that pAdapter and ifr have already been verified by caller,
4107 * and HDD context has also been validated
4108 */
4109 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4110 sizeof(compat_priv_data))) {
4111 ret = -EFAULT;
4112 goto exit;
4113 }
4114 priv_data.buf = compat_ptr(compat_priv_data.buf);
4115 priv_data.used_len = compat_priv_data.used_len;
4116 priv_data.total_len = compat_priv_data.total_len;
4117 ret = hdd_driver_command(pAdapter, &priv_data);
4118 exit:
4119 return ret;
4120}
4121#else /* CONFIG_COMPAT */
4122static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4123{
4124 /* will never be invoked */
4125 return 0;
4126}
4127#endif /* CONFIG_COMPAT */
4128
4129static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4130{
4131 hdd_priv_data_t priv_data;
4132 int ret = 0;
4133
4134 /*
4135 * Note that pAdapter and ifr have already been verified by caller,
4136 * and HDD context has also been validated
4137 */
4138 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4139 ret = -EFAULT;
4140 } else {
4141 ret = hdd_driver_command(pAdapter, &priv_data);
4142 }
4143 return ret;
4144}
4145
4146int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4147{
4148 hdd_adapter_t *pAdapter;
4149 hdd_context_t *pHddCtx;
4150 int ret;
4151
4152 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4153 if (NULL == pAdapter) {
4154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4155 "%s: HDD adapter context is Null", __func__);
4156 ret = -ENODEV;
4157 goto exit;
4158 }
4159 if (dev != pAdapter->dev) {
4160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4161 "%s: HDD adapter/dev inconsistency", __func__);
4162 ret = -ENODEV;
4163 goto exit;
4164 }
4165
4166 if ((!ifr) || (!ifr->ifr_data)) {
4167 ret = -EINVAL;
4168 goto exit;
4169 }
4170
4171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4172 ret = wlan_hdd_validate_context(pHddCtx);
4173 if (ret) {
4174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4175 "%s: invalid context", __func__);
4176 ret = -EBUSY;
4177 goto exit;
4178 }
4179
4180 switch (cmd) {
4181 case (SIOCDEVPRIVATE + 1):
4182 if (is_compat_task())
4183 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4184 else
4185 ret = hdd_driver_ioctl(pAdapter, ifr);
4186 break;
4187 default:
4188 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4189 __func__, cmd);
4190 ret = -EINVAL;
4191 break;
4192 }
4193 exit:
4194 return ret;
4195}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004196
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004197#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004198/**---------------------------------------------------------------------------
4199
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004200 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004201
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004202 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004203 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4204 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4205 <space>Scan Mode N<space>Meas Duration N
4206 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4207 then take N.
4208 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4209 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4210 This function does not take care of removing duplicate channels from the list
4211
4212 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004213 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004214
4215 \return - 0 for success non-zero for failure
4216
4217 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004218static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4219 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004220{
4221 tANI_U8 *inPtr = pValue;
4222 int tempInt = 0;
4223 int j = 0, i = 0, v = 0;
4224 char buf[32];
4225
4226 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4227 /*no argument after the command*/
4228 if (NULL == inPtr)
4229 {
4230 return -EINVAL;
4231 }
4232 /*no space after the command*/
4233 else if (SPACE_ASCII_VALUE != *inPtr)
4234 {
4235 return -EINVAL;
4236 }
4237
4238 /*removing empty spaces*/
4239 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4240
4241 /*no argument followed by spaces*/
4242 if ('\0' == *inPtr) return -EINVAL;
4243
4244 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004245 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004246 if (1 != v) return -EINVAL;
4247
4248 v = kstrtos32(buf, 10, &tempInt);
4249 if ( v < 0) return -EINVAL;
4250
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004251 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004252
4253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004254 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004255
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004256 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004257 {
4258 for (i = 0; i < 4; i++)
4259 {
4260 /*inPtr pointing to the beginning of first space after number of ie fields*/
4261 inPtr = strpbrk( inPtr, " " );
4262 /*no ie data after the number of ie fields argument*/
4263 if (NULL == inPtr) return -EINVAL;
4264
4265 /*removing empty space*/
4266 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4267
4268 /*no ie data after the number of ie fields argument and spaces*/
4269 if ( '\0' == *inPtr ) return -EINVAL;
4270
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004271 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004272 if (1 != v) return -EINVAL;
4273
4274 v = kstrtos32(buf, 10, &tempInt);
4275 if (v < 0) return -EINVAL;
4276
4277 switch (i)
4278 {
4279 case 0: /* Measurement token */
4280 if (tempInt <= 0)
4281 {
4282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4283 "Invalid Measurement Token(%d)", tempInt);
4284 return -EINVAL;
4285 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004286 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004287 break;
4288
4289 case 1: /* Channel number */
4290 if ((tempInt <= 0) ||
4291 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4292 {
4293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4294 "Invalid Channel Number(%d)", tempInt);
4295 return -EINVAL;
4296 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004297 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004298 break;
4299
4300 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004301 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004302 {
4303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4304 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4305 return -EINVAL;
4306 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004307 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004308 break;
4309
4310 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004311 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4312 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004313 {
4314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4315 "Invalid Measurement Duration(%d)", tempInt);
4316 return -EINVAL;
4317 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004318 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004319 break;
4320 }
4321 }
4322 }
4323
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004324 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004325 {
4326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304327 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004328 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004329 pEseBcnReq->bcnReq[j].measurementToken,
4330 pEseBcnReq->bcnReq[j].channel,
4331 pEseBcnReq->bcnReq[j].scanMode,
4332 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004333 }
4334
4335 return VOS_STATUS_SUCCESS;
4336}
4337
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004338static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4339{
4340 struct statsContext *pStatsContext = NULL;
4341 hdd_adapter_t *pAdapter = NULL;
4342
4343 if (NULL == pContext)
4344 {
4345 hddLog(VOS_TRACE_LEVEL_ERROR,
4346 "%s: Bad param, pContext [%p]",
4347 __func__, pContext);
4348 return;
4349 }
4350
Jeff Johnson72a40512013-12-19 10:14:15 -08004351 /* there is a race condition that exists between this callback
4352 function and the caller since the caller could time out either
4353 before or while this code is executing. we use a spinlock to
4354 serialize these actions */
4355 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004356
4357 pStatsContext = pContext;
4358 pAdapter = pStatsContext->pAdapter;
4359 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4360 {
4361 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004362 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004363 hddLog(VOS_TRACE_LEVEL_WARN,
4364 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4365 __func__, pAdapter, pStatsContext->magic);
4366 return;
4367 }
4368
Jeff Johnson72a40512013-12-19 10:14:15 -08004369 /* context is valid so caller is still waiting */
4370
4371 /* paranoia: invalidate the magic */
4372 pStatsContext->magic = 0;
4373
4374 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004375 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4376 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4377 tsmMetrics.UplinkPktQueueDlyHist,
4378 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4379 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4380 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4381 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4382 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4383 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4384 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4385
Jeff Johnson72a40512013-12-19 10:14:15 -08004386 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004387 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004388
4389 /* serialization is complete */
4390 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004391}
4392
4393
4394
4395static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4396 tAniTrafStrmMetrics* pTsmMetrics)
4397{
4398 hdd_station_ctx_t *pHddStaCtx = NULL;
4399 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004400 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004401 long lrc;
4402 struct statsContext context;
4403 hdd_context_t *pHddCtx = NULL;
4404
4405 if (NULL == pAdapter)
4406 {
4407 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4408 return VOS_STATUS_E_FAULT;
4409 }
4410
4411 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4412 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4413
4414 /* we are connected prepare our callback context */
4415 init_completion(&context.completion);
4416 context.pAdapter = pAdapter;
4417 context.magic = STATS_CONTEXT_MAGIC;
4418
4419 /* query tsm stats */
4420 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4421 pHddStaCtx->conn_info.staId[ 0 ],
4422 pHddStaCtx->conn_info.bssId,
4423 &context, pHddCtx->pvosContext, tid);
4424
4425 if (eHAL_STATUS_SUCCESS != hstatus)
4426 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4428 __func__);
4429 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004430 }
4431 else
4432 {
4433 /* request was sent -- wait for the response */
4434 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4435 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004436 if (lrc <= 0)
4437 {
4438 hddLog(VOS_TRACE_LEVEL_ERROR,
4439 "%s: SME %s while retrieving statistics",
4440 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004441 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004442 }
4443 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004444
Jeff Johnson72a40512013-12-19 10:14:15 -08004445 /* either we never sent a request, we sent a request and received a
4446 response or we sent a request and timed out. if we never sent a
4447 request or if we sent a request and got a response, we want to
4448 clear the magic out of paranoia. if we timed out there is a
4449 race condition such that the callback function could be
4450 executing at the same time we are. of primary concern is if the
4451 callback function had already verified the "magic" but had not
4452 yet set the completion variable when a timeout occurred. we
4453 serialize these activities by invalidating the magic while
4454 holding a shared spinlock which will cause us to block if the
4455 callback is currently executing */
4456 spin_lock(&hdd_context_lock);
4457 context.magic = 0;
4458 spin_unlock(&hdd_context_lock);
4459
4460 if (VOS_STATUS_SUCCESS == vstatus)
4461 {
4462 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4463 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4464 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4465 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4466 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4467 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4468 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4469 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4470 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4471 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4472 }
4473 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004474}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004475#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004476
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004477#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004478void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4479{
4480 eCsrBand band = -1;
4481 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4482 switch (band)
4483 {
4484 case eCSR_BAND_ALL:
4485 *pBand = WLAN_HDD_UI_BAND_AUTO;
4486 break;
4487
4488 case eCSR_BAND_24:
4489 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4490 break;
4491
4492 case eCSR_BAND_5G:
4493 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4494 break;
4495
4496 default:
4497 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4498 *pBand = -1;
4499 break;
4500 }
4501}
4502
4503/**---------------------------------------------------------------------------
4504
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004505 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4506
4507 This function parses the send action frame data passed in the format
4508 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4509
Srinivas Girigowda56076852013-08-20 14:00:50 -07004510 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004511 \param - pTargetApBssid Pointer to target Ap bssid
4512 \param - pChannel Pointer to the Target AP channel
4513 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4514 \param - pBuf Pointer to data
4515 \param - pBufLen Pointer to data length
4516
4517 \return - 0 for success non-zero for failure
4518
4519 --------------------------------------------------------------------------*/
4520VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4521 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4522{
4523 tANI_U8 *inPtr = pValue;
4524 tANI_U8 *dataEnd;
4525 int tempInt;
4526 int j = 0;
4527 int i = 0;
4528 int v = 0;
4529 tANI_U8 tempBuf[32];
4530 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004531 /* 12 hexa decimal digits, 5 ':' and '\0' */
4532 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004533
4534 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4535 /*no argument after the command*/
4536 if (NULL == inPtr)
4537 {
4538 return -EINVAL;
4539 }
4540
4541 /*no space after the command*/
4542 else if (SPACE_ASCII_VALUE != *inPtr)
4543 {
4544 return -EINVAL;
4545 }
4546
4547 /*removing empty spaces*/
4548 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4549
4550 /*no argument followed by spaces*/
4551 if ('\0' == *inPtr)
4552 {
4553 return -EINVAL;
4554 }
4555
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004556 v = sscanf(inPtr, "%17s", macAddress);
4557 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004558 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4560 "Invalid MAC address or All hex inputs are not read (%d)", v);
4561 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004562 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004563
4564 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4565 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4566 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4567 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4568 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4569 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004570
4571 /* point to the next argument */
4572 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4573 /*no argument after the command*/
4574 if (NULL == inPtr) return -EINVAL;
4575
4576 /*removing empty spaces*/
4577 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4578
4579 /*no argument followed by spaces*/
4580 if ('\0' == *inPtr)
4581 {
4582 return -EINVAL;
4583 }
4584
4585 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004586 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004587 if (1 != v) return -EINVAL;
4588
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004589 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304590 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304591 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004592
4593 *pChannel = tempInt;
4594
4595 /* point to the next argument */
4596 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4597 /*no argument after the command*/
4598 if (NULL == inPtr) return -EINVAL;
4599 /*removing empty spaces*/
4600 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4601
4602 /*no argument followed by spaces*/
4603 if ('\0' == *inPtr)
4604 {
4605 return -EINVAL;
4606 }
4607
4608 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004609 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004610 if (1 != v) return -EINVAL;
4611
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004612 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004613 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004614
4615 *pDwellTime = tempInt;
4616
4617 /* point to the next argument */
4618 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4619 /*no argument after the command*/
4620 if (NULL == inPtr) return -EINVAL;
4621 /*removing empty spaces*/
4622 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4623
4624 /*no argument followed by spaces*/
4625 if ('\0' == *inPtr)
4626 {
4627 return -EINVAL;
4628 }
4629
4630 /* find the length of data */
4631 dataEnd = inPtr;
4632 while(('\0' != *dataEnd) )
4633 {
4634 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004635 }
Kiet Lambe150c22013-11-21 16:30:32 +05304636 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004637 if ( *pBufLen <= 0) return -EINVAL;
4638
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004639 /* Allocate the number of bytes based on the number of input characters
4640 whether it is even or odd.
4641 if the number of input characters are even, then we need N/2 byte.
4642 if the number of input characters are odd, then we need do (N+1)/2 to
4643 compensate rounding off.
4644 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4645 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4646 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004647 if (NULL == *pBuf)
4648 {
4649 hddLog(VOS_TRACE_LEVEL_FATAL,
4650 "%s: vos_mem_alloc failed ", __func__);
4651 return -EINVAL;
4652 }
4653
4654 /* the buffer received from the upper layer is character buffer,
4655 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4656 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4657 and f0 in 3rd location */
4658 for (i = 0, j = 0; j < *pBufLen; j += 2)
4659 {
Kiet Lambe150c22013-11-21 16:30:32 +05304660 if( j+1 == *pBufLen)
4661 {
4662 tempByte = hdd_parse_hex(inPtr[j]);
4663 }
4664 else
4665 {
4666 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4667 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004668 (*pBuf)[i++] = tempByte;
4669 }
4670 *pBufLen = i;
4671 return VOS_STATUS_SUCCESS;
4672}
4673
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004674/**---------------------------------------------------------------------------
4675
Srinivas Girigowdade697412013-02-14 16:31:48 -08004676 \brief hdd_parse_channellist() - HDD Parse channel list
4677
4678 This function parses the channel list passed in the format
4679 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004680 if the Number of channels (N) does not match with the actual number of channels passed
4681 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4682 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4683 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4684 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004685
4686 \param - pValue Pointer to input channel list
4687 \param - ChannelList Pointer to local output array to record channel list
4688 \param - pNumChannels Pointer to number of roam scan channels
4689
4690 \return - 0 for success non-zero for failure
4691
4692 --------------------------------------------------------------------------*/
4693VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4694{
4695 tANI_U8 *inPtr = pValue;
4696 int tempInt;
4697 int j = 0;
4698 int v = 0;
4699 char buf[32];
4700
4701 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4702 /*no argument after the command*/
4703 if (NULL == inPtr)
4704 {
4705 return -EINVAL;
4706 }
4707
4708 /*no space after the command*/
4709 else if (SPACE_ASCII_VALUE != *inPtr)
4710 {
4711 return -EINVAL;
4712 }
4713
4714 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004715 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004716
4717 /*no argument followed by spaces*/
4718 if ('\0' == *inPtr)
4719 {
4720 return -EINVAL;
4721 }
4722
4723 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004724 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004725 if (1 != v) return -EINVAL;
4726
Srinivas Girigowdade697412013-02-14 16:31:48 -08004727 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004728 if ((v < 0) ||
4729 (tempInt <= 0) ||
4730 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4731 {
4732 return -EINVAL;
4733 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004734
4735 *pNumChannels = tempInt;
4736
4737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4738 "Number of channels are: %d", *pNumChannels);
4739
4740 for (j = 0; j < (*pNumChannels); j++)
4741 {
4742 /*inPtr pointing to the beginning of first space after number of channels*/
4743 inPtr = strpbrk( inPtr, " " );
4744 /*no channel list after the number of channels argument*/
4745 if (NULL == inPtr)
4746 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004747 if (0 != j)
4748 {
4749 *pNumChannels = j;
4750 return VOS_STATUS_SUCCESS;
4751 }
4752 else
4753 {
4754 return -EINVAL;
4755 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004756 }
4757
4758 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004759 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004760
4761 /*no channel list after the number of channels argument and spaces*/
4762 if ( '\0' == *inPtr )
4763 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004764 if (0 != j)
4765 {
4766 *pNumChannels = j;
4767 return VOS_STATUS_SUCCESS;
4768 }
4769 else
4770 {
4771 return -EINVAL;
4772 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004773 }
4774
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004775 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004776 if (1 != v) return -EINVAL;
4777
Srinivas Girigowdade697412013-02-14 16:31:48 -08004778 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004779 if ((v < 0) ||
4780 (tempInt <= 0) ||
4781 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4782 {
4783 return -EINVAL;
4784 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004785 pChannelList[j] = tempInt;
4786
4787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4788 "Channel %d added to preferred channel list",
4789 pChannelList[j] );
4790 }
4791
Srinivas Girigowdade697412013-02-14 16:31:48 -08004792 return VOS_STATUS_SUCCESS;
4793}
4794
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004795
4796/**---------------------------------------------------------------------------
4797
4798 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4799
4800 This function parses the reasoc command data passed in the format
4801 REASSOC<space><bssid><space><channel>
4802
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004803 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004804 \param - pTargetApBssid Pointer to target Ap bssid
4805 \param - pChannel Pointer to the Target AP channel
4806
4807 \return - 0 for success non-zero for failure
4808
4809 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004810VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4811 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004812{
4813 tANI_U8 *inPtr = pValue;
4814 int tempInt;
4815 int v = 0;
4816 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004817 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004818 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004819
4820 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4821 /*no argument after the command*/
4822 if (NULL == inPtr)
4823 {
4824 return -EINVAL;
4825 }
4826
4827 /*no space after the command*/
4828 else if (SPACE_ASCII_VALUE != *inPtr)
4829 {
4830 return -EINVAL;
4831 }
4832
4833 /*removing empty spaces*/
4834 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4835
4836 /*no argument followed by spaces*/
4837 if ('\0' == *inPtr)
4838 {
4839 return -EINVAL;
4840 }
4841
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004842 v = sscanf(inPtr, "%17s", macAddress);
4843 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004844 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4846 "Invalid MAC address or All hex inputs are not read (%d)", v);
4847 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004848 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004849
4850 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4851 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4852 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4853 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4854 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4855 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004856
4857 /* point to the next argument */
4858 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4859 /*no argument after the command*/
4860 if (NULL == inPtr) return -EINVAL;
4861
4862 /*removing empty spaces*/
4863 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4864
4865 /*no argument followed by spaces*/
4866 if ('\0' == *inPtr)
4867 {
4868 return -EINVAL;
4869 }
4870
4871 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004872 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004873 if (1 != v) return -EINVAL;
4874
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004875 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004876 if ((v < 0) ||
4877 (tempInt <= 0) ||
4878 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4879 {
4880 return -EINVAL;
4881 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004882
4883 *pChannel = tempInt;
4884 return VOS_STATUS_SUCCESS;
4885}
4886
4887#endif
4888
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004889#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004890/**---------------------------------------------------------------------------
4891
4892 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4893
4894 This function parses the SETCCKM IE command
4895 SETCCKMIE<space><ie data>
4896
4897 \param - pValue Pointer to input data
4898 \param - pCckmIe Pointer to output cckm Ie
4899 \param - pCckmIeLen Pointer to output cckm ie length
4900
4901 \return - 0 for success non-zero for failure
4902
4903 --------------------------------------------------------------------------*/
4904VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4905 tANI_U8 *pCckmIeLen)
4906{
4907 tANI_U8 *inPtr = pValue;
4908 tANI_U8 *dataEnd;
4909 int j = 0;
4910 int i = 0;
4911 tANI_U8 tempByte = 0;
4912
4913 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4914 /*no argument after the command*/
4915 if (NULL == inPtr)
4916 {
4917 return -EINVAL;
4918 }
4919
4920 /*no space after the command*/
4921 else if (SPACE_ASCII_VALUE != *inPtr)
4922 {
4923 return -EINVAL;
4924 }
4925
4926 /*removing empty spaces*/
4927 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4928
4929 /*no argument followed by spaces*/
4930 if ('\0' == *inPtr)
4931 {
4932 return -EINVAL;
4933 }
4934
4935 /* find the length of data */
4936 dataEnd = inPtr;
4937 while(('\0' != *dataEnd) )
4938 {
4939 dataEnd++;
4940 ++(*pCckmIeLen);
4941 }
4942 if ( *pCckmIeLen <= 0) return -EINVAL;
4943
4944 /* Allocate the number of bytes based on the number of input characters
4945 whether it is even or odd.
4946 if the number of input characters are even, then we need N/2 byte.
4947 if the number of input characters are odd, then we need do (N+1)/2 to
4948 compensate rounding off.
4949 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4950 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4951 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4952 if (NULL == *pCckmIe)
4953 {
4954 hddLog(VOS_TRACE_LEVEL_FATAL,
4955 "%s: vos_mem_alloc failed ", __func__);
4956 return -EINVAL;
4957 }
4958 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4959 /* the buffer received from the upper layer is character buffer,
4960 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4961 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4962 and f0 in 3rd location */
4963 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4964 {
4965 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4966 (*pCckmIe)[i++] = tempByte;
4967 }
4968 *pCckmIeLen = i;
4969
4970 return VOS_STATUS_SUCCESS;
4971}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004972#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004973
Jeff Johnson295189b2012-06-20 16:38:30 -07004974/**---------------------------------------------------------------------------
4975
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004976 \brief hdd_is_valid_mac_address() - Validate MAC address
4977
4978 This function validates whether the given MAC address is valid or not
4979 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4980 where X is the hexa decimal digit character and separated by ':'
4981 This algorithm works even if MAC address is not separated by ':'
4982
4983 This code checks given input string mac contains exactly 12 hexadecimal digits.
4984 and a separator colon : appears in the input string only after
4985 an even number of hex digits.
4986
4987 \param - pMacAddr pointer to the input MAC address
4988 \return - 1 for valid and 0 for invalid
4989
4990 --------------------------------------------------------------------------*/
4991
4992v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4993{
4994 int xdigit = 0;
4995 int separator = 0;
4996 while (*pMacAddr)
4997 {
4998 if (isxdigit(*pMacAddr))
4999 {
5000 xdigit++;
5001 }
5002 else if (':' == *pMacAddr)
5003 {
5004 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5005 break;
5006
5007 ++separator;
5008 }
5009 else
5010 {
5011 separator = -1;
5012 /* Invalid MAC found */
5013 return 0;
5014 }
5015 ++pMacAddr;
5016 }
5017 return (xdigit == 12 && (separator == 5 || separator == 0));
5018}
5019
5020/**---------------------------------------------------------------------------
5021
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 \brief hdd_open() - HDD Open function
5023
5024 This is called in response to ifconfig up
5025
5026 \param - dev Pointer to net_device structure
5027
5028 \return - 0 for success non-zero for failure
5029
5030 --------------------------------------------------------------------------*/
5031int hdd_open (struct net_device *dev)
5032{
5033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5034 hdd_context_t *pHddCtx;
5035 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5036 VOS_STATUS status;
5037 v_BOOL_t in_standby = TRUE;
5038
5039 if (NULL == pAdapter)
5040 {
5041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305042 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005043 return -ENODEV;
5044 }
5045
5046 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305047 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5048 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 if (NULL == pHddCtx)
5050 {
5051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005052 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005053 return -ENODEV;
5054 }
5055
5056 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5057 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5058 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005059 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5060 {
5061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305062 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005063 in_standby = FALSE;
5064 break;
5065 }
5066 else
5067 {
5068 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5069 pAdapterNode = pNext;
5070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 }
5072
5073 if (TRUE == in_standby)
5074 {
5075 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5076 {
5077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5078 "wlan out of power save", __func__);
5079 return -EINVAL;
5080 }
5081 }
5082
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005083 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5085 {
5086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005087 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 /* Enable TX queues only when we are connected */
5089 netif_tx_start_all_queues(dev);
5090 }
5091
5092 return 0;
5093}
5094
5095int hdd_mon_open (struct net_device *dev)
5096{
5097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5098
5099 if(pAdapter == NULL) {
5100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005101 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005102 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005103 }
5104
5105 netif_start_queue(dev);
5106
5107 return 0;
5108}
5109/**---------------------------------------------------------------------------
5110
5111 \brief hdd_stop() - HDD stop function
5112
5113 This is called in response to ifconfig down
5114
5115 \param - dev Pointer to net_device structure
5116
5117 \return - 0 for success non-zero for failure
5118
5119 --------------------------------------------------------------------------*/
5120
5121int hdd_stop (struct net_device *dev)
5122{
5123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5124 hdd_context_t *pHddCtx;
5125 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5126 VOS_STATUS status;
5127 v_BOOL_t enter_standby = TRUE;
5128
5129 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 if (NULL == pAdapter)
5131 {
5132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305133 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 return -ENODEV;
5135 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305136 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5137 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5139 if (NULL == pHddCtx)
5140 {
5141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005142 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005143 return -ENODEV;
5144 }
5145
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305146 /* Nothing to be done if the interface is not opened */
5147 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5148 {
5149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5150 "%s: NETDEV Interface is not OPENED", __func__);
5151 return -ENODEV;
5152 }
5153
5154 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005155 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305157
5158 /* Disable TX on the interface, after this hard_start_xmit() will not
5159 * be called on that interface
5160 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005161 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305162
5163 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 netif_carrier_off(pAdapter->dev);
5165
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305166 /* The interface is marked as down for outside world (aka kernel)
5167 * But the driver is pretty much alive inside. The driver needs to
5168 * tear down the existing connection on the netdev (session)
5169 * cleanup the data pipes and wait until the control plane is stabilized
5170 * for this interface. The call also needs to wait until the above
5171 * mentioned actions are completed before returning to the caller.
5172 * Notice that the hdd_stop_adapter is requested not to close the session
5173 * That is intentional to be able to scan if it is a STA/P2P interface
5174 */
5175 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005176
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305177 /* DeInit the adapter. This ensures datapath cleanup as well */
5178 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 /* SoftAP ifaces should never go in power save mode
5180 making sure same here. */
5181 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5182 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005183 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005184 )
5185 {
5186 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5188 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 EXIT();
5190 return 0;
5191 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305192 /* Find if any iface is up. If any iface is up then can't put device to
5193 * sleep/power save mode
5194 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5196 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5197 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005198 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5199 {
5200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305201 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005202 enter_standby = FALSE;
5203 break;
5204 }
5205 else
5206 {
5207 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5208 pAdapterNode = pNext;
5209 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 }
5211
5212 if (TRUE == enter_standby)
5213 {
5214 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5215 "entering standby", __func__);
5216 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5217 {
5218 /*log and return success*/
5219 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5220 "wlan in power save", __func__);
5221 }
5222 }
5223
5224 EXIT();
5225 return 0;
5226}
5227
5228/**---------------------------------------------------------------------------
5229
5230 \brief hdd_uninit() - HDD uninit function
5231
5232 This is called during the netdev unregister to uninitialize all data
5233associated with the device
5234
5235 \param - dev Pointer to net_device structure
5236
5237 \return - void
5238
5239 --------------------------------------------------------------------------*/
5240static void hdd_uninit (struct net_device *dev)
5241{
5242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5243
5244 ENTER();
5245
5246 do
5247 {
5248 if (NULL == pAdapter)
5249 {
5250 hddLog(VOS_TRACE_LEVEL_FATAL,
5251 "%s: NULL pAdapter", __func__);
5252 break;
5253 }
5254
5255 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5256 {
5257 hddLog(VOS_TRACE_LEVEL_FATAL,
5258 "%s: Invalid magic", __func__);
5259 break;
5260 }
5261
5262 if (NULL == pAdapter->pHddCtx)
5263 {
5264 hddLog(VOS_TRACE_LEVEL_FATAL,
5265 "%s: NULL pHddCtx", __func__);
5266 break;
5267 }
5268
5269 if (dev != pAdapter->dev)
5270 {
5271 hddLog(VOS_TRACE_LEVEL_FATAL,
5272 "%s: Invalid device reference", __func__);
5273 /* we haven't validated all cases so let this go for now */
5274 }
5275
5276 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5277
5278 /* after uninit our adapter structure will no longer be valid */
5279 pAdapter->dev = NULL;
5280 pAdapter->magic = 0;
5281 } while (0);
5282
5283 EXIT();
5284}
5285
5286/**---------------------------------------------------------------------------
5287
5288 \brief hdd_release_firmware() -
5289
5290 This function calls the release firmware API to free the firmware buffer.
5291
5292 \param - pFileName Pointer to the File Name.
5293 pCtx - Pointer to the adapter .
5294
5295
5296 \return - 0 for success, non zero for failure
5297
5298 --------------------------------------------------------------------------*/
5299
5300VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5301{
5302 VOS_STATUS status = VOS_STATUS_SUCCESS;
5303 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5304 ENTER();
5305
5306
5307 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5308
5309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5310
5311 if(pHddCtx->fw) {
5312 release_firmware(pHddCtx->fw);
5313 pHddCtx->fw = NULL;
5314 }
5315 else
5316 status = VOS_STATUS_E_FAILURE;
5317 }
5318 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5319 if(pHddCtx->nv) {
5320 release_firmware(pHddCtx->nv);
5321 pHddCtx->nv = NULL;
5322 }
5323 else
5324 status = VOS_STATUS_E_FAILURE;
5325
5326 }
5327
5328 EXIT();
5329 return status;
5330}
5331
5332/**---------------------------------------------------------------------------
5333
5334 \brief hdd_request_firmware() -
5335
5336 This function reads the firmware file using the request firmware
5337 API and returns the the firmware data and the firmware file size.
5338
5339 \param - pfileName - Pointer to the file name.
5340 - pCtx - Pointer to the adapter .
5341 - ppfw_data - Pointer to the pointer of the firmware data.
5342 - pSize - Pointer to the file size.
5343
5344 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5345
5346 --------------------------------------------------------------------------*/
5347
5348
5349VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5350{
5351 int status;
5352 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5353 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5354 ENTER();
5355
5356 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5357
5358 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5359
5360 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5361 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5362 __func__, pfileName);
5363 retval = VOS_STATUS_E_FAILURE;
5364 }
5365
5366 else {
5367 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5368 *pSize = pHddCtx->fw->size;
5369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5370 __func__, *pSize);
5371 }
5372 }
5373 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5374
5375 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5376
5377 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5378 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5379 __func__, pfileName);
5380 retval = VOS_STATUS_E_FAILURE;
5381 }
5382
5383 else {
5384 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5385 *pSize = pHddCtx->nv->size;
5386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5387 __func__, *pSize);
5388 }
5389 }
5390
5391 EXIT();
5392 return retval;
5393}
5394/**---------------------------------------------------------------------------
5395 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5396
5397 This is the function invoked by SME to inform the result of a full power
5398 request issued by HDD
5399
5400 \param - callbackcontext - Pointer to cookie
5401 status - result of request
5402
5403 \return - None
5404
5405--------------------------------------------------------------------------*/
5406void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5407{
5408 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5409
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005410 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005411 if(&pHddCtx->full_pwr_comp_var)
5412 {
5413 complete(&pHddCtx->full_pwr_comp_var);
5414 }
5415}
5416
5417/**---------------------------------------------------------------------------
5418
5419 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5420
5421 This is the function invoked by SME to inform the result of BMPS
5422 request issued by HDD
5423
5424 \param - callbackcontext - Pointer to cookie
5425 status - result of request
5426
5427 \return - None
5428
5429--------------------------------------------------------------------------*/
5430void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5431{
5432
5433 struct completion *completion_var = (struct completion*) callbackContext;
5434
Arif Hussain6d2a3322013-11-17 19:50:10 -08005435 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 if(completion_var != NULL)
5437 {
5438 complete(completion_var);
5439 }
5440}
5441
5442/**---------------------------------------------------------------------------
5443
5444 \brief hdd_get_cfg_file_size() -
5445
5446 This function reads the configuration file using the request firmware
5447 API and returns the configuration file size.
5448
5449 \param - pCtx - Pointer to the adapter .
5450 - pFileName - Pointer to the file name.
5451 - pBufSize - Pointer to the buffer size.
5452
5453 \return - 0 for success, non zero for failure
5454
5455 --------------------------------------------------------------------------*/
5456
5457VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5458{
5459 int status;
5460 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5461
5462 ENTER();
5463
5464 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5465
5466 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5467 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5468 status = VOS_STATUS_E_FAILURE;
5469 }
5470 else {
5471 *pBufSize = pHddCtx->fw->size;
5472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5473 release_firmware(pHddCtx->fw);
5474 pHddCtx->fw = NULL;
5475 }
5476
5477 EXIT();
5478 return VOS_STATUS_SUCCESS;
5479}
5480
5481/**---------------------------------------------------------------------------
5482
5483 \brief hdd_read_cfg_file() -
5484
5485 This function reads the configuration file using the request firmware
5486 API and returns the cfg data and the buffer size of the configuration file.
5487
5488 \param - pCtx - Pointer to the adapter .
5489 - pFileName - Pointer to the file name.
5490 - pBuffer - Pointer to the data buffer.
5491 - pBufSize - Pointer to the buffer size.
5492
5493 \return - 0 for success, non zero for failure
5494
5495 --------------------------------------------------------------------------*/
5496
5497VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5498 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5499{
5500 int status;
5501 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5502
5503 ENTER();
5504
5505 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5506
5507 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5508 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5509 return VOS_STATUS_E_FAILURE;
5510 }
5511 else {
5512 if(*pBufSize != pHddCtx->fw->size) {
5513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5514 "file size", __func__);
5515 release_firmware(pHddCtx->fw);
5516 pHddCtx->fw = NULL;
5517 return VOS_STATUS_E_FAILURE;
5518 }
5519 else {
5520 if(pBuffer) {
5521 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5522 }
5523 release_firmware(pHddCtx->fw);
5524 pHddCtx->fw = NULL;
5525 }
5526 }
5527
5528 EXIT();
5529
5530 return VOS_STATUS_SUCCESS;
5531}
5532
5533/**---------------------------------------------------------------------------
5534
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 \brief hdd_set_mac_address() -
5536
5537 This function sets the user specified mac address using
5538 the command ifconfig wlanX hw ether <mac adress>.
5539
5540 \param - dev - Pointer to the net device.
5541 - addr - Pointer to the sockaddr.
5542 \return - 0 for success, non zero for failure
5543
5544 --------------------------------------------------------------------------*/
5545
5546static int hdd_set_mac_address(struct net_device *dev, void *addr)
5547{
5548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5549 struct sockaddr *psta_mac_addr = addr;
5550 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5551
5552 ENTER();
5553
5554 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5556
5557 EXIT();
5558 return halStatus;
5559}
5560
5561tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5562{
5563 int i;
5564 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5565 {
Abhishek Singheb183782014-02-06 13:37:21 +05305566 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 break;
5568 }
5569
5570 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5571 return NULL;
5572
5573 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5574 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5575}
5576
5577void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5578{
5579 int i;
5580 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5581 {
5582 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5583 {
5584 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5585 break;
5586 }
5587 }
5588 return;
5589}
5590
5591#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5592 static struct net_device_ops wlan_drv_ops = {
5593 .ndo_open = hdd_open,
5594 .ndo_stop = hdd_stop,
5595 .ndo_uninit = hdd_uninit,
5596 .ndo_start_xmit = hdd_hard_start_xmit,
5597 .ndo_tx_timeout = hdd_tx_timeout,
5598 .ndo_get_stats = hdd_stats,
5599 .ndo_do_ioctl = hdd_ioctl,
5600 .ndo_set_mac_address = hdd_set_mac_address,
5601 .ndo_select_queue = hdd_select_queue,
5602#ifdef WLAN_FEATURE_PACKET_FILTERING
5603#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5604 .ndo_set_rx_mode = hdd_set_multicast_list,
5605#else
5606 .ndo_set_multicast_list = hdd_set_multicast_list,
5607#endif //LINUX_VERSION_CODE
5608#endif
5609 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 static struct net_device_ops wlan_mon_drv_ops = {
5611 .ndo_open = hdd_mon_open,
5612 .ndo_stop = hdd_stop,
5613 .ndo_uninit = hdd_uninit,
5614 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5615 .ndo_tx_timeout = hdd_tx_timeout,
5616 .ndo_get_stats = hdd_stats,
5617 .ndo_do_ioctl = hdd_ioctl,
5618 .ndo_set_mac_address = hdd_set_mac_address,
5619 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005620
5621#endif
5622
5623void hdd_set_station_ops( struct net_device *pWlanDev )
5624{
5625#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 pWlanDev->netdev_ops = &wlan_drv_ops;
5627#else
5628 pWlanDev->open = hdd_open;
5629 pWlanDev->stop = hdd_stop;
5630 pWlanDev->uninit = hdd_uninit;
5631 pWlanDev->hard_start_xmit = NULL;
5632 pWlanDev->tx_timeout = hdd_tx_timeout;
5633 pWlanDev->get_stats = hdd_stats;
5634 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 pWlanDev->set_mac_address = hdd_set_mac_address;
5636#endif
5637}
5638
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005639static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005640{
5641 struct net_device *pWlanDev = NULL;
5642 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 /*
5644 * cfg80211 initialization and registration....
5645 */
5646 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5647
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 if(pWlanDev != NULL)
5649 {
5650
5651 //Save the pointer to the net_device in the HDD adapter
5652 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5653
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5655
5656 pAdapter->dev = pWlanDev;
5657 pAdapter->pHddCtx = pHddCtx;
5658 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05305659 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07005660
5661 init_completion(&pAdapter->session_open_comp_var);
5662 init_completion(&pAdapter->session_close_comp_var);
5663 init_completion(&pAdapter->disconnect_comp_var);
5664 init_completion(&pAdapter->linkup_event_var);
5665 init_completion(&pAdapter->cancel_rem_on_chan_var);
5666 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305667 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5669 init_completion(&pAdapter->offchannel_tx_event);
5670#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005671 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005672#ifdef FEATURE_WLAN_TDLS
5673 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005674 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005675 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305676 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 init_completion(&pHddCtx->mc_sus_event_var);
5679 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305680 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005681 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005682 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005683
Rajeev79dbe4c2013-10-05 11:03:42 +05305684#ifdef FEATURE_WLAN_BATCH_SCAN
5685 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5686 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5687 pAdapter->pBatchScanRsp = NULL;
5688 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005689 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005690 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305691 mutex_init(&pAdapter->hdd_batch_scan_lock);
5692#endif
5693
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 pAdapter->isLinkUpSvcNeeded = FALSE;
5695 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5696 //Init the net_device structure
5697 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5698
5699 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5700 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5701 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5702 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5703
5704 hdd_set_station_ops( pAdapter->dev );
5705
5706 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5708 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5709 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 /* set pWlanDev's parent to underlying device */
5711 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005712
5713 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 }
5715
5716 return pAdapter;
5717}
5718
5719VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5720{
5721 struct net_device *pWlanDev = pAdapter->dev;
5722 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5723 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5724 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5725
5726 if( rtnl_lock_held )
5727 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005728 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5730 {
5731 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5732 return VOS_STATUS_E_FAILURE;
5733 }
5734 }
5735 if (register_netdevice(pWlanDev))
5736 {
5737 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5738 return VOS_STATUS_E_FAILURE;
5739 }
5740 }
5741 else
5742 {
5743 if(register_netdev(pWlanDev))
5744 {
5745 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5746 return VOS_STATUS_E_FAILURE;
5747 }
5748 }
5749 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5750
5751 return VOS_STATUS_SUCCESS;
5752}
5753
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005754static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005755{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005756 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005757
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005758 if (NULL == pAdapter)
5759 {
5760 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5761 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005763
5764 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5765 {
5766 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5767 return eHAL_STATUS_NOT_INITIALIZED;
5768 }
5769
5770 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5771
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005772#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005773 /* need to make sure all of our scheduled work has completed.
5774 * This callback is called from MC thread context, so it is safe to
5775 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005776 *
5777 * Even though this is called from MC thread context, if there is a faulty
5778 * work item in the system, that can hang this call forever. So flushing
5779 * this global work queue is not safe; and now we make sure that
5780 * individual work queues are stopped correctly. But the cancel work queue
5781 * is a GPL only API, so the proprietary version of the driver would still
5782 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005783 */
5784 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005785#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005786
5787 /* We can be blocked while waiting for scheduled work to be
5788 * flushed, and the adapter structure can potentially be freed, in
5789 * which case the magic will have been reset. So make sure the
5790 * magic is still good, and hence the adapter structure is still
5791 * valid, before signaling completion */
5792 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5793 {
5794 complete(&pAdapter->session_close_comp_var);
5795 }
5796
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 return eHAL_STATUS_SUCCESS;
5798}
5799
5800VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5801{
5802 struct net_device *pWlanDev = pAdapter->dev;
5803 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5804 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5805 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5806 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305807 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005808
5809 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005810 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 //Open a SME session for future operation
5812 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005813 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5815 {
5816 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005817 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 halStatus, halStatus );
5819 status = VOS_STATUS_E_FAILURE;
5820 goto error_sme_open;
5821 }
5822
5823 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305824 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 &pAdapter->session_open_comp_var,
5826 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305827 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 {
5829 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305830 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 status = VOS_STATUS_E_FAILURE;
5832 goto error_sme_open;
5833 }
5834
5835 // Register wireless extensions
5836 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5837 {
5838 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005839 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 halStatus, halStatus );
5841 status = VOS_STATUS_E_FAILURE;
5842 goto error_register_wext;
5843 }
5844 //Safe to register the hard_start_xmit function again
5845#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5846 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5847#else
5848 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5849#endif
5850
5851 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305852 hddLog(VOS_TRACE_LEVEL_INFO,
5853 "%s: Set HDD connState to eConnectionState_NotConnected",
5854 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5856
5857 //Set the default operation channel
5858 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5859
5860 /* Make the default Auth Type as OPEN*/
5861 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5862
5863 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5864 {
5865 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005866 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 status, status );
5868 goto error_init_txrx;
5869 }
5870
5871 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5872
5873 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5874 {
5875 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005876 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005877 status, status );
5878 goto error_wmm_init;
5879 }
5880
5881 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5882
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005883#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305884 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005885 {
5886 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305887 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005888 goto error_tdls_init;
5889 }
5890 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5891#endif
5892
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 return VOS_STATUS_SUCCESS;
5894
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005895#ifdef FEATURE_WLAN_TDLS
5896error_tdls_init:
5897 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5898 hdd_wmm_adapter_close(pAdapter);
5899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005900error_wmm_init:
5901 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5902 hdd_deinit_tx_rx(pAdapter);
5903error_init_txrx:
5904 hdd_UnregisterWext(pWlanDev);
5905error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005906 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 {
5908 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005909 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005911 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305913 unsigned long rc;
5914
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305916 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005918 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305919 if (rc <= 0)
5920 hddLog(VOS_TRACE_LEVEL_ERROR,
5921 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 }
5923}
5924error_sme_open:
5925 return status;
5926}
5927
Jeff Johnson295189b2012-06-20 16:38:30 -07005928void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5929{
5930 hdd_cfg80211_state_t *cfgState;
5931
5932 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5933
5934 if( NULL != cfgState->buf )
5935 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305936 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5938 rc = wait_for_completion_interruptible_timeout(
5939 &pAdapter->tx_action_cnf_event,
5940 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305941 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305944 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5945 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 }
5947 }
5948 return;
5949}
Jeff Johnson295189b2012-06-20 16:38:30 -07005950
5951void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5952{
5953 ENTER();
5954 switch ( pAdapter->device_mode )
5955 {
5956 case WLAN_HDD_INFRA_STATION:
5957 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005958 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005959 {
5960 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5961 {
5962 hdd_deinit_tx_rx( pAdapter );
5963 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5964 }
5965
5966 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5967 {
5968 hdd_wmm_adapter_close( pAdapter );
5969 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5970 }
5971
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005973#ifdef FEATURE_WLAN_TDLS
5974 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5975 {
5976 wlan_hdd_tdls_exit(pAdapter);
5977 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5978 }
5979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005980
5981 break;
5982 }
5983
5984 case WLAN_HDD_SOFTAP:
5985 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305987
5988 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5989 {
5990 hdd_wmm_adapter_close( pAdapter );
5991 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5992 }
5993
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005995
5996 hdd_unregister_hostapd(pAdapter);
5997 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005998 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 break;
6000 }
6001
6002 case WLAN_HDD_MONITOR:
6003 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6006 {
6007 hdd_deinit_tx_rx( pAdapter );
6008 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6009 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 if(NULL != pAdapterforTx)
6011 {
6012 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 break;
6015 }
6016
6017
6018 default:
6019 break;
6020 }
6021
6022 EXIT();
6023}
6024
6025void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6026{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006027 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306028
6029 ENTER();
6030 if (NULL == pAdapter)
6031 {
6032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6033 "%s: HDD adapter is Null", __func__);
6034 return;
6035 }
6036
6037 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006038
Rajeev79dbe4c2013-10-05 11:03:42 +05306039#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306040 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6041 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006042 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306043 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6044 )
6045 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006046 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306047 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006048 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6049 {
6050 hdd_deinit_batch_scan(pAdapter);
6051 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306052 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006053 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306054#endif
6055
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6057 if( rtnl_held )
6058 {
6059 unregister_netdevice(pWlanDev);
6060 }
6061 else
6062 {
6063 unregister_netdev(pWlanDev);
6064 }
6065 // note that the pAdapter is no longer valid at this point
6066 // since the memory has been reclaimed
6067 }
6068
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306069 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006070}
6071
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006072void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6073{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306074 VOS_STATUS status;
6075 hdd_adapter_t *pAdapter = NULL;
6076 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006077
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306078 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006079
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306080 /*loop through all adapters.*/
6081 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006082 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306083 pAdapter = pAdapterNode->pAdapter;
6084 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6085 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006086
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306087 { // we skip this registration for modes other than STA and P2P client modes.
6088 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6089 pAdapterNode = pNext;
6090 continue;
6091 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006092
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306093 //Apply Dynamic DTIM For P2P
6094 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6095 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6096 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6097 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6098 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6099 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6100 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6101 (eConnectionState_Associated ==
6102 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6103 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6104 {
6105 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006106
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306107 powerRequest.uIgnoreDTIM = 1;
6108 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6109
6110 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6111 {
6112 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6113 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6114 }
6115 else
6116 {
6117 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6118 }
6119
6120 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6121 * specified during Enter/Exit BMPS when LCD off*/
6122 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6123 NULL, eANI_BOOLEAN_FALSE);
6124 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6125 NULL, eANI_BOOLEAN_FALSE);
6126
6127 /* switch to the DTIM specified in cfg.ini */
6128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6129 "Switch to DTIM %d", powerRequest.uListenInterval);
6130 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6131 break;
6132
6133 }
6134
6135 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6136 pAdapterNode = pNext;
6137 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006138}
6139
6140void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6141{
6142 /*Switch back to DTIM 1*/
6143 tSirSetPowerParamsReq powerRequest = { 0 };
6144
6145 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6146 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006147 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006148
6149 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6150 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6151 NULL, eANI_BOOLEAN_FALSE);
6152 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6153 NULL, eANI_BOOLEAN_FALSE);
6154
6155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6156 "Switch to DTIM%d",powerRequest.uListenInterval);
6157 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6158
6159}
6160
Jeff Johnson295189b2012-06-20 16:38:30 -07006161VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6162{
6163 VOS_STATUS status = VOS_STATUS_SUCCESS;
6164
6165 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6166 {
6167 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6168 }
6169
6170 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6171 {
6172 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6173 }
6174
6175 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6176 {
6177 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6178 }
6179
6180 return status;
6181}
6182
6183VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6184{
6185 hdd_adapter_t *pAdapter = NULL;
6186 eHalStatus halStatus;
6187 VOS_STATUS status = VOS_STATUS_E_INVAL;
6188 v_BOOL_t disableBmps = FALSE;
6189 v_BOOL_t disableImps = FALSE;
6190
6191 switch(session_type)
6192 {
6193 case WLAN_HDD_INFRA_STATION:
6194 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 case WLAN_HDD_P2P_CLIENT:
6196 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 //Exit BMPS -> Is Sta/P2P Client is already connected
6198 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6199 if((NULL != pAdapter)&&
6200 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6201 {
6202 disableBmps = TRUE;
6203 }
6204
6205 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6206 if((NULL != pAdapter)&&
6207 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6208 {
6209 disableBmps = TRUE;
6210 }
6211
6212 //Exit both Bmps and Imps incase of Go/SAP Mode
6213 if((WLAN_HDD_SOFTAP == session_type) ||
6214 (WLAN_HDD_P2P_GO == session_type))
6215 {
6216 disableBmps = TRUE;
6217 disableImps = TRUE;
6218 }
6219
6220 if(TRUE == disableImps)
6221 {
6222 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6223 {
6224 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6225 }
6226 }
6227
6228 if(TRUE == disableBmps)
6229 {
6230 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6231 {
6232 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6233
6234 if(eHAL_STATUS_SUCCESS != halStatus)
6235 {
6236 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006237 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 VOS_ASSERT(0);
6239 return status;
6240 }
6241 }
6242
6243 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6244 {
6245 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6246
6247 if(eHAL_STATUS_SUCCESS != halStatus)
6248 {
6249 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006250 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 VOS_ASSERT(0);
6252 return status;
6253 }
6254 }
6255 }
6256
6257 if((TRUE == disableBmps) ||
6258 (TRUE == disableImps))
6259 {
6260 /* Now, get the chip into Full Power now */
6261 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6262 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6263 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6264
6265 if(halStatus != eHAL_STATUS_SUCCESS)
6266 {
6267 if(halStatus == eHAL_STATUS_PMC_PENDING)
6268 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306269 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306271 ret = wait_for_completion_interruptible_timeout(
6272 &pHddCtx->full_pwr_comp_var,
6273 msecs_to_jiffies(1000));
6274 if (ret <= 0)
6275 {
6276 hddLog(VOS_TRACE_LEVEL_ERROR,
6277 "%s: wait on full_pwr_comp_var failed %ld",
6278 __func__, ret);
6279 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 }
6281 else
6282 {
6283 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006284 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 VOS_ASSERT(0);
6286 return status;
6287 }
6288 }
6289
6290 status = VOS_STATUS_SUCCESS;
6291 }
6292
6293 break;
6294 }
6295 return status;
6296}
6297
6298hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006299 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 tANI_U8 rtnl_held )
6301{
6302 hdd_adapter_t *pAdapter = NULL;
6303 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6304 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6305 VOS_STATUS exitbmpsStatus;
6306
Arif Hussain6d2a3322013-11-17 19:50:10 -08006307 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006308
Nirav Shah436658f2014-02-28 17:05:45 +05306309 if(macAddr == NULL)
6310 {
6311 /* Not received valid macAddr */
6312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6313 "%s:Unable to add virtual intf: Not able to get"
6314 "valid mac address",__func__);
6315 return NULL;
6316 }
6317
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 //Disable BMPS incase of Concurrency
6319 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6320
6321 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6322 {
6323 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306324 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 VOS_ASSERT(0);
6326 return NULL;
6327 }
6328
6329 switch(session_type)
6330 {
6331 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006333 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 {
6335 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6336
6337 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306338 {
6339 hddLog(VOS_TRACE_LEVEL_FATAL,
6340 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006343
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306344#ifdef FEATURE_WLAN_TDLS
6345 /* A Mutex Lock is introduced while changing/initializing the mode to
6346 * protect the concurrent access for the Adapters by TDLS module.
6347 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306348 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306349#endif
6350
Jeff Johnsone7245742012-09-05 17:12:55 -07006351 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6352 NL80211_IFTYPE_P2P_CLIENT:
6353 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006354
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306356#ifdef FEATURE_WLAN_TDLS
6357 mutex_unlock(&pHddCtx->tdls_lock);
6358#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306359
6360 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 if( VOS_STATUS_SUCCESS != status )
6362 goto err_free_netdev;
6363
6364 status = hdd_register_interface( pAdapter, rtnl_held );
6365 if( VOS_STATUS_SUCCESS != status )
6366 {
6367 hdd_deinit_adapter(pHddCtx, pAdapter);
6368 goto err_free_netdev;
6369 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306370
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306371 // Workqueue which gets scheduled in IPv4 notification callback.
6372 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6373
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306374#ifdef WLAN_NS_OFFLOAD
6375 // Workqueue which gets scheduled in IPv6 notification callback.
6376 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 //Stop the Interface TX queue.
6379 netif_tx_disable(pAdapter->dev);
6380 //netif_tx_disable(pWlanDev);
6381 netif_carrier_off(pAdapter->dev);
6382
6383 break;
6384 }
6385
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 case WLAN_HDD_SOFTAP:
6388 {
6389 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6390 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306391 {
6392 hddLog(VOS_TRACE_LEVEL_FATAL,
6393 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006396
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6398 NL80211_IFTYPE_AP:
6399 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 pAdapter->device_mode = session_type;
6401
6402 status = hdd_init_ap_mode(pAdapter);
6403 if( VOS_STATUS_SUCCESS != status )
6404 goto err_free_netdev;
6405
6406 status = hdd_register_hostapd( pAdapter, rtnl_held );
6407 if( VOS_STATUS_SUCCESS != status )
6408 {
6409 hdd_deinit_adapter(pHddCtx, pAdapter);
6410 goto err_free_netdev;
6411 }
6412
6413 netif_tx_disable(pAdapter->dev);
6414 netif_carrier_off(pAdapter->dev);
6415
6416 hdd_set_conparam( 1 );
6417 break;
6418 }
6419 case WLAN_HDD_MONITOR:
6420 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6422 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306423 {
6424 hddLog(VOS_TRACE_LEVEL_FATAL,
6425 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306427 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006428
6429 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6430 pAdapter->device_mode = session_type;
6431 status = hdd_register_interface( pAdapter, rtnl_held );
6432#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6433 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6434#else
6435 pAdapter->dev->open = hdd_mon_open;
6436 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6437#endif
6438 hdd_init_tx_rx( pAdapter );
6439 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6440 //Set adapter to be used for data tx. It will use either GO or softap.
6441 pAdapter->sessionCtx.monitor.pAdapterForTx =
6442 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6444 {
6445 pAdapter->sessionCtx.monitor.pAdapterForTx =
6446 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6447 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 /* This workqueue will be used to transmit management packet over
6449 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006450 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6451 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6452 return NULL;
6453 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006454
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6456 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 }
6458 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 case WLAN_HDD_FTM:
6460 {
6461 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6462
6463 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306464 {
6465 hddLog(VOS_TRACE_LEVEL_FATAL,
6466 FL("failed to allocate adapter for session %d"), session_type);
6467 return NULL;
6468 }
6469
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6471 * message while loading driver in FTM mode. */
6472 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6473 pAdapter->device_mode = session_type;
6474 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306475
6476 hdd_init_tx_rx( pAdapter );
6477
6478 //Stop the Interface TX queue.
6479 netif_tx_disable(pAdapter->dev);
6480 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 }
6482 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 default:
6484 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306485 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6486 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 VOS_ASSERT(0);
6488 return NULL;
6489 }
6490 }
6491
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 if( VOS_STATUS_SUCCESS == status )
6493 {
6494 //Add it to the hdd's session list.
6495 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6496 if( NULL == pHddAdapterNode )
6497 {
6498 status = VOS_STATUS_E_NOMEM;
6499 }
6500 else
6501 {
6502 pHddAdapterNode->pAdapter = pAdapter;
6503 status = hdd_add_adapter_back ( pHddCtx,
6504 pHddAdapterNode );
6505 }
6506 }
6507
6508 if( VOS_STATUS_SUCCESS != status )
6509 {
6510 if( NULL != pAdapter )
6511 {
6512 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6513 pAdapter = NULL;
6514 }
6515 if( NULL != pHddAdapterNode )
6516 {
6517 vos_mem_free( pHddAdapterNode );
6518 }
6519
6520 goto resume_bmps;
6521 }
6522
6523 if(VOS_STATUS_SUCCESS == status)
6524 {
6525 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6526
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006527 //Initialize the WoWL service
6528 if(!hdd_init_wowl(pAdapter))
6529 {
6530 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6531 goto err_free_netdev;
6532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 return pAdapter;
6535
6536err_free_netdev:
6537 free_netdev(pAdapter->dev);
6538 wlan_hdd_release_intf_addr( pHddCtx,
6539 pAdapter->macAddressCurrent.bytes );
6540
6541resume_bmps:
6542 //If bmps disabled enable it
6543 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6544 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306545 if (pHddCtx->hdd_wlan_suspended)
6546 {
6547 hdd_set_pwrparams(pHddCtx);
6548 }
6549 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 }
6551 return NULL;
6552}
6553
6554VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6555 tANI_U8 rtnl_held )
6556{
6557 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6558 VOS_STATUS status;
6559
6560 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6561 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306562 {
6563 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6564 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006567
6568 while ( pCurrent->pAdapter != pAdapter )
6569 {
6570 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6571 if( VOS_STATUS_SUCCESS != status )
6572 break;
6573
6574 pCurrent = pNext;
6575 }
6576 pAdapterNode = pCurrent;
6577 if( VOS_STATUS_SUCCESS == status )
6578 {
6579 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6580 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306581
6582#ifdef FEATURE_WLAN_TDLS
6583
6584 /* A Mutex Lock is introduced while changing/initializing the mode to
6585 * protect the concurrent access for the Adapters by TDLS module.
6586 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306587 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306588#endif
6589
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 hdd_remove_adapter( pHddCtx, pAdapterNode );
6591 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006592 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006593
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306594#ifdef FEATURE_WLAN_TDLS
6595 mutex_unlock(&pHddCtx->tdls_lock);
6596#endif
6597
Jeff Johnson295189b2012-06-20 16:38:30 -07006598
6599 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306600 if ((!vos_concurrent_open_sessions_running()) &&
6601 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6602 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306604 if (pHddCtx->hdd_wlan_suspended)
6605 {
6606 hdd_set_pwrparams(pHddCtx);
6607 }
6608 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 }
6610
6611 return VOS_STATUS_SUCCESS;
6612 }
6613
6614 return VOS_STATUS_E_FAILURE;
6615}
6616
6617VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6618{
6619 hdd_adapter_list_node_t *pHddAdapterNode;
6620 VOS_STATUS status;
6621
6622 ENTER();
6623
6624 do
6625 {
6626 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6627 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6628 {
6629 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6630 vos_mem_free( pHddAdapterNode );
6631 }
6632 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6633
6634 EXIT();
6635
6636 return VOS_STATUS_SUCCESS;
6637}
6638
6639void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6640{
6641 v_U8_t addIE[1] = {0};
6642
6643 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6644 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6645 eANI_BOOLEAN_FALSE) )
6646 {
6647 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006648 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006649 }
6650
6651 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6652 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6653 eANI_BOOLEAN_FALSE) )
6654 {
6655 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006656 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 }
6658
6659 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6660 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6661 eANI_BOOLEAN_FALSE) )
6662 {
6663 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006664 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 }
6666}
6667
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306668VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6669 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006670{
6671 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6672 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6673 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306674 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306675 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006676
6677 ENTER();
6678
6679 switch(pAdapter->device_mode)
6680 {
6681 case WLAN_HDD_INFRA_STATION:
6682 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006683 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306684 {
6685 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6686 if( hdd_connIsConnected(pstation) ||
6687 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 {
6689 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6690 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6691 pAdapter->sessionId,
6692 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6693 else
6694 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6695 pAdapter->sessionId,
6696 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6697 //success implies disconnect command got queued up successfully
6698 if(halStatus == eHAL_STATUS_SUCCESS)
6699 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306700 ret = wait_for_completion_interruptible_timeout(
6701 &pAdapter->disconnect_comp_var,
6702 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6703 if (ret <= 0)
6704 {
6705 hddLog(VOS_TRACE_LEVEL_ERROR,
6706 "%s: wait on disconnect_comp_var failed %ld",
6707 __func__, ret);
6708 }
6709 }
6710 else
6711 {
6712 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6713 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006714 }
6715 memset(&wrqu, '\0', sizeof(wrqu));
6716 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6717 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6718 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6719 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306720 else if(pstation->conn_info.connState ==
6721 eConnectionState_Disconnecting)
6722 {
6723 ret = wait_for_completion_interruptible_timeout(
6724 &pAdapter->disconnect_comp_var,
6725 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6726 if (ret <= 0)
6727 {
6728 hddLog(VOS_TRACE_LEVEL_ERROR,
6729 FL("wait on disconnect_comp_var failed %ld"), ret);
6730 }
6731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 else
6733 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306734 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6735 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306737 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6738 {
6739 while (pAdapter->is_roc_inprogress)
6740 {
6741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6742 "%s: ROC in progress for session %d!!!",
6743 __func__, pAdapter->sessionId);
6744 // waiting for ROC to expire
6745 msleep(500);
6746 /* In GO present case , if retry exceeds 3,
6747 it means something went wrong. */
6748 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6749 {
6750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6751 "%s: ROC completion is not received.!!!", __func__);
6752 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6753 pAdapter->sessionId);
6754 wait_for_completion_interruptible_timeout(
6755 &pAdapter->cancel_rem_on_chan_var,
6756 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6757 break;
6758 }
6759 }
6760 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306761#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306762#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306763 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6764#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306765 if (pAdapter->ipv6_notifier_registered)
6766 {
6767 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6768 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6769 pAdapter->ipv6_notifier_registered = false;
6770 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306771#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306772 if (pAdapter->ipv4_notifier_registered)
6773 {
6774 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6775 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6776 pAdapter->ipv4_notifier_registered = false;
6777 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306778#ifdef WLAN_OPEN_SOURCE
6779 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6780#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306781 /* It is possible that the caller of this function does not
6782 * wish to close the session
6783 */
6784 if (VOS_TRUE == bCloseSession &&
6785 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 {
6787 INIT_COMPLETION(pAdapter->session_close_comp_var);
6788 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306789 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6790 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306792 unsigned long ret;
6793
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306795 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306796 &pAdapter->session_close_comp_var,
6797 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306798 if ( 0 >= ret)
6799 {
6800 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306801 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 }
6804 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 break;
6807
6808 case WLAN_HDD_SOFTAP:
6809 case WLAN_HDD_P2P_GO:
6810 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306811 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6812 while (pAdapter->is_roc_inprogress) {
6813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6814 "%s: ROC in progress for session %d!!!",
6815 __func__, pAdapter->sessionId);
6816 msleep(500);
6817 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6819 "%s: ROC completion is not received.!!!", __func__);
6820 WLANSAP_CancelRemainOnChannel(
6821 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6822 wait_for_completion_interruptible_timeout(
6823 &pAdapter->cancel_rem_on_chan_var,
6824 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6825 break;
6826 }
6827 }
6828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 mutex_lock(&pHddCtx->sap_lock);
6830 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6831 {
6832 VOS_STATUS status;
6833 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6834
6835 //Stop Bss.
6836 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6837 if (VOS_IS_STATUS_SUCCESS(status))
6838 {
6839 hdd_hostapd_state_t *pHostapdState =
6840 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6841
6842 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6843
6844 if (!VOS_IS_STATUS_SUCCESS(status))
6845 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306846 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6847 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 }
6849 }
6850 else
6851 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006852 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 }
6854 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306855 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006856
6857 if (eHAL_STATUS_FAILURE ==
6858 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6859 0, NULL, eANI_BOOLEAN_FALSE))
6860 {
6861 hddLog(LOGE,
6862 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006863 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 }
6865
6866 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6867 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6868 eANI_BOOLEAN_FALSE) )
6869 {
6870 hddLog(LOGE,
6871 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6872 }
6873
6874 // Reset WNI_CFG_PROBE_RSP Flags
6875 wlan_hdd_reset_prob_rspies(pAdapter);
6876 kfree(pAdapter->sessionCtx.ap.beacon);
6877 pAdapter->sessionCtx.ap.beacon = NULL;
6878 }
6879 mutex_unlock(&pHddCtx->sap_lock);
6880 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006881
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006883#ifdef WLAN_OPEN_SOURCE
6884 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6885#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006887
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 default:
6889 break;
6890 }
6891
6892 EXIT();
6893 return VOS_STATUS_SUCCESS;
6894}
6895
6896VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6897{
6898 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6899 VOS_STATUS status;
6900 hdd_adapter_t *pAdapter;
6901
6902 ENTER();
6903
6904 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6905
6906 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6907 {
6908 pAdapter = pAdapterNode->pAdapter;
6909 netif_tx_disable(pAdapter->dev);
6910 netif_carrier_off(pAdapter->dev);
6911
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306912 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006913
6914 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6915 pAdapterNode = pNext;
6916 }
6917
6918 EXIT();
6919
6920 return VOS_STATUS_SUCCESS;
6921}
6922
Rajeev Kumarf999e582014-01-09 17:33:29 -08006923
6924#ifdef FEATURE_WLAN_BATCH_SCAN
6925/**---------------------------------------------------------------------------
6926
6927 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6928 structures
6929
6930 \param - pAdapter Pointer to HDD adapter
6931
6932 \return - None
6933
6934 --------------------------------------------------------------------------*/
6935void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6936{
6937 tHddBatchScanRsp *pNode;
6938 tHddBatchScanRsp *pPrev;
6939
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306940 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006941 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306942 hddLog(VOS_TRACE_LEVEL_ERROR,
6943 "%s: Adapter context is Null", __func__);
6944 return;
6945 }
6946
6947 pNode = pAdapter->pBatchScanRsp;
6948 while (pNode)
6949 {
6950 pPrev = pNode;
6951 pNode = pNode->pNext;
6952 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006953 }
6954
6955 pAdapter->pBatchScanRsp = NULL;
6956 pAdapter->numScanList = 0;
6957 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6958 pAdapter->prev_batch_id = 0;
6959
6960 return;
6961}
6962#endif
6963
6964
Jeff Johnson295189b2012-06-20 16:38:30 -07006965VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6966{
6967 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6968 VOS_STATUS status;
6969 hdd_adapter_t *pAdapter;
6970
6971 ENTER();
6972
6973 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6974
6975 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6976 {
6977 pAdapter = pAdapterNode->pAdapter;
6978 netif_tx_disable(pAdapter->dev);
6979 netif_carrier_off(pAdapter->dev);
6980
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006981 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6982
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05306984
6985 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
6986
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306987 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6988 {
6989 hdd_wmm_adapter_close( pAdapter );
6990 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6991 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006992
Rajeev Kumarf999e582014-01-09 17:33:29 -08006993#ifdef FEATURE_WLAN_BATCH_SCAN
6994 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6995 {
6996 hdd_deinit_batch_scan(pAdapter);
6997 }
6998#endif
6999
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7001 pAdapterNode = pNext;
7002 }
7003
7004 EXIT();
7005
7006 return VOS_STATUS_SUCCESS;
7007}
7008
7009VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7010{
7011 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7012 VOS_STATUS status;
7013 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307014 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007015
7016 ENTER();
7017
7018 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7019
7020 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7021 {
7022 pAdapter = pAdapterNode->pAdapter;
7023
Kumar Anand82c009f2014-05-29 00:29:42 -07007024 hdd_wmm_init( pAdapter );
7025
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 switch(pAdapter->device_mode)
7027 {
7028 case WLAN_HDD_INFRA_STATION:
7029 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007030 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307031
7032 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7033
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 hdd_init_station_mode(pAdapter);
7035 /* Open the gates for HDD to receive Wext commands */
7036 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007037 pHddCtx->scan_info.mScanPending = FALSE;
7038 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007039
7040 //Trigger the initial scan
7041 hdd_wlan_initial_scan(pAdapter);
7042
7043 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307044 if (eConnectionState_Associated == connState ||
7045 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 {
7047 union iwreq_data wrqu;
7048 memset(&wrqu, '\0', sizeof(wrqu));
7049 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7050 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7051 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007052 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007053
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 /* indicate disconnected event to nl80211 */
7055 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7056 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307058 else if (eConnectionState_Connecting == connState)
7059 {
7060 /*
7061 * Indicate connect failure to supplicant if we were in the
7062 * process of connecting
7063 */
7064 cfg80211_connect_result(pAdapter->dev, NULL,
7065 NULL, 0, NULL, 0,
7066 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7067 GFP_KERNEL);
7068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 break;
7070
7071 case WLAN_HDD_SOFTAP:
7072 /* softAP can handle SSR */
7073 break;
7074
7075 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007078 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 break;
7080
7081 case WLAN_HDD_MONITOR:
7082 /* monitor interface start */
7083 break;
7084 default:
7085 break;
7086 }
7087
7088 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7089 pAdapterNode = pNext;
7090 }
7091
7092 EXIT();
7093
7094 return VOS_STATUS_SUCCESS;
7095}
7096
7097VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7098{
7099 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7100 hdd_adapter_t *pAdapter;
7101 VOS_STATUS status;
7102 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307103 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007104
7105 ENTER();
7106
7107 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7108
7109 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7110 {
7111 pAdapter = pAdapterNode->pAdapter;
7112
7113 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7114 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7115 {
7116 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7117 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7118
Abhishek Singhf4669da2014-05-26 15:07:49 +05307119 hddLog(VOS_TRACE_LEVEL_INFO,
7120 "%s: Set HDD connState to eConnectionState_NotConnected",
7121 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7123 init_completion(&pAdapter->disconnect_comp_var);
7124 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7125 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7126
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307127 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 &pAdapter->disconnect_comp_var,
7129 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307130 if (0 >= ret)
7131 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7132 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007133
7134 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7135 pHddCtx->isAmpAllowed = VOS_FALSE;
7136 sme_RoamConnect(pHddCtx->hHal,
7137 pAdapter->sessionId, &(pWextState->roamProfile),
7138 &roamId);
7139 }
7140
7141 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7142 pAdapterNode = pNext;
7143 }
7144
7145 EXIT();
7146
7147 return VOS_STATUS_SUCCESS;
7148}
7149
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007150void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7151{
7152 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7153 VOS_STATUS status;
7154 hdd_adapter_t *pAdapter;
7155 hdd_station_ctx_t *pHddStaCtx;
7156 hdd_ap_ctx_t *pHddApCtx;
7157 hdd_hostapd_state_t * pHostapdState;
7158 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7159 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7160 const char *p2pMode = "DEV";
7161 const char *ccMode = "Standalone";
7162 int n;
7163
7164 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7165 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7166 {
7167 pAdapter = pAdapterNode->pAdapter;
7168 switch (pAdapter->device_mode) {
7169 case WLAN_HDD_INFRA_STATION:
7170 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7171 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7172 staChannel = pHddStaCtx->conn_info.operationChannel;
7173 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7174 }
7175 break;
7176 case WLAN_HDD_P2P_CLIENT:
7177 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7178 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7179 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7180 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7181 p2pMode = "CLI";
7182 }
7183 break;
7184 case WLAN_HDD_P2P_GO:
7185 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7186 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7187 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7188 p2pChannel = pHddApCtx->operatingChannel;
7189 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7190 }
7191 p2pMode = "GO";
7192 break;
7193 case WLAN_HDD_SOFTAP:
7194 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7195 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7196 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7197 apChannel = pHddApCtx->operatingChannel;
7198 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7199 }
7200 break;
7201 default:
7202 break;
7203 }
7204 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7205 pAdapterNode = pNext;
7206 }
7207 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7208 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7209 }
7210 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7211 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7212 if (p2pChannel > 0) {
7213 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7214 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7215 }
7216 if (apChannel > 0) {
7217 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7218 apChannel, MAC_ADDR_ARRAY(apBssid));
7219 }
7220
7221 if (p2pChannel > 0 && apChannel > 0) {
7222 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7223 }
7224}
7225
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007226bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007227{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007228 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007229}
7230
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007231/* Once SSR is disabled then it cannot be set. */
7232void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007233{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007234 if (HDD_SSR_DISABLED == isSsrRequired)
7235 return;
7236
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 isSsrRequired = value;
7238}
7239
7240VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7241 hdd_adapter_list_node_t** ppAdapterNode)
7242{
7243 VOS_STATUS status;
7244 spin_lock(&pHddCtx->hddAdapters.lock);
7245 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7246 (hdd_list_node_t**) ppAdapterNode );
7247 spin_unlock(&pHddCtx->hddAdapters.lock);
7248 return status;
7249}
7250
7251VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7252 hdd_adapter_list_node_t* pAdapterNode,
7253 hdd_adapter_list_node_t** pNextAdapterNode)
7254{
7255 VOS_STATUS status;
7256 spin_lock(&pHddCtx->hddAdapters.lock);
7257 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7258 (hdd_list_node_t*) pAdapterNode,
7259 (hdd_list_node_t**)pNextAdapterNode );
7260
7261 spin_unlock(&pHddCtx->hddAdapters.lock);
7262 return status;
7263}
7264
7265VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7266 hdd_adapter_list_node_t* pAdapterNode)
7267{
7268 VOS_STATUS status;
7269 spin_lock(&pHddCtx->hddAdapters.lock);
7270 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7271 &pAdapterNode->node );
7272 spin_unlock(&pHddCtx->hddAdapters.lock);
7273 return status;
7274}
7275
7276VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7277 hdd_adapter_list_node_t** ppAdapterNode)
7278{
7279 VOS_STATUS status;
7280 spin_lock(&pHddCtx->hddAdapters.lock);
7281 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7282 (hdd_list_node_t**) ppAdapterNode );
7283 spin_unlock(&pHddCtx->hddAdapters.lock);
7284 return status;
7285}
7286
7287VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7288 hdd_adapter_list_node_t* pAdapterNode)
7289{
7290 VOS_STATUS status;
7291 spin_lock(&pHddCtx->hddAdapters.lock);
7292 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7293 (hdd_list_node_t*) pAdapterNode );
7294 spin_unlock(&pHddCtx->hddAdapters.lock);
7295 return status;
7296}
7297
7298VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7299 hdd_adapter_list_node_t* pAdapterNode)
7300{
7301 VOS_STATUS status;
7302 spin_lock(&pHddCtx->hddAdapters.lock);
7303 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7304 (hdd_list_node_t*) pAdapterNode );
7305 spin_unlock(&pHddCtx->hddAdapters.lock);
7306 return status;
7307}
7308
7309hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7310 tSirMacAddr macAddr )
7311{
7312 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7313 hdd_adapter_t *pAdapter;
7314 VOS_STATUS status;
7315
7316 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7317
7318 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7319 {
7320 pAdapter = pAdapterNode->pAdapter;
7321
7322 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7323 macAddr, sizeof(tSirMacAddr) ) )
7324 {
7325 return pAdapter;
7326 }
7327 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7328 pAdapterNode = pNext;
7329 }
7330
7331 return NULL;
7332
7333}
7334
7335hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7336{
7337 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7338 hdd_adapter_t *pAdapter;
7339 VOS_STATUS status;
7340
7341 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7342
7343 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7344 {
7345 pAdapter = pAdapterNode->pAdapter;
7346
7347 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7348 IFNAMSIZ ) )
7349 {
7350 return pAdapter;
7351 }
7352 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7353 pAdapterNode = pNext;
7354 }
7355
7356 return NULL;
7357
7358}
7359
7360hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7361{
7362 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7363 hdd_adapter_t *pAdapter;
7364 VOS_STATUS status;
7365
7366 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7367
7368 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7369 {
7370 pAdapter = pAdapterNode->pAdapter;
7371
7372 if( pAdapter && (mode == pAdapter->device_mode) )
7373 {
7374 return pAdapter;
7375 }
7376 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7377 pAdapterNode = pNext;
7378 }
7379
7380 return NULL;
7381
7382}
7383
7384//Remove this function later
7385hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7386{
7387 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7388 hdd_adapter_t *pAdapter;
7389 VOS_STATUS status;
7390
7391 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7392
7393 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7394 {
7395 pAdapter = pAdapterNode->pAdapter;
7396
7397 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7398 {
7399 return pAdapter;
7400 }
7401
7402 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7403 pAdapterNode = pNext;
7404 }
7405
7406 return NULL;
7407
7408}
7409
Jeff Johnson295189b2012-06-20 16:38:30 -07007410/**---------------------------------------------------------------------------
7411
7412 \brief hdd_set_monitor_tx_adapter() -
7413
7414 This API initializes the adapter to be used while transmitting on monitor
7415 adapter.
7416
7417 \param - pHddCtx - Pointer to the HDD context.
7418 pAdapter - Adapter that will used for TX. This can be NULL.
7419 \return - None.
7420 --------------------------------------------------------------------------*/
7421void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7422{
7423 hdd_adapter_t *pMonAdapter;
7424
7425 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7426
7427 if( NULL != pMonAdapter )
7428 {
7429 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7430 }
7431}
Jeff Johnson295189b2012-06-20 16:38:30 -07007432/**---------------------------------------------------------------------------
7433
7434 \brief hdd_select_queue() -
7435
7436 This API returns the operating channel of the requested device mode
7437
7438 \param - pHddCtx - Pointer to the HDD context.
7439 - mode - Device mode for which operating channel is required
7440 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7441 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7442 \return - channel number. "0" id the requested device is not found OR it is not connected.
7443 --------------------------------------------------------------------------*/
7444v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7445{
7446 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7447 VOS_STATUS status;
7448 hdd_adapter_t *pAdapter;
7449 v_U8_t operatingChannel = 0;
7450
7451 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7452
7453 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7454 {
7455 pAdapter = pAdapterNode->pAdapter;
7456
7457 if( mode == pAdapter->device_mode )
7458 {
7459 switch(pAdapter->device_mode)
7460 {
7461 case WLAN_HDD_INFRA_STATION:
7462 case WLAN_HDD_P2P_CLIENT:
7463 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7464 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7465 break;
7466 case WLAN_HDD_SOFTAP:
7467 case WLAN_HDD_P2P_GO:
7468 /*softap connection info */
7469 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7470 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7471 break;
7472 default:
7473 break;
7474 }
7475
7476 break; //Found the device of interest. break the loop
7477 }
7478
7479 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7480 pAdapterNode = pNext;
7481 }
7482 return operatingChannel;
7483}
7484
7485#ifdef WLAN_FEATURE_PACKET_FILTERING
7486/**---------------------------------------------------------------------------
7487
7488 \brief hdd_set_multicast_list() -
7489
7490 This used to set the multicast address list.
7491
7492 \param - dev - Pointer to the WLAN device.
7493 - skb - Pointer to OS packet (sk_buff).
7494 \return - success/fail
7495
7496 --------------------------------------------------------------------------*/
7497static void hdd_set_multicast_list(struct net_device *dev)
7498{
7499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 int mc_count;
7501 int i = 0;
7502 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307503
7504 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 {
7506 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307507 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 return;
7509 }
7510
7511 if (dev->flags & IFF_ALLMULTI)
7512 {
7513 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007514 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307515 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 }
7517 else
7518 {
7519 mc_count = netdev_mc_count(dev);
7520 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007521 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7523 {
7524 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007525 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307526 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007527 return;
7528 }
7529
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307530 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007531
7532 netdev_for_each_mc_addr(ha, dev) {
7533 if (i == mc_count)
7534 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307535 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7536 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007537 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007538 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307539 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 i++;
7541 }
7542 }
7543 return;
7544}
7545#endif
7546
7547/**---------------------------------------------------------------------------
7548
7549 \brief hdd_select_queue() -
7550
7551 This function is registered with the Linux OS for network
7552 core to decide which queue to use first.
7553
7554 \param - dev - Pointer to the WLAN device.
7555 - skb - Pointer to OS packet (sk_buff).
7556 \return - ac, Queue Index/access category corresponding to UP in IP header
7557
7558 --------------------------------------------------------------------------*/
7559v_U16_t hdd_select_queue(struct net_device *dev,
7560 struct sk_buff *skb)
7561{
7562 return hdd_wmm_select_queue(dev, skb);
7563}
7564
7565
7566/**---------------------------------------------------------------------------
7567
7568 \brief hdd_wlan_initial_scan() -
7569
7570 This function triggers the initial scan
7571
7572 \param - pAdapter - Pointer to the HDD adapter.
7573
7574 --------------------------------------------------------------------------*/
7575void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7576{
7577 tCsrScanRequest scanReq;
7578 tCsrChannelInfo channelInfo;
7579 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007580 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7582
7583 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7584 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7585 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7586
7587 if(sme_Is11dSupported(pHddCtx->hHal))
7588 {
7589 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7590 if ( HAL_STATUS_SUCCESS( halStatus ) )
7591 {
7592 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7593 if( !scanReq.ChannelInfo.ChannelList )
7594 {
7595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7596 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007597 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007598 return;
7599 }
7600 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7601 channelInfo.numOfChannels);
7602 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7603 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007604 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 }
7606
7607 scanReq.scanType = eSIR_PASSIVE_SCAN;
7608 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7609 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7610 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7611 }
7612 else
7613 {
7614 scanReq.scanType = eSIR_ACTIVE_SCAN;
7615 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7616 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7617 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7618 }
7619
7620 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7621 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7622 {
7623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7624 __func__, halStatus );
7625 }
7626
7627 if(sme_Is11dSupported(pHddCtx->hHal))
7628 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7629}
7630
Jeff Johnson295189b2012-06-20 16:38:30 -07007631/**---------------------------------------------------------------------------
7632
7633 \brief hdd_full_power_callback() - HDD full power callback function
7634
7635 This is the function invoked by SME to inform the result of a full power
7636 request issued by HDD
7637
7638 \param - callbackcontext - Pointer to cookie
7639 \param - status - result of request
7640
7641 \return - None
7642
7643 --------------------------------------------------------------------------*/
7644static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7645{
Jeff Johnson72a40512013-12-19 10:14:15 -08007646 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007647
7648 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307649 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007650
7651 if (NULL == callbackContext)
7652 {
7653 hddLog(VOS_TRACE_LEVEL_ERROR,
7654 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007655 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 return;
7657 }
7658
Jeff Johnson72a40512013-12-19 10:14:15 -08007659 /* there is a race condition that exists between this callback
7660 function and the caller since the caller could time out either
7661 before or while this code is executing. we use a spinlock to
7662 serialize these actions */
7663 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007664
7665 if (POWER_CONTEXT_MAGIC != pContext->magic)
7666 {
7667 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007668 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 hddLog(VOS_TRACE_LEVEL_WARN,
7670 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007671 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 return;
7673 }
7674
Jeff Johnson72a40512013-12-19 10:14:15 -08007675 /* context is valid so caller is still waiting */
7676
7677 /* paranoia: invalidate the magic */
7678 pContext->magic = 0;
7679
7680 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007682
7683 /* serialization is complete */
7684 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007685}
7686
7687/**---------------------------------------------------------------------------
7688
7689 \brief hdd_wlan_exit() - HDD WLAN exit function
7690
7691 This is the driver exit point (invoked during rmmod)
7692
7693 \param - pHddCtx - Pointer to the HDD Context
7694
7695 \return - None
7696
7697 --------------------------------------------------------------------------*/
7698void hdd_wlan_exit(hdd_context_t *pHddCtx)
7699{
7700 eHalStatus halStatus;
7701 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7702 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307703 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007704 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007705 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307707 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007708
7709 ENTER();
7710
Jeff Johnson88ba7742013-02-27 14:36:02 -08007711 if (VOS_FTM_MODE != hdd_get_conparam())
7712 {
7713 // Unloading, restart logic is no more required.
7714 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007715
c_hpothu5ab05e92014-06-13 17:34:05 +05307716 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7717 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307719 pAdapter = pAdapterNode->pAdapter;
7720 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307722 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7723 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7724 {
7725 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7726 hdd_UnregisterWext(pAdapter->dev);
7727 }
7728 // Cancel any outstanding scan requests. We are about to close all
7729 // of our adapters, but an adapter structure is what SME passes back
7730 // to our callback function. Hence if there are any outstanding scan
7731 // requests then there is a race condition between when the adapter
7732 // is closed and when the callback is invoked.We try to resolve that
7733 // race condition here by canceling any outstanding scans before we
7734 // close the adapters.
7735 // Note that the scans may be cancelled in an asynchronous manner,
7736 // so ideally there needs to be some kind of synchronization. Rather
7737 // than introduce a new synchronization here, we will utilize the
7738 // fact that we are about to Request Full Power, and since that is
7739 // synchronized, the expectation is that by the time Request Full
7740 // Power has completed all scans will be cancelled.
7741 if (pHddCtx->scan_info.mScanPending)
7742 {
7743 hddLog(VOS_TRACE_LEVEL_INFO,
7744 FL("abort scan mode: %d sessionId: %d"),
7745 pAdapter->device_mode,
7746 pAdapter->sessionId);
7747 hdd_abort_mac_scan(pHddCtx,
7748 pAdapter->sessionId,
7749 eCSR_SCAN_ABORT_DEFAULT);
7750 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007751 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307752 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7753 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 }
7755 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307756 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007757 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307758 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007759 wlan_hdd_ftm_close(pHddCtx);
7760 goto free_hdd_ctx;
7761 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307762
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 /* DeRegister with platform driver as client for Suspend/Resume */
7764 vosStatus = hddDeregisterPmOps(pHddCtx);
7765 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7766 {
7767 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7768 VOS_ASSERT(0);
7769 }
7770
7771 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7772 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7773 {
7774 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7775 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007776
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007777 //Stop the traffic monitor timer
7778 if ( VOS_TIMER_STATE_RUNNING ==
7779 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7780 {
7781 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7782 }
7783
7784 // Destroy the traffic monitor timer
7785 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7786 &pHddCtx->tx_rx_trafficTmr)))
7787 {
7788 hddLog(VOS_TRACE_LEVEL_ERROR,
7789 "%s: Cannot deallocate Traffic monitor timer", __func__);
7790 }
7791
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 //Disable IMPS/BMPS as we do not want the device to enter any power
7793 //save mode during shutdown
7794 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7795 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7796 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7797
7798 //Ensure that device is in full power as we will touch H/W during vos_Stop
7799 init_completion(&powerContext.completion);
7800 powerContext.magic = POWER_CONTEXT_MAGIC;
7801
7802 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7803 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7804
7805 if (eHAL_STATUS_SUCCESS != halStatus)
7806 {
7807 if (eHAL_STATUS_PMC_PENDING == halStatus)
7808 {
7809 /* request was sent -- wait for the response */
7810 lrc = wait_for_completion_interruptible_timeout(
7811 &powerContext.completion,
7812 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 if (lrc <= 0)
7814 {
7815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007816 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 }
7818 }
7819 else
7820 {
7821 hddLog(VOS_TRACE_LEVEL_ERROR,
7822 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007823 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 /* continue -- need to clean up as much as possible */
7825 }
7826 }
7827
Jeff Johnson72a40512013-12-19 10:14:15 -08007828 /* either we never sent a request, we sent a request and received a
7829 response or we sent a request and timed out. if we never sent a
7830 request or if we sent a request and got a response, we want to
7831 clear the magic out of paranoia. if we timed out there is a
7832 race condition such that the callback function could be
7833 executing at the same time we are. of primary concern is if the
7834 callback function had already verified the "magic" but had not
7835 yet set the completion variable when a timeout occurred. we
7836 serialize these activities by invalidating the magic while
7837 holding a shared spinlock which will cause us to block if the
7838 callback is currently executing */
7839 spin_lock(&hdd_context_lock);
7840 powerContext.magic = 0;
7841 spin_unlock(&hdd_context_lock);
7842
Yue Ma0d4891e2013-08-06 17:01:45 -07007843 hdd_debugfs_exit(pHddCtx);
7844
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 // Unregister the Net Device Notifier
7846 unregister_netdevice_notifier(&hdd_netdev_notifier);
7847
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 hdd_stop_all_adapters( pHddCtx );
7849
Jeff Johnson295189b2012-06-20 16:38:30 -07007850#ifdef WLAN_BTAMP_FEATURE
7851 vosStatus = WLANBAP_Stop(pVosContext);
7852 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7853 {
7854 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7855 "%s: Failed to stop BAP",__func__);
7856 }
7857#endif //WLAN_BTAMP_FEATURE
7858
7859 //Stop all the modules
7860 vosStatus = vos_stop( pVosContext );
7861 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7862 {
7863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7864 "%s: Failed to stop VOSS",__func__);
7865 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7866 }
7867
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 //Assert Deep sleep signal now to put Libra HW in lowest power state
7869 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7870 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7871
7872 //Vote off any PMIC voltage supplies
7873 vos_chipPowerDown(NULL, NULL, NULL);
7874
7875 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7876
Leo Chang59cdc7e2013-07-10 10:08:21 -07007877
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880
7881 //Close the scheduler before calling vos_close to make sure no thread is
7882 // scheduled after the each module close is called i.e after all the data
7883 // structures are freed.
7884 vosStatus = vos_sched_close( pVosContext );
7885 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7886 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7887 "%s: Failed to close VOSS Scheduler",__func__);
7888 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7889 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007890#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007891#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7892 /* Destroy the wake lock */
7893 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7894#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007895 /* Destroy the wake lock */
7896 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007897#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007898
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307899#ifdef CONFIG_ENABLE_LINUX_REG
7900 vosStatus = vos_nv_close();
7901 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7902 {
7903 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7904 "%s: Failed to close NV", __func__);
7905 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7906 }
7907#endif
7908
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 //Close VOSS
7910 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7911 vos_close(pVosContext);
7912
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 //Close Watchdog
7914 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7915 vos_watchdog_close(pVosContext);
7916
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307917 //Clean up HDD Nlink Service
7918 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307919
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307920#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307921 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307922 {
7923 wlan_logging_sock_deactivate_svc();
7924 }
7925#endif
7926
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05307927#ifdef WLAN_KD_READY_NOTIFIER
7928 nl_srv_exit(pHddCtx->ptt_pid);
7929#else
7930 nl_srv_exit();
7931#endif /* WLAN_KD_READY_NOTIFIER */
7932
7933
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 /* Cancel the vote for XO Core ON.
7935 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7936 * exited at this point
7937 */
7938 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007939 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007940 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7941 {
7942 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7943 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007944 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 }
7946
7947 hdd_close_all_adapters( pHddCtx );
7948
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 /* free the power on lock from platform driver */
7950 if (free_riva_power_on_lock("wlan"))
7951 {
7952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7953 __func__);
7954 }
7955
Jeff Johnson88ba7742013-02-27 14:36:02 -08007956free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307957
7958 //Free up dynamically allocated members inside HDD Adapter
7959 if (pHddCtx->cfg_ini)
7960 {
7961 kfree(pHddCtx->cfg_ini);
7962 pHddCtx->cfg_ini= NULL;
7963 }
7964
Leo Changf04ddad2013-09-18 13:46:38 -07007965 /* FTM mode, WIPHY did not registered
7966 If un-register here, system crash will happen */
7967 if (VOS_FTM_MODE != hdd_get_conparam())
7968 {
7969 wiphy_unregister(wiphy) ;
7970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 if (hdd_is_ssr_required())
7973 {
7974 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007975 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 msleep(5000);
7977 }
7978 hdd_set_ssr_required (VOS_FALSE);
7979}
7980
7981
7982/**---------------------------------------------------------------------------
7983
7984 \brief hdd_update_config_from_nv() - Function to update the contents of
7985 the running configuration with parameters taken from NV storage
7986
7987 \param - pHddCtx - Pointer to the HDD global context
7988
7989 \return - VOS_STATUS_SUCCESS if successful
7990
7991 --------------------------------------------------------------------------*/
7992static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7993{
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 v_BOOL_t itemIsValid = VOS_FALSE;
7995 VOS_STATUS status;
7996 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7997 v_U8_t macLoop;
7998
7999 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8000 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8001 if(status != VOS_STATUS_SUCCESS)
8002 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008003 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 return VOS_STATUS_E_FAILURE;
8005 }
8006
8007 if (itemIsValid == VOS_TRUE)
8008 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008009 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8011 VOS_MAX_CONCURRENCY_PERSONA);
8012 if(status != VOS_STATUS_SUCCESS)
8013 {
8014 /* Get MAC from NV fail, not update CFG info
8015 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008016 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 return VOS_STATUS_E_FAILURE;
8018 }
8019
8020 /* If first MAC is not valid, treat all others are not valid
8021 * Then all MACs will be got from ini file */
8022 if(vos_is_macaddr_zero(&macFromNV[0]))
8023 {
8024 /* MAC address in NV file is not configured yet */
8025 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8026 return VOS_STATUS_E_INVAL;
8027 }
8028
8029 /* Get MAC address from NV, update CFG info */
8030 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8031 {
8032 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8033 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308034 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 /* This MAC is not valid, skip it
8036 * This MAC will be got from ini file */
8037 }
8038 else
8039 {
8040 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8041 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8042 VOS_MAC_ADDR_SIZE);
8043 }
8044 }
8045 }
8046 else
8047 {
8048 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8049 return VOS_STATUS_E_FAILURE;
8050 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008051
Jeff Johnson295189b2012-06-20 16:38:30 -07008052
8053 return VOS_STATUS_SUCCESS;
8054}
8055
8056/**---------------------------------------------------------------------------
8057
8058 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8059
8060 \param - pAdapter - Pointer to the HDD
8061
8062 \return - None
8063
8064 --------------------------------------------------------------------------*/
8065VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8066{
8067 eHalStatus halStatus;
8068 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308069 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008070
Jeff Johnson295189b2012-06-20 16:38:30 -07008071
8072 // Send ready indication to the HDD. This will kick off the MAC
8073 // into a 'running' state and should kick off an initial scan.
8074 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8075 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8076 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308077 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 "code %08d [x%08x]",__func__, halStatus, halStatus );
8079 return VOS_STATUS_E_FAILURE;
8080 }
8081
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308082 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8084 // And RIVA will crash
8085 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8086 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308087 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8088 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8089
8090
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 return VOS_STATUS_SUCCESS;
8092}
8093
Jeff Johnson295189b2012-06-20 16:38:30 -07008094/* wake lock APIs for HDD */
8095void hdd_prevent_suspend(void)
8096{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008097#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008099#else
8100 wcnss_prevent_suspend();
8101#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008102}
8103
8104void hdd_allow_suspend(void)
8105{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008106#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008108#else
8109 wcnss_allow_suspend();
8110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008111}
8112
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308113void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008114{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008115#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008116 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008117#else
8118 /* Do nothing as there is no API in wcnss for timeout*/
8119#endif
8120}
8121
Jeff Johnson295189b2012-06-20 16:38:30 -07008122/**---------------------------------------------------------------------------
8123
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008124 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8125 information between Host and Riva
8126
8127 This function gets reported version of FW
8128 It also finds the version of Riva headers used to compile the host
8129 It compares the above two and prints a warning if they are different
8130 It gets the SW and HW version string
8131 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8132 indicating the features they support through a bitmap
8133
8134 \param - pHddCtx - Pointer to HDD context
8135
8136 \return - void
8137
8138 --------------------------------------------------------------------------*/
8139
8140void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8141{
8142
8143 tSirVersionType versionCompiled;
8144 tSirVersionType versionReported;
8145 tSirVersionString versionString;
8146 tANI_U8 fwFeatCapsMsgSupported = 0;
8147 VOS_STATUS vstatus;
8148
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008149 memset(&versionCompiled, 0, sizeof(versionCompiled));
8150 memset(&versionReported, 0, sizeof(versionReported));
8151
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008152 /* retrieve and display WCNSS version information */
8153 do {
8154
8155 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8156 &versionCompiled);
8157 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8158 {
8159 hddLog(VOS_TRACE_LEVEL_FATAL,
8160 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008161 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008162 break;
8163 }
8164
8165 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8166 &versionReported);
8167 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8168 {
8169 hddLog(VOS_TRACE_LEVEL_FATAL,
8170 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008171 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008172 break;
8173 }
8174
8175 if ((versionCompiled.major != versionReported.major) ||
8176 (versionCompiled.minor != versionReported.minor) ||
8177 (versionCompiled.version != versionReported.version) ||
8178 (versionCompiled.revision != versionReported.revision))
8179 {
8180 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8181 "Host expected %u.%u.%u.%u\n",
8182 WLAN_MODULE_NAME,
8183 (int)versionReported.major,
8184 (int)versionReported.minor,
8185 (int)versionReported.version,
8186 (int)versionReported.revision,
8187 (int)versionCompiled.major,
8188 (int)versionCompiled.minor,
8189 (int)versionCompiled.version,
8190 (int)versionCompiled.revision);
8191 }
8192 else
8193 {
8194 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8195 WLAN_MODULE_NAME,
8196 (int)versionReported.major,
8197 (int)versionReported.minor,
8198 (int)versionReported.version,
8199 (int)versionReported.revision);
8200 }
8201
8202 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8203 versionString,
8204 sizeof(versionString));
8205 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8206 {
8207 hddLog(VOS_TRACE_LEVEL_FATAL,
8208 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008209 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008210 break;
8211 }
8212
8213 pr_info("%s: WCNSS software version %s\n",
8214 WLAN_MODULE_NAME, versionString);
8215
8216 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8217 versionString,
8218 sizeof(versionString));
8219 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8220 {
8221 hddLog(VOS_TRACE_LEVEL_FATAL,
8222 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008223 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008224 break;
8225 }
8226
8227 pr_info("%s: WCNSS hardware version %s\n",
8228 WLAN_MODULE_NAME, versionString);
8229
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008230 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8231 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008232 send the message only if it the riva is 1.1
8233 minor numbers for different riva branches:
8234 0 -> (1.0)Mainline Build
8235 1 -> (1.1)Mainline Build
8236 2->(1.04) Stability Build
8237 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008238 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008239 ((versionReported.minor>=1) && (versionReported.version>=1)))
8240 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8241 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008242
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008243 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008244 {
8245#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8246 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8247 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8248#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008249 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8250 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8251 {
8252 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8253 }
8254
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008255 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008256 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008257
8258 } while (0);
8259
8260}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308261void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8262{
8263 struct sk_buff *skb;
8264 struct nlmsghdr *nlh;
8265 tAniMsgHdr *ani_hdr;
8266
8267 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8268
8269 if(skb == NULL) {
8270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8271 "%s: alloc_skb failed", __func__);
8272 return;
8273 }
8274
8275 nlh = (struct nlmsghdr *)skb->data;
8276 nlh->nlmsg_pid = 0; /* from kernel */
8277 nlh->nlmsg_flags = 0;
8278 nlh->nlmsg_seq = 0;
8279 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8280
8281 ani_hdr = NLMSG_DATA(nlh);
8282 ani_hdr->type = type;
8283
8284 switch(type) {
8285 case WLAN_SVC_SAP_RESTART_IND:
8286 ani_hdr->length = 0;
8287 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8288 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8289 break;
8290 default:
8291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8292 "Attempt to send unknown nlink message %d", type);
8293 kfree_skb(skb);
8294 return;
8295 }
8296
8297 nl_srv_bcast(skb);
8298
8299 return;
8300}
8301
8302
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008303
8304/**---------------------------------------------------------------------------
8305
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308306 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8307
8308 \param - pHddCtx - Pointer to the hdd context
8309
8310 \return - true if hardware supports 5GHz
8311
8312 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308313boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308314{
8315 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8316 * then hardware support 5Ghz.
8317 */
8318 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8319 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308321 return true;
8322 }
8323 else
8324 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308326 __func__);
8327 return false;
8328 }
8329}
8330
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308331/**---------------------------------------------------------------------------
8332
8333 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8334 generate function
8335
8336 This is generate the random mac address for WLAN interface
8337
8338 \param - pHddCtx - Pointer to HDD context
8339 idx - Start interface index to get auto
8340 generated mac addr.
8341 mac_addr - Mac address
8342
8343 \return - 0 for success, < 0 for failure
8344
8345 --------------------------------------------------------------------------*/
8346
8347static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8348 int idx, v_MACADDR_t mac_addr)
8349{
8350 int i;
8351 unsigned int serialno;
8352 serialno = wcnss_get_serial_number();
8353
8354 if (0 != serialno)
8355 {
8356 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8357 bytes of the serial number that can be used to generate
8358 the other 3 bytes of the MAC address. Mask off all but
8359 the lower 3 bytes (this will also make sure we don't
8360 overflow in the next step) */
8361 serialno &= 0x00FFFFFF;
8362
8363 /* we need a unique address for each session */
8364 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8365
8366 /* autogen other Mac addresses */
8367 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8368 {
8369 /* start with the entire default address */
8370 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8371 /* then replace the lower 3 bytes */
8372 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8373 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8374 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8375
8376 serialno++;
8377 hddLog(VOS_TRACE_LEVEL_ERROR,
8378 "%s: Derived Mac Addr: "
8379 MAC_ADDRESS_STR, __func__,
8380 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8381 }
8382
8383 }
8384 else
8385 {
8386 hddLog(LOGE, FL("Failed to Get Serial NO"));
8387 return -1;
8388 }
8389 return 0;
8390}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308391
8392/**---------------------------------------------------------------------------
8393
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308394 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8395 completed to flush out the scan results
8396
8397 11d scan is done during driver load and is a passive scan on all
8398 channels supported by the device, 11d scans may find some APs on
8399 frequencies which are forbidden to be used in the regulatory domain
8400 the device is operating in. If these APs are notified to the supplicant
8401 it may try to connect to these APs, thus flush out all the scan results
8402 which are present in SME after 11d scan is done.
8403
8404 \return - eHalStatus
8405
8406 --------------------------------------------------------------------------*/
8407static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8408 tANI_U32 scanId, eCsrScanStatus status)
8409{
8410 ENTER();
8411
8412 sme_ScanFlushResult(halHandle, 0);
8413
8414 EXIT();
8415
8416 return eHAL_STATUS_SUCCESS;
8417}
8418
8419/**---------------------------------------------------------------------------
8420
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 \brief hdd_wlan_startup() - HDD init function
8422
8423 This is the driver startup code executed once a WLAN device has been detected
8424
8425 \param - dev - Pointer to the underlying device
8426
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008427 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008428
8429 --------------------------------------------------------------------------*/
8430
8431int hdd_wlan_startup(struct device *dev )
8432{
8433 VOS_STATUS status;
8434 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008435 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 hdd_context_t *pHddCtx = NULL;
8437 v_CONTEXT_t pVosContext= NULL;
8438#ifdef WLAN_BTAMP_FEATURE
8439 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8440 WLANBAP_ConfigType btAmpConfig;
8441 hdd_config_t *pConfig;
8442#endif
8443 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308445 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008446
8447 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 /*
8449 * cfg80211: wiphy allocation
8450 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308451 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008452
8453 if(wiphy == NULL)
8454 {
8455 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008456 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 }
8458
8459 pHddCtx = wiphy_priv(wiphy);
8460
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 //Initialize the adapter context to zeros.
8462 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8463
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308466 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008467
8468 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8469
8470 /*Get vos context here bcoz vos_open requires it*/
8471 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8472
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008473 if(pVosContext == NULL)
8474 {
8475 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8476 goto err_free_hdd_context;
8477 }
8478
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 //Save the Global VOSS context in adapter context for future.
8480 pHddCtx->pvosContext = pVosContext;
8481
8482 //Save the adapter context in global context for future.
8483 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8484
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 pHddCtx->parent_dev = dev;
8486
8487 init_completion(&pHddCtx->full_pwr_comp_var);
8488 init_completion(&pHddCtx->standby_comp_var);
8489 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008490 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008491 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308492 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308493 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008494
8495#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008496 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008497#else
8498 init_completion(&pHddCtx->driver_crda_req);
8499#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008500
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308501 spin_lock_init(&pHddCtx->schedScan_lock);
8502
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8504
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308505#ifdef FEATURE_WLAN_TDLS
8506 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8507 * invoked by other instances also) to protect the concurrent
8508 * access for the Adapters by TDLS module.
8509 */
8510 mutex_init(&pHddCtx->tdls_lock);
8511#endif
Agarwal Ashish1f422872014-07-22 00:11:55 +05308512 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308513
Agarwal Ashish1f422872014-07-22 00:11:55 +05308514 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 // Load all config first as TL config is needed during vos_open
8516 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8517 if(pHddCtx->cfg_ini == NULL)
8518 {
8519 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8520 goto err_free_hdd_context;
8521 }
8522
8523 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8524
8525 // Read and parse the qcom_cfg.ini file
8526 status = hdd_parse_config_ini( pHddCtx );
8527 if ( VOS_STATUS_SUCCESS != status )
8528 {
8529 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8530 __func__, WLAN_INI_FILE);
8531 goto err_config;
8532 }
Arif Hussaind5218912013-12-05 01:10:55 -08008533#ifdef MEMORY_DEBUG
8534 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8535 vos_mem_init();
8536
8537 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8538 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8539#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008540
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308541 /* INI has been read, initialise the configuredMcastBcastFilter with
8542 * INI value as this will serve as the default value
8543 */
8544 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8545 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8546 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308547
8548 if (false == hdd_is_5g_supported(pHddCtx))
8549 {
8550 //5Ghz is not supported.
8551 if (1 != pHddCtx->cfg_ini->nBandCapability)
8552 {
8553 hddLog(VOS_TRACE_LEVEL_INFO,
8554 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8555 pHddCtx->cfg_ini->nBandCapability = 1;
8556 }
8557 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308558
8559 /* If SNR Monitoring is enabled, FW has to parse all beacons
8560 * for calcaluting and storing the average SNR, so set Nth beacon
8561 * filter to 1 to enable FW to parse all the beaocons
8562 */
8563 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8564 {
8565 /* The log level is deliberately set to WARN as overriding
8566 * nthBeaconFilter to 1 will increase power cosumption and this
8567 * might just prove helpful to detect the power issue.
8568 */
8569 hddLog(VOS_TRACE_LEVEL_WARN,
8570 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8571 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308574 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008576 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008578 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8579 {
8580 hddLog(VOS_TRACE_LEVEL_FATAL,
8581 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8582 goto err_config;
8583 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008585
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008586 // Update VOS trace levels based upon the cfg.ini
8587 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8588 pHddCtx->cfg_ini->vosTraceEnableBAP);
8589 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8590 pHddCtx->cfg_ini->vosTraceEnableTL);
8591 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8592 pHddCtx->cfg_ini->vosTraceEnableWDI);
8593 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8594 pHddCtx->cfg_ini->vosTraceEnableHDD);
8595 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8596 pHddCtx->cfg_ini->vosTraceEnableSME);
8597 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8598 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308599 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8600 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008601 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8602 pHddCtx->cfg_ini->vosTraceEnableWDA);
8603 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8604 pHddCtx->cfg_ini->vosTraceEnableSYS);
8605 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8606 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008607 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8608 pHddCtx->cfg_ini->vosTraceEnableSAP);
8609 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8610 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008611
Jeff Johnson295189b2012-06-20 16:38:30 -07008612 // Update WDI trace levels based upon the cfg.ini
8613 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8614 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8615 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8616 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8617 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8618 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8619 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8620 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008621
Jeff Johnson88ba7742013-02-27 14:36:02 -08008622 if (VOS_FTM_MODE == hdd_get_conparam())
8623 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8625 {
8626 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8627 goto err_free_hdd_context;
8628 }
8629 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308630
8631 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008634
Jeff Johnson88ba7742013-02-27 14:36:02 -08008635 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8637 {
8638 status = vos_watchdog_open(pVosContext,
8639 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8640
8641 if(!VOS_IS_STATUS_SUCCESS( status ))
8642 {
8643 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308644 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008645 }
8646 }
8647
8648 pHddCtx->isLogpInProgress = FALSE;
8649 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8650
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8652 if(!VOS_IS_STATUS_SUCCESS(status))
8653 {
8654 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008655 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008656 }
8657
Amar Singhala49cbc52013-10-08 18:37:44 -07008658#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008659 /* initialize the NV module. This is required so that
8660 we can initialize the channel information in wiphy
8661 from the NV.bin data. The channel information in
8662 wiphy needs to be initialized before wiphy registration */
8663
8664 status = vos_nv_open();
8665 if (!VOS_IS_STATUS_SUCCESS(status))
8666 {
8667 /* NV module cannot be initialized */
8668 hddLog( VOS_TRACE_LEVEL_FATAL,
8669 "%s: vos_nv_open failed", __func__);
8670 goto err_clkvote;
8671 }
8672
8673 status = vos_init_wiphy_from_nv_bin();
8674 if (!VOS_IS_STATUS_SUCCESS(status))
8675 {
8676 /* NV module cannot be initialized */
8677 hddLog( VOS_TRACE_LEVEL_FATAL,
8678 "%s: vos_init_wiphy failed", __func__);
8679 goto err_vos_nv_close;
8680 }
8681
Amar Singhala49cbc52013-10-08 18:37:44 -07008682#endif
8683
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308684 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 if ( !VOS_IS_STATUS_SUCCESS( status ))
8686 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008687 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308688 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 }
8690
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8692
8693 if ( NULL == pHddCtx->hHal )
8694 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008695 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 goto err_vosclose;
8697 }
8698
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008699 status = vos_preStart( pHddCtx->pvosContext );
8700 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8701 {
8702 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308703 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008704 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008705
Arif Hussaineaf68602013-12-30 23:10:44 -08008706 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8707 {
8708 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8710 __func__, enable_dfs_chan_scan);
8711 }
8712 if (0 == enable_11d || 1 == enable_11d)
8713 {
8714 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8716 __func__, enable_11d);
8717 }
8718
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008719 /* Note that the vos_preStart() sequence triggers the cfg download.
8720 The cfg download must occur before we update the SME config
8721 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008722 status = hdd_set_sme_config( pHddCtx );
8723
8724 if ( VOS_STATUS_SUCCESS != status )
8725 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008726 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308727 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008728 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008729
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 /* In the integrated architecture we update the configuration from
8731 the INI file and from NV before vOSS has been started so that
8732 the final contents are available to send down to the cCPU */
8733
8734 // Apply the cfg.ini to cfg.dat
8735 if (FALSE == hdd_update_config_dat(pHddCtx))
8736 {
8737 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308738 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 }
8740
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308741 // Get mac addr from platform driver
8742 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8743
8744 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308746 /* Store the mac addr for first interface */
8747 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8748
8749 hddLog(VOS_TRACE_LEVEL_ERROR,
8750 "%s: WLAN Mac Addr: "
8751 MAC_ADDRESS_STR, __func__,
8752 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8753
8754 /* Here, passing Arg2 as 1 because we do not want to change the
8755 last 3 bytes (means non OUI bytes) of first interface mac
8756 addr.
8757 */
8758 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8759 {
8760 hddLog(VOS_TRACE_LEVEL_ERROR,
8761 "%s: Failed to generate wlan interface mac addr "
8762 "using MAC from ini file ", __func__);
8763 }
8764 }
8765 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8766 {
8767 // Apply the NV to cfg.dat
8768 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008769#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8770 /* There was not a valid set of MAC Addresses in NV. See if the
8771 default addresses were modified by the cfg.ini settings. If so,
8772 we'll use them, but if not, we'll autogenerate a set of MAC
8773 addresses based upon the device serial number */
8774
8775 static const v_MACADDR_t default_address =
8776 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008777
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308778 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8779 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 {
8781 /* cfg.ini has the default address, invoke autogen logic */
8782
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308783 /* Here, passing Arg2 as 0 because we want to change the
8784 last 3 bytes (means non OUI bytes) of all the interfaces
8785 mac addr.
8786 */
8787 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8788 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308790 hddLog(VOS_TRACE_LEVEL_ERROR,
8791 "%s: Failed to generate wlan interface mac addr "
8792 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8793 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 }
8796 else
8797#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8798 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008799 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 "%s: Invalid MAC address in NV, using MAC from ini file "
8801 MAC_ADDRESS_STR, __func__,
8802 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8803 }
8804 }
8805 {
8806 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308807
8808 /* Set the MAC Address Currently this is used by HAL to
8809 * add self sta. Remove this once self sta is added as
8810 * part of session open.
8811 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8813 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8814 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 if (!HAL_STATUS_SUCCESS( halStatus ))
8817 {
8818 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8819 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308820 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 }
8822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008823
8824 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8825 Note: Firmware image will be read and downloaded inside vos_start API */
8826 status = vos_start( pHddCtx->pvosContext );
8827 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8828 {
8829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308830 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 }
8832
Leo Chang6cec3e22014-01-21 15:33:49 -08008833#ifdef FEATURE_WLAN_CH_AVOID
8834 /* Plug in avoid channel notification callback
8835 * This should happen before ADD_SELF_STA
8836 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308837
8838 /* check the Channel Avoidance is enabled */
8839 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8840 {
8841 sme_AddChAvoidCallback(pHddCtx->hHal,
8842 hdd_hostapd_ch_avoid_cb);
8843 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008844#endif /* FEATURE_WLAN_CH_AVOID */
8845
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008846 /* Exchange capability info between Host and FW and also get versioning info from FW */
8847 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008848
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308849#ifdef CONFIG_ENABLE_LINUX_REG
8850 status = wlan_hdd_init_channels(pHddCtx);
8851 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8852 {
8853 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8854 __func__);
8855 goto err_vosstop;
8856 }
8857#endif
8858
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 status = hdd_post_voss_start_config( pHddCtx );
8860 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8861 {
8862 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8863 __func__);
8864 goto err_vosstop;
8865 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008866
8867#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308868 wlan_hdd_cfg80211_update_reg_info( wiphy );
8869
8870 /* registration of wiphy dev with cfg80211 */
8871 if (0 > wlan_hdd_cfg80211_register(wiphy))
8872 {
8873 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8874 goto err_vosstop;
8875 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008876#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008877
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308878#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308879 /* registration of wiphy dev with cfg80211 */
8880 if (0 > wlan_hdd_cfg80211_register(wiphy))
8881 {
8882 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8883 goto err_vosstop;
8884 }
8885
8886 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8887 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8888 {
8889 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8890 __func__);
8891 goto err_unregister_wiphy;
8892 }
8893#endif
8894
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8896 {
8897 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8898 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8899 }
8900 else
8901 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8903 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8904 if (pAdapter != NULL)
8905 {
kaidde69982014-06-18 13:23:21 +08008906 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308908 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8909 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8910 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008911
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308912 /* Generate the P2P Device Address. This consists of the device's
8913 * primary MAC address with the locally administered bit set.
8914 */
8915 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008916 }
8917 else
8918 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308919 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8920 if (p2p_dev_addr != NULL)
8921 {
8922 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8923 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8924 }
8925 else
8926 {
8927 hddLog(VOS_TRACE_LEVEL_FATAL,
8928 "%s: Failed to allocate mac_address for p2p_device",
8929 __func__);
8930 goto err_close_adapter;
8931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008933
8934 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8935 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8936 if ( NULL == pP2pAdapter )
8937 {
8938 hddLog(VOS_TRACE_LEVEL_FATAL,
8939 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008940 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008941 goto err_close_adapter;
8942 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008945
8946 if( pAdapter == NULL )
8947 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8949 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008951
Arif Hussain66559122013-11-21 10:11:40 -08008952 if (country_code)
8953 {
8954 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008955 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008956 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8957#ifndef CONFIG_ENABLE_LINUX_REG
8958 hdd_checkandupdate_phymode(pAdapter, country_code);
8959#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008960 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8961 (void *)(tSmeChangeCountryCallback)
8962 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008963 country_code,
8964 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308965 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008966 if (eHAL_STATUS_SUCCESS == ret)
8967 {
Arif Hussaincb607082013-12-20 11:57:42 -08008968 ret = wait_for_completion_interruptible_timeout(
8969 &pAdapter->change_country_code,
8970 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8971
8972 if (0 >= ret)
8973 {
8974 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8975 "%s: SME while setting country code timed out", __func__);
8976 }
Arif Hussain66559122013-11-21 10:11:40 -08008977 }
8978 else
8979 {
Arif Hussaincb607082013-12-20 11:57:42 -08008980 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8981 "%s: SME Change Country code from module param fail ret=%d",
8982 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008983 }
8984 }
8985
Jeff Johnson295189b2012-06-20 16:38:30 -07008986#ifdef WLAN_BTAMP_FEATURE
8987 vStatus = WLANBAP_Open(pVosContext);
8988 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8989 {
8990 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8991 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008992 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 }
8994
8995 vStatus = BSL_Init(pVosContext);
8996 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8997 {
8998 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8999 "%s: Failed to Init BSL",__func__);
9000 goto err_bap_close;
9001 }
9002 vStatus = WLANBAP_Start(pVosContext);
9003 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9004 {
9005 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9006 "%s: Failed to start TL",__func__);
9007 goto err_bap_close;
9008 }
9009
9010 pConfig = pHddCtx->cfg_ini;
9011 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9012 status = WLANBAP_SetConfig(&btAmpConfig);
9013
9014#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009015
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009016#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9017 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9018 {
9019 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9020 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9021 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9022 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9023 }
9024#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009025
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309026 wlan_hdd_tdls_init(pHddCtx);
9027
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309028 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9029
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 /* Register with platform driver as client for Suspend/Resume */
9031 status = hddRegisterPmOps(pHddCtx);
9032 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9033 {
9034 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9035#ifdef WLAN_BTAMP_FEATURE
9036 goto err_bap_stop;
9037#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009038 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009039#endif //WLAN_BTAMP_FEATURE
9040 }
9041
Yue Ma0d4891e2013-08-06 17:01:45 -07009042 /* Open debugfs interface */
9043 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9044 {
9045 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9046 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009047 }
9048
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 /* Register TM level change handler function to the platform */
9050 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9051 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9052 {
9053 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9054 goto err_unregister_pmops;
9055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009056
9057 /* register for riva power on lock to platform driver */
9058 if (req_riva_power_on_lock("wlan"))
9059 {
9060 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9061 __func__);
9062 goto err_unregister_pmops;
9063 }
9064
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 // register net device notifier for device change notification
9066 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9067
9068 if(ret < 0)
9069 {
9070 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9071 goto err_free_power_on_lock;
9072 }
9073
9074 //Initialize the nlink service
9075 if(nl_srv_init() != 0)
9076 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309077 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 goto err_reg_netdev;
9079 }
9080
Leo Chang4ce1cc52013-10-21 18:27:15 -07009081#ifdef WLAN_KD_READY_NOTIFIER
9082 pHddCtx->kd_nl_init = 1;
9083#endif /* WLAN_KD_READY_NOTIFIER */
9084
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 //Initialize the BTC service
9086 if(btc_activate_service(pHddCtx) != 0)
9087 {
9088 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9089 goto err_nl_srv;
9090 }
9091
9092#ifdef PTT_SOCK_SVC_ENABLE
9093 //Initialize the PTT service
9094 if(ptt_sock_activate_svc(pHddCtx) != 0)
9095 {
9096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9097 goto err_nl_srv;
9098 }
9099#endif
9100
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309101#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9102 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9103 {
9104 if(wlan_logging_sock_activate_svc(
9105 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9106 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9107 {
9108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9109 " failed", __func__);
9110 goto err_nl_srv;
9111 }
9112 }
9113#endif
9114
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009118 /* Action frame registered in one adapter which will
9119 * applicable to all interfaces
9120 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309121 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009123
9124 mutex_init(&pHddCtx->sap_lock);
9125
Jeff Johnson295189b2012-06-20 16:38:30 -07009126
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009127#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009128#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9129 /* Initialize the wake lcok */
9130 wake_lock_init(&pHddCtx->rx_wake_lock,
9131 WAKE_LOCK_SUSPEND,
9132 "qcom_rx_wakelock");
9133#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009134 /* Initialize the wake lcok */
9135 wake_lock_init(&pHddCtx->sap_wake_lock,
9136 WAKE_LOCK_SUSPEND,
9137 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009138#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009139
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009140 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9141 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009142
Katya Nigam5c306ea2014-06-19 15:39:54 +05309143 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9145 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309146
9147#ifdef FEATURE_WLAN_SCAN_PNO
9148 /*SME must send channel update configuration to RIVA*/
9149 sme_UpdateChannelConfig(pHddCtx->hHal);
9150#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309151 /* Send the update default channel list to the FW*/
9152 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309153#ifndef CONFIG_ENABLE_LINUX_REG
9154 /*updating wiphy so that regulatory user hints can be processed*/
9155 if (wiphy)
9156 {
9157 regulatory_hint(wiphy, "00");
9158 }
9159#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009160 // Initialize the restart logic
9161 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309162
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009163 //Register the traffic monitor timer now
9164 if ( pHddCtx->cfg_ini->dynSplitscan)
9165 {
9166 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9167 VOS_TIMER_TYPE_SW,
9168 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9169 (void *)pHddCtx);
9170 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309171#ifdef WLAN_FEATURE_EXTSCAN
9172 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9173 wlan_hdd_cfg80211_extscan_callback,
9174 pHddCtx);
9175#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009176 goto success;
9177
9178err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009179#ifdef WLAN_KD_READY_NOTIFIER
9180 nl_srv_exit(pHddCtx->ptt_pid);
9181#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009183#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009184err_reg_netdev:
9185 unregister_netdevice_notifier(&hdd_netdev_notifier);
9186
9187err_free_power_on_lock:
9188 free_riva_power_on_lock("wlan");
9189
9190err_unregister_pmops:
9191 hddDevTmUnregisterNotifyCallback(pHddCtx);
9192 hddDeregisterPmOps(pHddCtx);
9193
Yue Ma0d4891e2013-08-06 17:01:45 -07009194 hdd_debugfs_exit(pHddCtx);
9195
Jeff Johnson295189b2012-06-20 16:38:30 -07009196#ifdef WLAN_BTAMP_FEATURE
9197err_bap_stop:
9198 WLANBAP_Stop(pVosContext);
9199#endif
9200
9201#ifdef WLAN_BTAMP_FEATURE
9202err_bap_close:
9203 WLANBAP_Close(pVosContext);
9204#endif
9205
Jeff Johnson295189b2012-06-20 16:38:30 -07009206err_close_adapter:
9207 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309208#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309209err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309210#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309211 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009212err_vosstop:
9213 vos_stop(pVosContext);
9214
Amar Singhala49cbc52013-10-08 18:37:44 -07009215err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 status = vos_sched_close( pVosContext );
9217 if (!VOS_IS_STATUS_SUCCESS(status)) {
9218 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9219 "%s: Failed to close VOSS Scheduler", __func__);
9220 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9221 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009222 vos_close(pVosContext );
9223
Amar Singhal0a402232013-10-11 20:57:16 -07009224err_vos_nv_close:
9225
c_hpothue6a36282014-03-19 12:27:38 +05309226#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009227 vos_nv_close();
9228
Jeff Johnson295189b2012-06-20 16:38:30 -07009229err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309230#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009231 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
9233err_wdclose:
9234 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9235 vos_watchdog_close(pVosContext);
9236
Jeff Johnson295189b2012-06-20 16:38:30 -07009237err_config:
9238 kfree(pHddCtx->cfg_ini);
9239 pHddCtx->cfg_ini= NULL;
9240
9241err_free_hdd_context:
9242 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 wiphy_free(wiphy) ;
9244 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 VOS_BUG(1);
9246
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009247 if (hdd_is_ssr_required())
9248 {
9249 /* WDI timeout had happened during load, so SSR is needed here */
9250 subsystem_restart("wcnss");
9251 msleep(5000);
9252 }
9253 hdd_set_ssr_required (VOS_FALSE);
9254
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009255 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009256
9257success:
9258 EXIT();
9259 return 0;
9260}
9261
9262/**---------------------------------------------------------------------------
9263
Jeff Johnson32d95a32012-09-10 13:15:23 -07009264 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009265
Jeff Johnson32d95a32012-09-10 13:15:23 -07009266 This is the driver entry point - called in different timeline depending
9267 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009268
9269 \param - None
9270
9271 \return - 0 for success, non zero for failure
9272
9273 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009274static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009275{
9276 VOS_STATUS status;
9277 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 struct device *dev = NULL;
9279 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009280#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9281 int max_retries = 0;
9282#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009283
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309284#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9285 wlan_logging_sock_init_svc();
9286#endif
9287
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 ENTER();
9289
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009290#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009292#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009293
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309294 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9296 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9297
9298 //Power Up Libra WLAN card first if not already powered up
9299 status = vos_chipPowerUp(NULL,NULL,NULL);
9300 if (!VOS_IS_STATUS_SUCCESS(status))
9301 {
9302 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9303 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309304#ifdef WLAN_OPEN_SOURCE
9305 wake_lock_destroy(&wlan_wake_lock);
9306#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309307
9308#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9309 wlan_logging_sock_deinit_svc();
9310#endif
9311
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009312 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 }
9314
Jeff Johnson295189b2012-06-20 16:38:30 -07009315#ifdef ANI_BUS_TYPE_PCI
9316
9317 dev = wcnss_wlan_get_device();
9318
9319#endif // ANI_BUS_TYPE_PCI
9320
9321#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009322
9323#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9324 /* wait until WCNSS driver downloads NV */
9325 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9326 msleep(1000);
9327 }
9328 if (max_retries >= 5) {
9329 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309330#ifdef WLAN_OPEN_SOURCE
9331 wake_lock_destroy(&wlan_wake_lock);
9332#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309333
9334#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9335 wlan_logging_sock_deinit_svc();
9336#endif
9337
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009338 return -ENODEV;
9339 }
9340#endif
9341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 dev = wcnss_wlan_get_device();
9343#endif // ANI_BUS_TYPE_PLATFORM
9344
9345
9346 do {
9347 if (NULL == dev) {
9348 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9349 ret_status = -1;
9350 break;
9351 }
9352
Jeff Johnson295189b2012-06-20 16:38:30 -07009353#ifdef TIMER_MANAGER
9354 vos_timer_manager_init();
9355#endif
9356
9357 /* Preopen VOSS so that it is ready to start at least SAL */
9358 status = vos_preOpen(&pVosContext);
9359
9360 if (!VOS_IS_STATUS_SUCCESS(status))
9361 {
9362 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9363 ret_status = -1;
9364 break;
9365 }
9366
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009367#ifndef MODULE
9368 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9369 */
9370 hdd_set_conparam((v_UINT_t)con_mode);
9371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
9373 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009374 if (hdd_wlan_startup(dev))
9375 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009377 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 vos_preClose( &pVosContext );
9379 ret_status = -1;
9380 break;
9381 }
9382
9383 /* Cancel the vote for XO Core ON
9384 * This is done here for safety purposes in case we re-initialize without turning
9385 * it OFF in any error scenario.
9386 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009387 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009389 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9391 {
9392 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009393 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 }
9395 } while (0);
9396
9397 if (0 != ret_status)
9398 {
9399 //Assert Deep sleep signal now to put Libra HW in lowest power state
9400 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9401 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9402
9403 //Vote off any PMIC voltage supplies
9404 vos_chipPowerDown(NULL, NULL, NULL);
9405#ifdef TIMER_MANAGER
9406 vos_timer_exit();
9407#endif
9408#ifdef MEMORY_DEBUG
9409 vos_mem_exit();
9410#endif
9411
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009412#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009414#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309415
9416#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9417 wlan_logging_sock_deinit_svc();
9418#endif
9419
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9421 }
9422 else
9423 {
9424 //Send WLAN UP indication to Nlink Service
9425 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9426
9427 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 }
9429
9430 EXIT();
9431
9432 return ret_status;
9433}
9434
Jeff Johnson32d95a32012-09-10 13:15:23 -07009435/**---------------------------------------------------------------------------
9436
9437 \brief hdd_module_init() - Init Function
9438
9439 This is the driver entry point (invoked when module is loaded using insmod)
9440
9441 \param - None
9442
9443 \return - 0 for success, non zero for failure
9444
9445 --------------------------------------------------------------------------*/
9446#ifdef MODULE
9447static int __init hdd_module_init ( void)
9448{
9449 return hdd_driver_init();
9450}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009451#else /* #ifdef MODULE */
9452static int __init hdd_module_init ( void)
9453{
9454 /* Driver initialization is delayed to fwpath_changed_handler */
9455 return 0;
9456}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009457#endif /* #ifdef MODULE */
9458
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
9460/**---------------------------------------------------------------------------
9461
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009462 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009463
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009464 This is the driver exit point (invoked when module is unloaded using rmmod
9465 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009466
9467 \param - None
9468
9469 \return - None
9470
9471 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009472static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009473{
9474 hdd_context_t *pHddCtx = NULL;
9475 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309476 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309477 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009478
9479 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9480
9481 //Get the global vos context
9482 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9483
9484 if(!pVosContext)
9485 {
9486 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9487 goto done;
9488 }
9489
9490 //Get the HDD context.
9491 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9492
9493 if(!pHddCtx)
9494 {
9495 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9496 }
9497 else
9498 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309499 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9500
9501 if (pHddCtx->isLogpInProgress)
9502 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309504 "%s:SSR in Progress; block rmmod !!!", __func__);
9505 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9506 msecs_to_jiffies(30000));
9507 if(!rc)
9508 {
9509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9510 "%s:SSR timedout, fatal error", __func__);
9511 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009512 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009514
Mihir Shete18156292014-03-11 15:38:30 +05309515 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9517
Agarwal Ashish8db39882014-07-30 21:56:07 +05309518 /* Driver Need to send country code 00 in below condition
9519 * 1) If gCountryCodePriority is set to 1; and last country
9520 * code set is through 11d. This needs to be done in case
9521 * when NV country code is 00.
9522 * This Needs to be done as when kernel store last country
9523 * code and if stored country code is not through 11d,
9524 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9525 * in next load/unload as soon as we get any country through
9526 * 11d. In sme_HandleChangeCountryCodeByUser
9527 * pMsg->countryCode will be last countryCode and
9528 * pMac->scan.countryCode11d will be country through 11d so
9529 * due to mismatch driver will disable 11d.
9530 *
9531 * 2) When NV country Code is non-zero ;
9532 * There are chances that kernel last country and default
9533 * country can be same. In this case if Driver doesn't pass 00 to
9534 * kernel, at the time of driver loading next timer, driver will not
9535 * call any hint to kernel as country is same. This can add 3 sec
9536 * delay in driver loading.
9537 */
9538
9539 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309540 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Agarwal Ashish8db39882014-07-30 21:56:07 +05309541 sme_Is11dSupported(pHddCtx->hHal)) || (vos_is_nv_country_non_zero() ))
Agarwal Ashish5e414792014-06-08 15:25:23 +05309542 {
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309543 hddLog(VOS_TRACE_LEVEL_INFO,
9544 FL("CountryCode 00 is being set while unloading driver"));
Agarwal Ashish5e414792014-06-08 15:25:23 +05309545 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9546 }
9547
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 //Do all the cleanup before deregistering the driver
9549 hdd_wlan_exit(pHddCtx);
9550 }
9551
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 vos_preClose( &pVosContext );
9553
9554#ifdef TIMER_MANAGER
9555 vos_timer_exit();
9556#endif
9557#ifdef MEMORY_DEBUG
9558 vos_mem_exit();
9559#endif
9560
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309561#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9562 wlan_logging_sock_deinit_svc();
9563#endif
9564
Jeff Johnson295189b2012-06-20 16:38:30 -07009565done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009566#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009568#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309569
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9571}
9572
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009573/**---------------------------------------------------------------------------
9574
9575 \brief hdd_module_exit() - Exit function
9576
9577 This is the driver exit point (invoked when module is unloaded using rmmod)
9578
9579 \param - None
9580
9581 \return - None
9582
9583 --------------------------------------------------------------------------*/
9584static void __exit hdd_module_exit(void)
9585{
9586 hdd_driver_exit();
9587}
9588
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009589#ifdef MODULE
9590static int fwpath_changed_handler(const char *kmessage,
9591 struct kernel_param *kp)
9592{
Jeff Johnson76052702013-04-16 13:55:05 -07009593 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009594}
9595
9596static int con_mode_handler(const char *kmessage,
9597 struct kernel_param *kp)
9598{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009599 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009600}
9601#else /* #ifdef MODULE */
9602/**---------------------------------------------------------------------------
9603
Jeff Johnson76052702013-04-16 13:55:05 -07009604 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009605
Jeff Johnson76052702013-04-16 13:55:05 -07009606 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009607 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009608 - invoked when module parameter fwpath is modified from userspace to signal
9609 initializing the WLAN driver or when con_mode is modified from userspace
9610 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009611
9612 \return - 0 for success, non zero for failure
9613
9614 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009615static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009616{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009617 int ret_status;
9618
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009619 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009620 ret_status = hdd_driver_init();
9621 wlan_hdd_inited = ret_status ? 0 : 1;
9622 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009623 }
9624
9625 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009626
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009627 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009628
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009629 ret_status = hdd_driver_init();
9630 wlan_hdd_inited = ret_status ? 0 : 1;
9631 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009632}
9633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634/**---------------------------------------------------------------------------
9635
Jeff Johnson76052702013-04-16 13:55:05 -07009636 \brief fwpath_changed_handler() - Handler Function
9637
9638 Handle changes to the fwpath parameter
9639
9640 \return - 0 for success, non zero for failure
9641
9642 --------------------------------------------------------------------------*/
9643static int fwpath_changed_handler(const char *kmessage,
9644 struct kernel_param *kp)
9645{
9646 int ret;
9647
9648 ret = param_set_copystring(kmessage, kp);
9649 if (0 == ret)
9650 ret = kickstart_driver();
9651 return ret;
9652}
9653
9654/**---------------------------------------------------------------------------
9655
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009656 \brief con_mode_handler() -
9657
9658 Handler function for module param con_mode when it is changed by userspace
9659 Dynamically linked - do nothing
9660 Statically linked - exit and init driver, as in rmmod and insmod
9661
Jeff Johnson76052702013-04-16 13:55:05 -07009662 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009663
Jeff Johnson76052702013-04-16 13:55:05 -07009664 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009665
9666 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009667static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009668{
Jeff Johnson76052702013-04-16 13:55:05 -07009669 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009670
Jeff Johnson76052702013-04-16 13:55:05 -07009671 ret = param_set_int(kmessage, kp);
9672 if (0 == ret)
9673 ret = kickstart_driver();
9674 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009675}
9676#endif /* #ifdef MODULE */
9677
9678/**---------------------------------------------------------------------------
9679
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 \brief hdd_get_conparam() -
9681
9682 This is the driver exit point (invoked when module is unloaded using rmmod)
9683
9684 \param - None
9685
9686 \return - tVOS_CON_MODE
9687
9688 --------------------------------------------------------------------------*/
9689tVOS_CON_MODE hdd_get_conparam ( void )
9690{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009691#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009693#else
9694 return (tVOS_CON_MODE)curr_con_mode;
9695#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009696}
9697void hdd_set_conparam ( v_UINT_t newParam )
9698{
9699 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009700#ifndef MODULE
9701 curr_con_mode = con_mode;
9702#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009703}
9704/**---------------------------------------------------------------------------
9705
9706 \brief hdd_softap_sta_deauth() - function
9707
9708 This to take counter measure to handle deauth req from HDD
9709
9710 \param - pAdapter - Pointer to the HDD
9711
9712 \param - enable - boolean value
9713
9714 \return - None
9715
9716 --------------------------------------------------------------------------*/
9717
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009718VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009719{
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009721 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009722
9723 ENTER();
9724
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009725 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9726 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009727
9728 //Ignore request to deauth bcmc station
9729 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009730 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009731
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009732 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009733
9734 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009735 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009736}
9737
9738/**---------------------------------------------------------------------------
9739
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309740 \brief hdd_del_all_sta() - function
9741
9742 This function removes all the stations associated on stopping AP/P2P GO.
9743
9744 \param - pAdapter - Pointer to the HDD
9745
9746 \return - None
9747
9748 --------------------------------------------------------------------------*/
9749
9750int hdd_del_all_sta(hdd_adapter_t *pAdapter)
9751{
9752 v_U16_t i;
9753 VOS_STATUS vos_status;
9754
9755 ENTER();
9756
9757 hddLog(VOS_TRACE_LEVEL_INFO,
9758 "%s: Delete all STAs associated.",__func__);
9759 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9760 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
9761 )
9762 {
9763 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
9764 {
9765 if ((pAdapter->aStaInfo[i].isUsed) &&
9766 (!pAdapter->aStaInfo[i].isDeauthInProgress))
9767 {
9768 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
9769 hddLog(VOS_TRACE_LEVEL_ERROR,
9770 "%s: Delete STA with staid = %d and MAC::"
9771 MAC_ADDRESS_STR,
9772 __func__, i, MAC_ADDR_ARRAY(macAddr));
9773 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
9774 if (VOS_IS_STATUS_SUCCESS(vos_status))
9775 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
9776 }
9777 }
9778 }
9779
9780 EXIT();
9781 return 0;
9782}
9783
9784/**---------------------------------------------------------------------------
9785
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 \brief hdd_softap_sta_disassoc() - function
9787
9788 This to take counter measure to handle deauth req from HDD
9789
9790 \param - pAdapter - Pointer to the HDD
9791
9792 \param - enable - boolean value
9793
9794 \return - None
9795
9796 --------------------------------------------------------------------------*/
9797
9798void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9799{
9800 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9801
9802 ENTER();
9803
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309804 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009805
9806 //Ignore request to disassoc bcmc station
9807 if( pDestMacAddress[0] & 0x1 )
9808 return;
9809
9810 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9811}
9812
9813void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9814{
9815 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9816
9817 ENTER();
9818
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309819 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9822}
9823
Jeff Johnson295189b2012-06-20 16:38:30 -07009824/**---------------------------------------------------------------------------
9825 *
9826 * \brief hdd_get__concurrency_mode() -
9827 *
9828 *
9829 * \param - None
9830 *
9831 * \return - CONCURRENCY MODE
9832 *
9833 * --------------------------------------------------------------------------*/
9834tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9835{
9836 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9837 hdd_context_t *pHddCtx;
9838
9839 if (NULL != pVosContext)
9840 {
9841 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9842 if (NULL != pHddCtx)
9843 {
9844 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9845 }
9846 }
9847
9848 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009849 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 return VOS_STA;
9851}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309852v_BOOL_t
9853wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
9854{
9855 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009856
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309857 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
9858 if (pAdapter == NULL)
9859 {
9860 hddLog(VOS_TRACE_LEVEL_INFO,
9861 FL("GO doesn't exist"));
9862 return TRUE;
9863 }
9864 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9865 {
9866 hddLog(VOS_TRACE_LEVEL_INFO,
9867 FL("GO started"));
9868 return TRUE;
9869 }
9870 else
9871 /* wait till GO changes its interface to p2p device */
9872 hddLog(VOS_TRACE_LEVEL_INFO,
9873 FL("Del_bss called, avoid apps suspend"));
9874 return FALSE;
9875
9876}
Jeff Johnson295189b2012-06-20 16:38:30 -07009877/* Decide whether to allow/not the apps power collapse.
9878 * Allow apps power collapse if we are in connected state.
9879 * if not, allow only if we are in IMPS */
9880v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9881{
9882 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009883 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009884 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9886 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9887 hdd_adapter_t *pAdapter = NULL;
9888 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009889 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009890
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9892 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009893
Yathish9f22e662012-12-10 14:21:35 -08009894 concurrent_state = hdd_get_concurrency_mode();
9895
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309896 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
9897 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
9898 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -08009899#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309900
Yathish9f22e662012-12-10 14:21:35 -08009901 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309902 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -08009903 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9904 return TRUE;
9905#endif
9906
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 /*loop through all adapters. TBD fix for Concurrency */
9908 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9909 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9910 {
9911 pAdapter = pAdapterNode->pAdapter;
9912 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9913 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9914 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009915 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309916 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009917 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009918 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9919 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009921 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009922 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9923 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009924 return FALSE;
9925 }
9926 }
9927 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9928 pAdapterNode = pNext;
9929 }
9930 return TRUE;
9931}
9932
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009933/* Decides whether to send suspend notification to Riva
9934 * if any adapter is in BMPS; then it is required */
9935v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9936{
9937 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9938 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9939
9940 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9941 {
9942 return TRUE;
9943 }
9944 return FALSE;
9945}
9946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9948{
9949 switch(mode)
9950 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009951 case VOS_STA_MODE:
9952 case VOS_P2P_CLIENT_MODE:
9953 case VOS_P2P_GO_MODE:
9954 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009955 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309956 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 break;
9958 default:
9959 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309961 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9962 "Number of open sessions for mode %d = %d"),
9963 pHddCtx->concurrency_mode, mode,
9964 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009965}
9966
9967
9968void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9969{
9970 switch(mode)
9971 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009972 case VOS_STA_MODE:
9973 case VOS_P2P_CLIENT_MODE:
9974 case VOS_P2P_GO_MODE:
9975 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +05309976 pHddCtx->no_of_open_sessions[mode]--;
9977 if (!(pHddCtx->no_of_open_sessions[mode]))
9978 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 break;
9980 default:
9981 break;
9982 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309983 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9984 "Number of open sessions for mode %d = %d"),
9985 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
9986
9987}
9988/**---------------------------------------------------------------------------
9989 *
9990 * \brief wlan_hdd_incr_active_session()
9991 *
9992 * This function increments the number of active sessions
9993 * maintained per device mode
9994 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
9995 * Incase of SAP/P2P GO upon bss start it is incremented
9996 *
9997 * \param pHddCtx - HDD Context
9998 * \param mode - device mode
9999 *
10000 * \return - None
10001 *
10002 * --------------------------------------------------------------------------*/
10003void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10004{
10005 switch (mode) {
10006 case VOS_STA_MODE:
10007 case VOS_P2P_CLIENT_MODE:
10008 case VOS_P2P_GO_MODE:
10009 case VOS_STA_SAP_MODE:
10010 pHddCtx->no_of_active_sessions[mode]++;
10011 break;
10012 default:
10013 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10014 break;
10015 }
10016 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10017 mode,
10018 pHddCtx->no_of_active_sessions[mode]);
10019}
10020
10021/**---------------------------------------------------------------------------
10022 *
10023 * \brief wlan_hdd_decr_active_session()
10024 *
10025 * This function decrements the number of active sessions
10026 * maintained per device mode
10027 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10028 * Incase of SAP/P2P GO upon bss stop it is decremented
10029 *
10030 * \param pHddCtx - HDD Context
10031 * \param mode - device mode
10032 *
10033 * \return - None
10034 *
10035 * --------------------------------------------------------------------------*/
10036void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10037{
10038 switch (mode) {
10039 case VOS_STA_MODE:
10040 case VOS_P2P_CLIENT_MODE:
10041 case VOS_P2P_GO_MODE:
10042 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010043 if (pHddCtx->no_of_active_sessions[mode] > 0)
10044 pHddCtx->no_of_active_sessions[mode]--;
10045 else
10046 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10047 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010048 break;
10049 default:
10050 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10051 break;
10052 }
10053 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10054 mode,
10055 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010056}
10057
Jeff Johnsone7245742012-09-05 17:12:55 -070010058/**---------------------------------------------------------------------------
10059 *
10060 * \brief wlan_hdd_restart_init
10061 *
10062 * This function initalizes restart timer/flag. An internal function.
10063 *
10064 * \param - pHddCtx
10065 *
10066 * \return - None
10067 *
10068 * --------------------------------------------------------------------------*/
10069
10070static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10071{
10072 /* Initialize */
10073 pHddCtx->hdd_restart_retries = 0;
10074 atomic_set(&pHddCtx->isRestartInProgress, 0);
10075 vos_timer_init(&pHddCtx->hdd_restart_timer,
10076 VOS_TIMER_TYPE_SW,
10077 wlan_hdd_restart_timer_cb,
10078 pHddCtx);
10079}
10080/**---------------------------------------------------------------------------
10081 *
10082 * \brief wlan_hdd_restart_deinit
10083 *
10084 * This function cleans up the resources used. An internal function.
10085 *
10086 * \param - pHddCtx
10087 *
10088 * \return - None
10089 *
10090 * --------------------------------------------------------------------------*/
10091
10092static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10093{
10094
10095 VOS_STATUS vos_status;
10096 /* Block any further calls */
10097 atomic_set(&pHddCtx->isRestartInProgress, 1);
10098 /* Cleanup */
10099 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10100 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010101 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010102 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10103 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010104 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010105
10106}
10107
10108/**---------------------------------------------------------------------------
10109 *
10110 * \brief wlan_hdd_framework_restart
10111 *
10112 * This function uses a cfg80211 API to start a framework initiated WLAN
10113 * driver module unload/load.
10114 *
10115 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10116 *
10117 *
10118 * \param - pHddCtx
10119 *
10120 * \return - VOS_STATUS_SUCCESS: Success
10121 * VOS_STATUS_E_EMPTY: Adapter is Empty
10122 * VOS_STATUS_E_NOMEM: No memory
10123
10124 * --------------------------------------------------------------------------*/
10125
10126static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10127{
10128 VOS_STATUS status = VOS_STATUS_SUCCESS;
10129 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010130 int len = (sizeof (struct ieee80211_mgmt));
10131 struct ieee80211_mgmt *mgmt = NULL;
10132
10133 /* Prepare the DEAUTH managment frame with reason code */
10134 mgmt = kzalloc(len, GFP_KERNEL);
10135 if(mgmt == NULL)
10136 {
10137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10138 "%s: memory allocation failed (%d bytes)", __func__, len);
10139 return VOS_STATUS_E_NOMEM;
10140 }
10141 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010142
10143 /* Iterate over all adapters/devices */
10144 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10145 do
10146 {
10147 if( (status == VOS_STATUS_SUCCESS) &&
10148 pAdapterNode &&
10149 pAdapterNode->pAdapter)
10150 {
10151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10152 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10153 pAdapterNode->pAdapter->dev->name,
10154 pAdapterNode->pAdapter->device_mode,
10155 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010156 /*
10157 * CFG80211 event to restart the driver
10158 *
10159 * 'cfg80211_send_unprot_deauth' sends a
10160 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10161 * of SME(Linux Kernel) state machine.
10162 *
10163 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10164 * the driver.
10165 *
10166 */
10167
10168 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010169 }
10170 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10171 pAdapterNode = pNext;
10172 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10173
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010174
10175 /* Free the allocated management frame */
10176 kfree(mgmt);
10177
Jeff Johnsone7245742012-09-05 17:12:55 -070010178 /* Retry until we unload or reach max count */
10179 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10180 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10181
10182 return status;
10183
10184}
10185/**---------------------------------------------------------------------------
10186 *
10187 * \brief wlan_hdd_restart_timer_cb
10188 *
10189 * Restart timer callback. An internal function.
10190 *
10191 * \param - User data:
10192 *
10193 * \return - None
10194 *
10195 * --------------------------------------------------------------------------*/
10196
10197void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10198{
10199 hdd_context_t *pHddCtx = usrDataForCallback;
10200 wlan_hdd_framework_restart(pHddCtx);
10201 return;
10202
10203}
10204
10205
10206/**---------------------------------------------------------------------------
10207 *
10208 * \brief wlan_hdd_restart_driver
10209 *
10210 * This function sends an event to supplicant to restart the WLAN driver.
10211 *
10212 * This function is called from vos_wlanRestart.
10213 *
10214 * \param - pHddCtx
10215 *
10216 * \return - VOS_STATUS_SUCCESS: Success
10217 * VOS_STATUS_E_EMPTY: Adapter is Empty
10218 * VOS_STATUS_E_ALREADY: Request already in progress
10219
10220 * --------------------------------------------------------------------------*/
10221VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10222{
10223 VOS_STATUS status = VOS_STATUS_SUCCESS;
10224
10225 /* A tight check to make sure reentrancy */
10226 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10227 {
Mihir Shetefd528652014-06-23 19:07:50 +053010228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010229 "%s: WLAN restart is already in progress", __func__);
10230
10231 return VOS_STATUS_E_ALREADY;
10232 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010233 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010234#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010235 wcnss_reset_intr();
10236#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010237
Jeff Johnsone7245742012-09-05 17:12:55 -070010238 return status;
10239}
10240
Mihir Shetee1093ba2014-01-21 20:13:32 +053010241/**---------------------------------------------------------------------------
10242 *
10243 * \brief wlan_hdd_init_channels
10244 *
10245 * This function is used to initialize the channel list in CSR
10246 *
10247 * This function is called from hdd_wlan_startup
10248 *
10249 * \param - pHddCtx: HDD context
10250 *
10251 * \return - VOS_STATUS_SUCCESS: Success
10252 * VOS_STATUS_E_FAULT: Failure reported by SME
10253
10254 * --------------------------------------------------------------------------*/
10255static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10256{
10257 eHalStatus status;
10258
10259 status = sme_InitChannels(pHddCtx->hHal);
10260 if (HAL_STATUS_SUCCESS(status))
10261 {
10262 return VOS_STATUS_SUCCESS;
10263 }
10264 else
10265 {
10266 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10267 __func__, status);
10268 return VOS_STATUS_E_FAULT;
10269 }
10270}
10271
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010272static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10273{
10274 eHalStatus status;
10275
10276 status = sme_InitChannelsForCC(pHddCtx->hHal);
10277 if (HAL_STATUS_SUCCESS(status))
10278 {
10279 return VOS_STATUS_SUCCESS;
10280 }
10281 else
10282 {
10283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10284 __func__, status);
10285 return VOS_STATUS_E_FAULT;
10286 }
10287}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010288/*
10289 * API to find if there is any STA or P2P-Client is connected
10290 */
10291VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10292{
10293 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10294}
Jeff Johnsone7245742012-09-05 17:12:55 -070010295
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010296int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10297{
10298 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10299 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010300 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010301
10302 pScanInfo = &pHddCtx->scan_info;
10303 if (pScanInfo->mScanPending)
10304 {
10305 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10306 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10307 eCSR_SCAN_ABORT_DEFAULT);
10308
10309 status = wait_for_completion_interruptible_timeout(
10310 &pScanInfo->abortscan_event_var,
10311 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010312 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010313 {
10314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010315 "%s: Timeout or Interrupt occurred while waiting for abort"
10316 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010317 return -ETIMEDOUT;
10318 }
10319 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010320 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010321}
10322
Jeff Johnson295189b2012-06-20 16:38:30 -070010323//Register the module init/exit functions
10324module_init(hdd_module_init);
10325module_exit(hdd_module_exit);
10326
10327MODULE_LICENSE("Dual BSD/GPL");
10328MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10329MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10330
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010331module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10332 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010333
Jeff Johnson76052702013-04-16 13:55:05 -070010334module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010335 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010336
10337module_param(enable_dfs_chan_scan, int,
10338 S_IRUSR | S_IRGRP | S_IROTH);
10339
10340module_param(enable_11d, int,
10341 S_IRUSR | S_IRGRP | S_IROTH);
10342
10343module_param(country_code, charp,
10344 S_IRUSR | S_IRGRP | S_IROTH);