blob: b5440047428866b3a8f346362a557fa41f0aa1ab [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/*========================================================================
31
32 \file wlan_hdd_main.c
33
34 \brief WLAN Host Device Driver implementation
35
36 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
37
38 Qualcomm Confidential and Proprietary.
39
40 ========================================================================*/
41
42/**=========================================================================
43
44 EDIT HISTORY FOR FILE
45
46
47 This section contains comments describing changes made to the module.
48 Notice that changes are listed in reverse chronological order.
49
50
51 $Header:$ $DateTime: $ $Author: $
52
53
54 when who what, where, why
55 -------- --- --------------------------------------------------------
56 04/5/09 Shailender Created module.
57 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
58 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
59 ==========================================================================*/
60
61/*--------------------------------------------------------------------------
62 Include Files
63 ------------------------------------------------------------------------*/
64//#include <wlan_qct_driver.h>
65#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_api.h>
67#include <vos_sched.h>
68#include <vos_power.h>
69#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053084#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <wlan_hdd_wowl.h>
86#include <wlan_hdd_misc.h>
87#include <wlan_hdd_wext.h>
88#ifdef WLAN_BTAMP_FEATURE
89#include <bap_hdd_main.h>
90#include <bapInternal.h>
91#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053092#include "wlan_hdd_trace.h"
93#include "vos_types.h"
94#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095#include <linux/wireless.h>
96#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053097#include <linux/inetdevice.h>
98#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include "wlan_hdd_cfg80211.h"
100#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700102int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#include "sapApi.h"
104#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700105#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
107#include <soc/qcom/subsystem_restart.h>
108#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include <wlan_hdd_hostapd.h>
112#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "wlan_hdd_dev_pwr.h"
115#ifdef WLAN_BTAMP_FEATURE
116#include "bap_hdd_misc.h"
117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800120#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530121#ifdef FEATURE_WLAN_TDLS
122#include "wlan_hdd_tdls.h"
123#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700124#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530143#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530155static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800156
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700158static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700159#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700160
Jeff Johnsone7245742012-09-05 17:12:55 -0700161/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800162 * spinlock for synchronizing asynchronous request/response
163 * (full description of use in wlan_hdd_main.h)
164 */
165DEFINE_SPINLOCK(hdd_context_lock);
166
167/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700168 * The rate at which the driver sends RESTART event to supplicant
169 * once the function 'vos_wlanRestart()' is called
170 *
171 */
172#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
173#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700174
175/*
176 * Size of Driver command strings from upper layer
177 */
178#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
179#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
180
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700182#define TID_MIN_VALUE 0
183#define TID_MAX_VALUE 15
184static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
185 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800186static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
187 tCsrEseBeaconReq *pEseBcnReq);
188#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530190static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530191/*
192 * Maximum buffer size used for returning the data back to user space
193 */
194#define WLAN_MAX_BUF_SIZE 1024
195#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700196/*
197 * Driver miracast parameters 0-Disabled
198 * 1-Source, 2-Sink
199 */
200#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
202
c_hpothu92367912014-05-01 15:18:17 +0530203//wait time for beacon miss rate.
204#define BCN_MISS_RATE_TIME 500
205
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800206#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700207static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700210static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700211
212//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700213static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
214static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
215static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
216void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800217void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219v_U16_t hdd_select_queue(struct net_device *dev,
220 struct sk_buff *skb);
221
222#ifdef WLAN_FEATURE_PACKET_FILTERING
223static void hdd_set_multicast_list(struct net_device *dev);
224#endif
225
226void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
227
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800228#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800229void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
230static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700231static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
232 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
233 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700234static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
235 tANI_U8 *pTargetApBssid,
236 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800237#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800238#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700239VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800240#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700241
Mihir Shetee1093ba2014-01-21 20:13:32 +0530242static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530243const char * hdd_device_modetoString(v_U8_t device_mode)
244{
245 switch(device_mode)
246 {
247 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
248 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
250 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
251 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
252 CASE_RETURN_STRING( WLAN_HDD_FTM );
253 CASE_RETURN_STRING( WLAN_HDD_IBSS );
254 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
255 default:
256 return "device_mode Unknown";
257 }
258}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530259
Jeff Johnson295189b2012-06-20 16:38:30 -0700260static int hdd_netdev_notifier_call(struct notifier_block * nb,
261 unsigned long state,
262 void *ndev)
263{
264 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700266 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267#ifdef WLAN_BTAMP_FEATURE
268 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530270 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271
272 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700274 (strncmp(dev->name, "p2p", 3)))
275 return NOTIFY_DONE;
276
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 VOS_ASSERT(0);
284 return NOTIFY_DONE;
285 }
286
Jeff Johnson27cee452013-03-27 11:10:24 -0700287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
288 if (NULL == pHddCtx)
289 {
290 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
291 VOS_ASSERT(0);
292 return NOTIFY_DONE;
293 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800294 if (pHddCtx->isLogpInProgress)
295 return NOTIFY_DONE;
296
Jeff Johnson27cee452013-03-27 11:10:24 -0700297
298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
299 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301 switch (state) {
302 case NETDEV_REGISTER:
303 break;
304
305 case NETDEV_UNREGISTER:
306 break;
307
308 case NETDEV_UP:
309 break;
310
311 case NETDEV_DOWN:
312 break;
313
314 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700315 if(TRUE == pAdapter->isLinkUpSvcNeeded)
316 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 break;
318
319 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530320 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530321 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530322 {
323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
324 "%s: Timeout occurred while waiting for abortscan %ld",
325 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327 else
328 {
329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530330 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 }
332#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 status = WLANBAP_StopAmp();
335 if(VOS_STATUS_SUCCESS != status )
336 {
337 pHddCtx->isAmpAllowed = VOS_TRUE;
338 hddLog(VOS_TRACE_LEVEL_FATAL,
339 "%s: Failed to stop AMP", __func__);
340 }
341 else
342 {
343 //a state m/c implementation in PAL is TBD to avoid this delay
344 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700345 if ( pHddCtx->isAmpAllowed )
346 {
347 WLANBAP_DeregisterFromHCI();
348 pHddCtx->isAmpAllowed = VOS_FALSE;
349 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 }
351#endif //WLAN_BTAMP_FEATURE
352 break;
353
354 default:
355 break;
356 }
357
358 return NOTIFY_DONE;
359}
360
361struct notifier_block hdd_netdev_notifier = {
362 .notifier_call = hdd_netdev_notifier_call,
363};
364
365/*---------------------------------------------------------------------------
366 * Function definitions
367 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700368void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
369void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700371static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700372#ifndef MODULE
373/* current con_mode - used only for statically linked driver
374 * con_mode is changed by userspace to indicate a mode change which will
375 * result in calling the module exit and init functions. The module
376 * exit function will clean up based on the value of con_mode prior to it
377 * being changed by userspace. So curr_con_mode records the current con_mode
378 * for exit when con_mode becomes the next mode for init
379 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700380static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700381#endif
382
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800383/**---------------------------------------------------------------------------
384
385 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
386
387 Called immediately after the cfg.ini is read in order to configure
388 the desired trace levels.
389
390 \param - moduleId - module whose trace level is being configured
391 \param - bitmask - bitmask of log levels to be enabled
392
393 \return - void
394
395 --------------------------------------------------------------------------*/
396static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
397{
398 wpt_tracelevel level;
399
400 /* if the bitmask is the default value, then a bitmask was not
401 specified in cfg.ini, so leave the logging level alone (it
402 will remain at the "compiled in" default value) */
403 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
404 {
405 return;
406 }
407
408 /* a mask was specified. start by disabling all logging */
409 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
410
411 /* now cycle through the bitmask until all "set" bits are serviced */
412 level = VOS_TRACE_LEVEL_FATAL;
413 while (0 != bitmask)
414 {
415 if (bitmask & 1)
416 {
417 vos_trace_setValue(moduleId, level, 1);
418 }
419 level++;
420 bitmask >>= 1;
421 }
422}
423
424
Jeff Johnson295189b2012-06-20 16:38:30 -0700425/**---------------------------------------------------------------------------
426
427 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
428
429 Called immediately after the cfg.ini is read in order to configure
430 the desired trace levels in the WDI.
431
432 \param - moduleId - module whose trace level is being configured
433 \param - bitmask - bitmask of log levels to be enabled
434
435 \return - void
436
437 --------------------------------------------------------------------------*/
438static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
439{
440 wpt_tracelevel level;
441
442 /* if the bitmask is the default value, then a bitmask was not
443 specified in cfg.ini, so leave the logging level alone (it
444 will remain at the "compiled in" default value) */
445 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
446 {
447 return;
448 }
449
450 /* a mask was specified. start by disabling all logging */
451 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
452
453 /* now cycle through the bitmask until all "set" bits are serviced */
454 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
455 while (0 != bitmask)
456 {
457 if (bitmask & 1)
458 {
459 wpalTraceSetLevel(moduleId, level, 1);
460 }
461 level++;
462 bitmask >>= 1;
463 }
464}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530466/*
467 * FUNCTION: wlan_hdd_validate_context
468 * This function is used to check the HDD context
469 */
470int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
471{
472 ENTER();
473
474 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
475 {
476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
477 "%s: HDD context is Null", __func__);
478 return -ENODEV;
479 }
480
481 if (pHddCtx->isLogpInProgress)
482 {
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: LOGP in Progress. Ignore!!!", __func__);
485 return -EAGAIN;
486 }
487
Mihir Shete18156292014-03-11 15:38:30 +0530488 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530489 {
490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
491 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
492 return -EAGAIN;
493 }
494 return 0;
495}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700496#ifdef CONFIG_ENABLE_LINUX_REG
497void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
498{
499 hdd_adapter_t *pAdapter = NULL;
500 hdd_station_ctx_t *pHddStaCtx = NULL;
501 eCsrPhyMode phyMode;
502 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530503
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700504 if (NULL == pHddCtx)
505 {
506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
507 "HDD Context is null !!");
508 return ;
509 }
510
511 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
512 if (NULL == pAdapter)
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
515 "pAdapter is null !!");
516 return ;
517 }
518
519 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
520 if (NULL == pHddStaCtx)
521 {
522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
523 "pHddStaCtx is null !!");
524 return ;
525 }
526
527 cfg_param = pHddCtx->cfg_ini;
528 if (NULL == cfg_param)
529 {
530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
531 "cfg_params not available !!");
532 return ;
533 }
534
535 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
536
537 if (!pHddCtx->isVHT80Allowed)
538 {
539 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
540 (eCSR_DOT11_MODE_11ac == phyMode) ||
541 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
542 {
543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
544 "Setting phymode to 11n!!");
545 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
546 }
547 }
548 else
549 {
550 /*New country Supports 11ac as well resetting value back from .ini*/
551 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
552 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
553 return ;
554 }
555
556 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
557 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
558 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
559 {
560 VOS_STATUS vosStatus;
561
562 // need to issue a disconnect to CSR.
563 INIT_COMPLETION(pAdapter->disconnect_comp_var);
564 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
565 pAdapter->sessionId,
566 eCSR_DISCONNECT_REASON_UNSPECIFIED );
567
568 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530569 {
570 long ret;
571
572 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700573 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530574 if (0 >= ret)
575 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
576 ret);
577 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578
579 }
580}
581#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530582void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
583{
584 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
585 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
586 hdd_config_t *cfg_param;
587 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530588 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589
590 if (NULL == pHddCtx)
591 {
592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
593 "HDD Context is null !!");
594 return ;
595 }
596
597 cfg_param = pHddCtx->cfg_ini;
598
599 if (NULL == cfg_param)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
602 "cfg_params not available !!");
603 return ;
604 }
605
606 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
607
608 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
609 {
610 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
611 (eCSR_DOT11_MODE_11ac == phyMode) ||
612 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
613 {
614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
615 "Setting phymode to 11n!!");
616 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
617 }
618 }
619 else
620 {
621 /*New country Supports 11ac as well resetting value back from .ini*/
622 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
623 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
624 return ;
625 }
626
627 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
628 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
629 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
630 {
631 VOS_STATUS vosStatus;
632
633 // need to issue a disconnect to CSR.
634 INIT_COMPLETION(pAdapter->disconnect_comp_var);
635 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
636 pAdapter->sessionId,
637 eCSR_DISCONNECT_REASON_UNSPECIFIED );
638
639 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530640 {
641 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530643 if (ret <= 0)
644 {
645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
646 "wait on disconnect_comp_var is failed %ld", ret);
647 }
648 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649
650 }
651}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700652#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530653
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700654void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
655{
656 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
657 hdd_config_t *cfg_param;
658
659 if (NULL == pHddCtx)
660 {
661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
662 "HDD Context is null !!");
663 return ;
664 }
665
666 cfg_param = pHddCtx->cfg_ini;
667
668 if (NULL == cfg_param)
669 {
670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
671 "cfg_params not available !!");
672 return ;
673 }
674
675 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
676 {
677 /*New country doesn't support DFS */
678 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
679 }
680 else
681 {
682 /*New country Supports DFS as well resetting value back from .ini*/
683 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
684 }
685
686}
687
Rajeev79dbe4c2013-10-05 11:03:42 +0530688#ifdef FEATURE_WLAN_BATCH_SCAN
689
690/**---------------------------------------------------------------------------
691
692 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
693 input string
694
695 This function extracts assigned integer from string in below format:
696 "STRING=10" : extracts integer 10 from this string
697
698 \param - pInPtr Pointer to input string
699 \param - base Base for string to int conversion(10 for decimal 16 for hex)
700 \param - pOutPtr Pointer to variable in which extracted integer needs to be
701 assigned
702 \param - pLastArg to tell whether it is last arguement in input string or
703 not
704
705 \return - NULL for failure cases
706 pointer to next arguement in input string for success cases
707 --------------------------------------------------------------------------*/
708static tANI_U8 *
709hdd_extract_assigned_int_from_str
710(
711 tANI_U8 *pInPtr,
712 tANI_U8 base,
713 tANI_U32 *pOutPtr,
714 tANI_U8 *pLastArg
715)
716{
717 int tempInt;
718 int v = 0;
719 char buf[32];
720 int val = 0;
721 *pLastArg = FALSE;
722
723 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
724 if (NULL == pInPtr)
725 {
726 return NULL;
727 }
728
729 pInPtr++;
730
731 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
732
733 val = sscanf(pInPtr, "%32s ", buf);
734 if (val < 0 && val > strlen(pInPtr))
735 {
736 return NULL;
737 }
738 pInPtr += val;
739 v = kstrtos32(buf, base, &tempInt);
740 if (v < 0)
741 {
742 return NULL;
743 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800744 if (tempInt < 0)
745 {
746 tempInt = 0;
747 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530748 *pOutPtr = tempInt;
749
750 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
751 if (NULL == pInPtr)
752 {
753 *pLastArg = TRUE;
754 return NULL;
755 }
756 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
757
758 return pInPtr;
759}
760
761/**---------------------------------------------------------------------------
762
763 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
764 input string
765
766 This function extracts assigned character from string in below format:
767 "STRING=A" : extracts char 'A' from this string
768
769 \param - pInPtr Pointer to input string
770 \param - pOutPtr Pointer to variable in which extracted char needs to be
771 assigned
772 \param - pLastArg to tell whether it is last arguement in input string or
773 not
774
775 \return - NULL for failure cases
776 pointer to next arguement in input string for success cases
777 --------------------------------------------------------------------------*/
778static tANI_U8 *
779hdd_extract_assigned_char_from_str
780(
781 tANI_U8 *pInPtr,
782 tANI_U8 *pOutPtr,
783 tANI_U8 *pLastArg
784)
785{
786 *pLastArg = FALSE;
787
788 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
789 if (NULL == pInPtr)
790 {
791 return NULL;
792 }
793
794 pInPtr++;
795
796 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
797
798 *pOutPtr = *pInPtr;
799
800 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
801 if (NULL == pInPtr)
802 {
803 *pLastArg = TRUE;
804 return NULL;
805 }
806 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
807
808 return pInPtr;
809}
810
811
812/**---------------------------------------------------------------------------
813
814 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
815
816 This function parses set batch scan command in below format:
817 WLS_BATCHING_SET <space> followed by below arguements
818 "SCANFREQ=XX" : Optional defaults to 30 sec
819 "MSCAN=XX" : Required number of scans to attempt to batch
820 "BESTN=XX" : Best Network (RSSI) defaults to 16
821 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
822 A. implies only 5 GHz , B. implies only 2.4GHz
823 "RTT=X" : optional defaults to 0
824 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
825 error
826
827 For example input commands:
828 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
829 translated into set batch scan with following parameters:
830 a) Frequence 60 seconds
831 b) Batch 10 scans together
832 c) Best RSSI to be 20
833 d) 5GHz band only
834 e) RTT is equal to 0
835
836 \param - pValue Pointer to input channel list
837 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
838
839 \return - 0 for success non-zero for failure
840
841 --------------------------------------------------------------------------*/
842static int
843hdd_parse_set_batchscan_command
844(
845 tANI_U8 *pValue,
846 tSirSetBatchScanReq *pHddSetBatchScanReq
847)
848{
849 tANI_U8 *inPtr = pValue;
850 tANI_U8 val = 0;
851 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800852 tANI_U32 nScanFreq;
853 tANI_U32 nMscan;
854 tANI_U32 nBestN;
855 tANI_U8 ucRfBand;
856 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800857 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530858
859 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
861 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
862 nRtt = 0;
863 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530864
865 /*go to space after WLS_BATCHING_SET command*/
866 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
867 /*no argument after the command*/
868 if (NULL == inPtr)
869 {
870 return -EINVAL;
871 }
872
873 /*no space after the command*/
874 else if (SPACE_ASCII_VALUE != *inPtr)
875 {
876 return -EINVAL;
877 }
878
879 /*removing empty spaces*/
880 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
881
882 /*no argument followed by spaces*/
883 if ('\0' == *inPtr)
884 {
885 return -EINVAL;
886 }
887
888 /*check and parse SCANFREQ*/
889 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
890 {
891 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800892 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800893
Rajeev Kumarc933d982013-11-18 20:04:20 -0800894 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800895 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800897 }
898
Rajeev79dbe4c2013-10-05 11:03:42 +0530899 if ( (NULL == inPtr) || (TRUE == lastArg))
900 {
901 return -EINVAL;
902 }
903 }
904
905 /*check and parse MSCAN*/
906 if ((strncmp(inPtr, "MSCAN", 5) == 0))
907 {
908 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800909 &nMscan, &lastArg);
910
911 if (0 == nMscan)
912 {
913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
914 "invalid MSCAN=%d", nMscan);
915 return -EINVAL;
916 }
917
Rajeev79dbe4c2013-10-05 11:03:42 +0530918 if (TRUE == lastArg)
919 {
920 goto done;
921 }
922 else if (NULL == inPtr)
923 {
924 return -EINVAL;
925 }
926 }
927 else
928 {
929 return -EINVAL;
930 }
931
932 /*check and parse BESTN*/
933 if ((strncmp(inPtr, "BESTN", 5) == 0))
934 {
935 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800936 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800937
Rajeev Kumarc933d982013-11-18 20:04:20 -0800938 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800939 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800941 }
942
Rajeev79dbe4c2013-10-05 11:03:42 +0530943 if (TRUE == lastArg)
944 {
945 goto done;
946 }
947 else if (NULL == inPtr)
948 {
949 return -EINVAL;
950 }
951 }
952
953 /*check and parse CHANNEL*/
954 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
955 {
956 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800957
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 if (('A' == val) || ('a' == val))
959 {
c_hpothuebf89732014-02-25 13:00:24 +0530960 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530961 }
962 else if (('B' == val) || ('b' == val))
963 {
c_hpothuebf89732014-02-25 13:00:24 +0530964 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 }
966 else
967 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800968 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
969 }
970
971 if (TRUE == lastArg)
972 {
973 goto done;
974 }
975 else if (NULL == inPtr)
976 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530977 return -EINVAL;
978 }
979 }
980
981 /*check and parse RTT*/
982 if ((strncmp(inPtr, "RTT", 3) == 0))
983 {
984 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800985 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530986 if (TRUE == lastArg)
987 {
988 goto done;
989 }
990 if (NULL == inPtr)
991 {
992 return -EINVAL;
993 }
994 }
995
996
997done:
998
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800999 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1000 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1001 pHddSetBatchScanReq->bestNetwork = nBestN;
1002 pHddSetBatchScanReq->rfBand = ucRfBand;
1003 pHddSetBatchScanReq->rtt = nRtt;
1004
Rajeev79dbe4c2013-10-05 11:03:42 +05301005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1006 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1007 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1008 pHddSetBatchScanReq->scanFrequency,
1009 pHddSetBatchScanReq->numberOfScansToBatch,
1010 pHddSetBatchScanReq->bestNetwork,
1011 pHddSetBatchScanReq->rfBand,
1012 pHddSetBatchScanReq->rtt);
1013
1014 return 0;
1015}/*End of hdd_parse_set_batchscan_command*/
1016
1017/**---------------------------------------------------------------------------
1018
1019 \brief hdd_set_batch_scan_req_callback () - This function is called after
1020 receiving set batch scan response from FW and it saves set batch scan
1021 response data FW to HDD context and sets the completion event on
1022 which hdd_ioctl is waiting
1023
1024 \param - callbackContext Pointer to HDD adapter
1025 \param - pRsp Pointer to set batch scan response data received from FW
1026
1027 \return - nothing
1028
1029 --------------------------------------------------------------------------*/
1030static void hdd_set_batch_scan_req_callback
1031(
1032 void *callbackContext,
1033 tSirSetBatchScanRsp *pRsp
1034)
1035{
1036 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1037 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1038
1039 /*sanity check*/
1040 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1041 {
1042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1043 "%s: Invalid pAdapter magic", __func__);
1044 VOS_ASSERT(0);
1045 return;
1046 }
1047 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1048
1049 /*save set batch scan response*/
1050 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1051
1052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1053 "Received set batch scan rsp from FW with nScansToBatch=%d",
1054 pHddSetBatchScanRsp->nScansToBatch);
1055
1056 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1057 complete(&pAdapter->hdd_set_batch_scan_req_var);
1058
1059 return;
1060}/*End of hdd_set_batch_scan_req_callback*/
1061
1062
1063/**---------------------------------------------------------------------------
1064
1065 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1066 info in hdd batch scan response queue
1067
1068 \param - pAdapter Pointer to hdd adapter
1069 \param - pAPMetaInfo Pointer to access point meta info
1070 \param - scanId scan ID of batch scan response
1071 \param - isLastAp tells whether AP is last AP in batch scan response or not
1072
1073 \return - nothing
1074
1075 --------------------------------------------------------------------------*/
1076static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1077 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1078{
1079 tHddBatchScanRsp *pHead;
1080 tHddBatchScanRsp *pNode;
1081 tHddBatchScanRsp *pPrev;
1082 tHddBatchScanRsp *pTemp;
1083 tANI_U8 ssidLen;
1084
1085 /*head of hdd batch scan response queue*/
1086 pHead = pAdapter->pBatchScanRsp;
1087
1088 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1089 if (NULL == pNode)
1090 {
1091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1092 "%s: Could not allocate memory", __func__);
1093 VOS_ASSERT(0);
1094 return;
1095 }
1096
1097 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1098 sizeof(pNode->ApInfo.bssid));
1099 ssidLen = strlen(pApMetaInfo->ssid);
1100 if (SIR_MAX_SSID_SIZE < ssidLen)
1101 {
1102 /*invalid scan result*/
1103 vos_mem_free(pNode);
1104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1105 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1106 return;
1107 }
1108 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1109 /*null terminate ssid*/
1110 pNode->ApInfo.ssid[ssidLen] = '\0';
1111 pNode->ApInfo.ch = pApMetaInfo->ch;
1112 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1113 pNode->ApInfo.age = pApMetaInfo->timestamp;
1114 pNode->ApInfo.batchId = scanId;
1115 pNode->ApInfo.isLastAp = isLastAp;
1116
1117 pNode->pNext = NULL;
1118 if (NULL == pHead)
1119 {
1120 pAdapter->pBatchScanRsp = pNode;
1121 }
1122 else
1123 {
1124 pTemp = pHead;
1125 while (NULL != pTemp)
1126 {
1127 pPrev = pTemp;
1128 pTemp = pTemp->pNext;
1129 }
1130 pPrev->pNext = pNode;
1131 }
1132
1133 return;
1134}/*End of hdd_populate_batch_scan_rsp_queue*/
1135
1136/**---------------------------------------------------------------------------
1137
1138 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1139 receiving batch scan response indication from FW. It saves get batch scan
1140 response data in HDD batch scan response queue. This callback sets the
1141 completion event on which hdd_ioctl is waiting only after getting complete
1142 batch scan response data from FW
1143
1144 \param - callbackContext Pointer to HDD adapter
1145 \param - pRsp Pointer to get batch scan response data received from FW
1146
1147 \return - nothing
1148
1149 --------------------------------------------------------------------------*/
1150static void hdd_batch_scan_result_ind_callback
1151(
1152 void *callbackContext,
1153 void *pRsp
1154)
1155{
1156 v_BOOL_t isLastAp;
1157 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001158 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301159 tANI_U32 numberScanList;
1160 tANI_U32 nextScanListOffset;
1161 tANI_U32 nextApMetaInfoOffset;
1162 hdd_adapter_t* pAdapter;
1163 tpSirBatchScanList pScanList;
1164 tpSirBatchScanNetworkInfo pApMetaInfo;
1165 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1166 tSirSetBatchScanReq *pReq;
1167
1168 pAdapter = (hdd_adapter_t *)callbackContext;
1169 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001170 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301171 {
1172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1173 "%s: Invalid pAdapter magic", __func__);
1174 VOS_ASSERT(0);
1175 return;
1176 }
1177
1178 /*initialize locals*/
1179 pReq = &pAdapter->hddSetBatchScanReq;
1180 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1181 isLastAp = FALSE;
1182 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001183 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301184 numberScanList = 0;
1185 nextScanListOffset = 0;
1186 nextApMetaInfoOffset = 0;
1187 pScanList = NULL;
1188 pApMetaInfo = NULL;
1189
1190 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1191 {
1192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1193 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1194 isLastAp = TRUE;
1195 goto done;
1196 }
1197
1198 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1200 "Batch scan rsp: numberScalList %d", numberScanList);
1201
1202 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1203 {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1205 "%s: numberScanList %d", __func__, numberScanList);
1206 isLastAp = TRUE;
1207 goto done;
1208 }
1209
1210 while (numberScanList)
1211 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001212 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301213 nextScanListOffset);
1214 if (NULL == pScanList)
1215 {
1216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1217 "%s: pScanList is %p", __func__, pScanList);
1218 isLastAp = TRUE;
1219 goto done;
1220 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001221 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001223 "Batch scan rsp: numApMetaInfo %d scanId %d",
1224 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301225
1226 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1227 {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1229 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1230 isLastAp = TRUE;
1231 goto done;
1232 }
1233
Rajeev Kumarce651e42013-10-21 18:57:15 -07001234 /*Initialize next AP meta info offset for next scan list*/
1235 nextApMetaInfoOffset = 0;
1236
Rajeev79dbe4c2013-10-05 11:03:42 +05301237 while (numApMetaInfo)
1238 {
1239 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1240 nextApMetaInfoOffset);
1241 if (NULL == pApMetaInfo)
1242 {
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1244 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1245 isLastAp = TRUE;
1246 goto done;
1247 }
1248 /*calculate AP age*/
1249 pApMetaInfo->timestamp =
1250 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1251
1252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001253 "%s: bssId "MAC_ADDRESS_STR
1254 " ch %d rssi %d timestamp %d", __func__,
1255 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1256 pApMetaInfo->ch, pApMetaInfo->rssi,
1257 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301258
1259 /*mark last AP in batch scan response*/
1260 if ((TRUE == pBatchScanRsp->isLastResult) &&
1261 (1 == numberScanList) && (1 == numApMetaInfo))
1262 {
1263 isLastAp = TRUE;
1264 }
1265
1266 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1267 /*store batch scan repsonse in hdd queue*/
1268 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1269 pScanList->scanId, isLastAp);
1270 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1271
1272 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1273 numApMetaInfo--;
1274 }
1275
Rajeev Kumarce651e42013-10-21 18:57:15 -07001276 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1277 + (sizeof(tSirBatchScanNetworkInfo)
1278 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301279 numberScanList--;
1280 }
1281
1282done:
1283
1284 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1285 requested from hdd_ioctl*/
1286 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1287 (TRUE == isLastAp))
1288 {
1289 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1290 complete(&pAdapter->hdd_get_batch_scan_req_var);
1291 }
1292
1293 return;
1294}/*End of hdd_batch_scan_result_ind_callback*/
1295
1296/**---------------------------------------------------------------------------
1297
1298 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1299 response as per batch scan FR request format by putting proper markers
1300
1301 \param - pDest pointer to destination buffer
1302 \param - cur_len current length
1303 \param - tot_len total remaining size which can be written to user space
1304 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1305 \param - pAdapter Pointer to HDD adapter
1306
1307 \return - ret no of characters written
1308
1309 --------------------------------------------------------------------------*/
1310static tANI_U32
1311hdd_format_batch_scan_rsp
1312(
1313 tANI_U8 *pDest,
1314 tANI_U32 cur_len,
1315 tANI_U32 tot_len,
1316 tHddBatchScanRsp *pApMetaInfo,
1317 hdd_adapter_t* pAdapter
1318)
1319{
1320 tANI_U32 ret = 0;
1321 tANI_U32 rem_len = 0;
1322 tANI_U8 temp_len = 0;
1323 tANI_U8 temp_total_len = 0;
1324 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1325 tANI_U8 *pTemp = temp;
1326
1327 /*Batch scan reponse needs to be returned to user space in
1328 following format:
1329 "scancount=X\n" where X is the number of scans in current batch
1330 batch
1331 "trunc\n" optional present if current scan truncated
1332 "bssid=XX:XX:XX:XX:XX:XX\n"
1333 "ssid=XXXX\n"
1334 "freq=X\n" frequency in Mhz
1335 "level=XX\n"
1336 "age=X\n" ms
1337 "dist=X\n" cm (-1 if not available)
1338 "errror=X\n" (-1if not available)
1339 "====\n" (end of ap marker)
1340 "####\n" (end of scan marker)
1341 "----\n" (end of results)*/
1342 /*send scan result in above format to user space based on
1343 available length*/
1344 /*The GET response may have more data than the driver can return in its
1345 buffer. In that case the buffer should be filled to the nearest complete
1346 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1347 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1348 The final buffer should end with "----\n"*/
1349
1350 /*sanity*/
1351 if (cur_len > tot_len)
1352 {
1353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1354 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1355 return 0;
1356 }
1357 else
1358 {
1359 rem_len = (tot_len - cur_len);
1360 }
1361
1362 /*end scan marker*/
1363 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1364 {
1365 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1366 pTemp += temp_len;
1367 temp_total_len += temp_len;
1368 }
1369
1370 /*bssid*/
1371 temp_len = snprintf(pTemp, sizeof(temp),
1372 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1373 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1374 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1375 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1376 pTemp += temp_len;
1377 temp_total_len += temp_len;
1378
1379 /*ssid*/
1380 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1381 pApMetaInfo->ApInfo.ssid);
1382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*freq*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001387 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301388 pTemp += temp_len;
1389 temp_total_len += temp_len;
1390
1391 /*level*/
1392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1393 pApMetaInfo->ApInfo.rssi);
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301399 pApMetaInfo->ApInfo.age);
1400 pTemp += temp_len;
1401 temp_total_len += temp_len;
1402
1403 /*dist*/
1404 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1405 pTemp += temp_len;
1406 temp_total_len += temp_len;
1407
1408 /*error*/
1409 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1410 pTemp += temp_len;
1411 temp_total_len += temp_len;
1412
1413 /*end AP marker*/
1414 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
1417
1418 /*last AP in batch scan response*/
1419 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1420 {
1421 /*end scan marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*end batch scan result marker*/
1427 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1428 pTemp += temp_len;
1429 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001430
Rajeev79dbe4c2013-10-05 11:03:42 +05301431 }
1432
1433 if (temp_total_len < rem_len)
1434 {
1435 ret = temp_total_len + 1;
1436 strlcpy(pDest, temp, ret);
1437 pAdapter->isTruncated = FALSE;
1438 }
1439 else
1440 {
1441 pAdapter->isTruncated = TRUE;
1442 if (rem_len >= strlen("%%%%"))
1443 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301445 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001446 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301447 {
1448 ret = 0;
1449 }
1450 }
1451
1452 return ret;
1453
1454}/*End of hdd_format_batch_scan_rsp*/
1455
1456/**---------------------------------------------------------------------------
1457
1458 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1459 buffer starting with head of hdd batch scan response queue
1460
1461 \param - pAdapter Pointer to HDD adapter
1462 \param - pDest Pointer to user data buffer
1463 \param - cur_len current offset in user buffer
1464 \param - rem_len remaining no of bytes in user buffer
1465
1466 \return - number of bytes written in user buffer
1467
1468 --------------------------------------------------------------------------*/
1469
1470tANI_U32 hdd_populate_user_batch_scan_rsp
1471(
1472 hdd_adapter_t* pAdapter,
1473 tANI_U8 *pDest,
1474 tANI_U32 cur_len,
1475 tANI_U32 rem_len
1476)
1477{
1478 tHddBatchScanRsp *pHead;
1479 tHddBatchScanRsp *pPrev;
1480 tANI_U32 len;
1481
Rajeev79dbe4c2013-10-05 11:03:42 +05301482 pAdapter->isTruncated = FALSE;
1483
1484 /*head of hdd batch scan response queue*/
1485 pHead = pAdapter->pBatchScanRsp;
1486 while (pHead)
1487 {
1488 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1489 pAdapter);
1490 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001491 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301492 cur_len += len;
1493 if(TRUE == pAdapter->isTruncated)
1494 {
1495 /*result is truncated return rest of scan rsp in next req*/
1496 cur_len = rem_len;
1497 break;
1498 }
1499 pPrev = pHead;
1500 pHead = pHead->pNext;
1501 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001502 if (TRUE == pPrev->ApInfo.isLastAp)
1503 {
1504 pAdapter->prev_batch_id = 0;
1505 }
1506 else
1507 {
1508 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1509 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301510 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001511 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301512 }
1513
1514 return cur_len;
1515}/*End of hdd_populate_user_batch_scan_rsp*/
1516
1517/**---------------------------------------------------------------------------
1518
1519 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1520 scan response data from HDD queue to user space
1521 It does following in detail:
1522 a) if HDD has enough data in its queue then it 1st copies data to user
1523 space and then send get batch scan indication message to FW. In this
1524 case it does not wait on any event and batch scan response data will
1525 be populated in HDD response queue in MC thread context after receiving
1526 indication from FW
1527 b) else send get batch scan indication message to FW and wait on an event
1528 which will be set once HDD receives complete batch scan response from
1529 FW and then this function returns batch scan response to user space
1530
1531 \param - pAdapter Pointer to HDD adapter
1532 \param - pPrivData Pointer to priv_data
1533
1534 \return - 0 for success -EFAULT for failure
1535
1536 --------------------------------------------------------------------------*/
1537
1538int hdd_return_batch_scan_rsp_to_user
1539(
1540 hdd_adapter_t* pAdapter,
1541 hdd_priv_data_t *pPrivData,
1542 tANI_U8 *command
1543)
1544{
1545 tANI_U8 *pDest;
1546 tANI_U32 count = 0;
1547 tANI_U32 len = 0;
1548 tANI_U32 cur_len = 0;
1549 tANI_U32 rem_len = 0;
1550 eHalStatus halStatus;
1551 unsigned long rc;
1552 tSirTriggerBatchScanResultInd *pReq;
1553
1554 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1555 pReq->param = 0;/*batch scan client*/
1556 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1557 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1558
1559 cur_len = pPrivData->used_len;
1560 if (pPrivData->total_len > pPrivData->used_len)
1561 {
1562 rem_len = pPrivData->total_len - pPrivData->used_len;
1563 }
1564 else
1565 {
1566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1567 "%s: Invalid user data buffer total_len %d used_len %d",
1568 __func__, pPrivData->total_len, pPrivData->used_len);
1569 return -EFAULT;
1570 }
1571
1572 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1573 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1574 cur_len, rem_len);
1575 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1576
1577 /*enough scan result available in cache to return to user space or
1578 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001579 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301580 {
1581 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1582 halStatus = sme_TriggerBatchScanResultInd(
1583 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1584 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1585 pAdapter);
1586 if ( eHAL_STATUS_SUCCESS == halStatus )
1587 {
1588 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1589 {
1590 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1591 rc = wait_for_completion_timeout(
1592 &pAdapter->hdd_get_batch_scan_req_var,
1593 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1594 if (0 == rc)
1595 {
1596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1597 "%s: Timeout waiting to fetch batch scan rsp from fw",
1598 __func__);
1599 return -EFAULT;
1600 }
1601 }
1602
1603 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001604 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301605 pDest += len;
1606 cur_len += len;
1607
1608 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1609 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1610 cur_len, rem_len);
1611 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1612
1613 count = 0;
1614 len = (len - pPrivData->used_len);
1615 pDest = (command + pPrivData->used_len);
1616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001617 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301618 while(count < len)
1619 {
1620 printk("%c", *(pDest + count));
1621 count++;
1622 }
1623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1624 "%s: copy %d data to user buffer", __func__, len);
1625 if (copy_to_user(pPrivData->buf, pDest, len))
1626 {
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "%s: failed to copy data to user buffer", __func__);
1629 return -EFAULT;
1630 }
1631 }
1632 else
1633 {
1634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1635 "sme_GetBatchScanScan returned failure halStatus %d",
1636 halStatus);
1637 return -EINVAL;
1638 }
1639 }
1640 else
1641 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301642 count = 0;
1643 len = (len - pPrivData->used_len);
1644 pDest = (command + pPrivData->used_len);
1645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001646 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301647 while(count < len)
1648 {
1649 printk("%c", *(pDest + count));
1650 count++;
1651 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 if (copy_to_user(pPrivData->buf, pDest, len))
1655 {
1656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: failed to copy data to user buffer", __func__);
1658 return -EFAULT;
1659 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301660 }
1661
1662 return 0;
1663} /*End of hdd_return_batch_scan_rsp_to_user*/
1664
Rajeev Kumar8b373292014-01-08 20:36:55 -08001665
1666/**---------------------------------------------------------------------------
1667
1668 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1669 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1670 WLS_BATCHING VERSION
1671 WLS_BATCHING SET
1672 WLS_BATCHING GET
1673 WLS_BATCHING STOP
1674
1675 \param - pAdapter Pointer to HDD adapter
1676 \param - pPrivdata Pointer to priv_data
1677 \param - command Pointer to command
1678
1679 \return - 0 for success -EFAULT for failure
1680
1681 --------------------------------------------------------------------------*/
1682
1683int hdd_handle_batch_scan_ioctl
1684(
1685 hdd_adapter_t *pAdapter,
1686 hdd_priv_data_t *pPrivdata,
1687 tANI_U8 *command
1688)
1689{
1690 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001691 hdd_context_t *pHddCtx;
1692
1693 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1694 ret = wlan_hdd_validate_context(pHddCtx);
1695 if (ret)
1696 {
1697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1698 "%s: HDD context is not valid!", __func__);
1699 goto exit;
1700 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001701
1702 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1703 {
1704 char extra[32];
1705 tANI_U8 len = 0;
1706 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1707
1708 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1709 {
1710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1711 "%s: Batch scan feature is not supported by FW", __func__);
1712 ret = -EINVAL;
1713 goto exit;
1714 }
1715
1716 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1717 version);
1718 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1719 {
1720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s: failed to copy data to user buffer", __func__);
1722 ret = -EFAULT;
1723 goto exit;
1724 }
1725 ret = HDD_BATCH_SCAN_VERSION;
1726 }
1727 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1728 {
1729 int status;
1730 tANI_U8 *value = (command + 16);
1731 eHalStatus halStatus;
1732 unsigned long rc;
1733 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1734 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1735
1736 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1737 {
1738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1739 "%s: Batch scan feature is not supported by FW", __func__);
1740 ret = -EINVAL;
1741 goto exit;
1742 }
1743
1744 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1745 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1746 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1747 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301750 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001751 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301752 hdd_device_modetoString(pAdapter->device_mode),
1753 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001754 ret = -EINVAL;
1755 goto exit;
1756 }
1757
1758 status = hdd_parse_set_batchscan_command(value, pReq);
1759 if (status)
1760 {
1761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1762 "Invalid WLS_BATCHING SET command");
1763 ret = -EINVAL;
1764 goto exit;
1765 }
1766
1767
1768 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1769 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1770 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1771 pAdapter);
1772
1773 if ( eHAL_STATUS_SUCCESS == halStatus )
1774 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301775 char extra[32];
1776 tANI_U8 len = 0;
1777 tANI_U8 mScan = 0;
1778
Rajeev Kumar8b373292014-01-08 20:36:55 -08001779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1780 "sme_SetBatchScanReq returned success halStatus %d",
1781 halStatus);
1782 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1783 {
1784 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1785 rc = wait_for_completion_timeout(
1786 &pAdapter->hdd_set_batch_scan_req_var,
1787 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1788 if (0 == rc)
1789 {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 "%s: Timeout waiting for set batch scan to complete",
1792 __func__);
1793 ret = -EINVAL;
1794 goto exit;
1795 }
1796 }
1797 if ( !pRsp->nScansToBatch )
1798 {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1800 "%s: Received set batch scan failure response from FW",
1801 __func__);
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805 /*As per the Batch Scan Framework API we should return the MIN of
1806 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301807 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001808
1809 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1810
1811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301813 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1814 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1815 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1816 {
1817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1818 "%s: failed to copy MSCAN value to user buffer", __func__);
1819 ret = -EFAULT;
1820 goto exit;
1821 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001822 }
1823 else
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "sme_SetBatchScanReq returned failure halStatus %d",
1827 halStatus);
1828 ret = -EINVAL;
1829 goto exit;
1830 }
1831 }
1832 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1833 {
1834 eHalStatus halStatus;
1835 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1836 pInd->param = 0;
1837
1838 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1839 {
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1841 "%s: Batch scan feature is not supported by FW", __func__);
1842 ret = -EINVAL;
1843 goto exit;
1844 }
1845
1846 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "Batch scan is not yet enabled batch scan state %d",
1850 pAdapter->batchScanState);
1851 ret = -EINVAL;
1852 goto exit;
1853 }
1854
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001855 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1856 hdd_deinit_batch_scan(pAdapter);
1857 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1858
Rajeev Kumar8b373292014-01-08 20:36:55 -08001859 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1860
1861 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1862 pAdapter->sessionId);
1863 if ( eHAL_STATUS_SUCCESS == halStatus )
1864 {
1865 ret = 0;
1866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1867 "sme_StopBatchScanInd returned success halStatus %d",
1868 halStatus);
1869 }
1870 else
1871 {
1872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1873 "sme_StopBatchScanInd returned failure halStatus %d",
1874 halStatus);
1875 ret = -EINVAL;
1876 goto exit;
1877 }
1878 }
1879 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1880 {
1881 tANI_U32 remain_len;
1882
1883 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1884 {
1885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1886 "%s: Batch scan feature is not supported by FW", __func__);
1887 ret = -EINVAL;
1888 goto exit;
1889 }
1890
1891 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "Batch scan is not yet enabled could not return results"
1895 "Batch Scan state %d",
1896 pAdapter->batchScanState);
1897 ret = -EINVAL;
1898 goto exit;
1899 }
1900
1901 pPrivdata->used_len = 16;
1902 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1903 if (remain_len < pPrivdata->total_len)
1904 {
1905 /*Clear previous batch scan response data if any*/
1906 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1907 }
1908 else
1909 {
1910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1911 "Invalid total length from user space can't fetch batch"
1912 " scan response total_len %d used_len %d remain len %d",
1913 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1914 ret = -EINVAL;
1915 goto exit;
1916 }
1917 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1918 }
1919
1920exit:
1921
1922 return ret;
1923}
1924
1925
Rajeev79dbe4c2013-10-05 11:03:42 +05301926#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1927
c_hpothu92367912014-05-01 15:18:17 +05301928static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1929{
1930 bcnMissRateContext_t *pCBCtx = (bcnMissRateContext_t *)data;
1931
1932 /* there is a race condition that exists between this callback
1933 function and the caller since the caller could time out either
1934 before or while this code is executing. we use a spinlock to
1935 serialize these actions */
1936 spin_lock(&hdd_context_lock);
1937
1938 gbcnMissRate = -1;
1939
1940 if(pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC || NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR,
1943 FL("invalid context magic: %08x data: %p"), pCBCtx->magic, data );
1944 spin_unlock(&hdd_context_lock);
1945 return ;
1946 }
1947
1948 if (VOS_STATUS_SUCCESS == status)
1949 {
1950 gbcnMissRate = bcnMissRate;
1951 }
1952 complete(&(pCBCtx->completion));
1953 spin_unlock(&hdd_context_lock);
1954
1955 return;
1956}
1957
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301958static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1959{
1960 int ret = 0;
1961
1962 if (!pCfg || !command || !extra || !len)
1963 {
1964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1965 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1966 ret = -EINVAL;
1967 return ret;
1968 }
1969
1970 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1971 {
1972 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1973 (int)pCfg->nActiveMaxChnTime);
1974 return ret;
1975 }
1976 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1977 {
1978 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1979 (int)pCfg->nActiveMinChnTime);
1980 return ret;
1981 }
1982 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1983 {
1984 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1985 (int)pCfg->nPassiveMaxChnTime);
1986 return ret;
1987 }
1988 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
1989 {
1990 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
1991 (int)pCfg->nPassiveMinChnTime);
1992 return ret;
1993 }
1994 else
1995 {
1996 ret = -EINVAL;
1997 }
1998
1999 return ret;
2000}
2001
2002static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2003{
2004 hdd_config_t *pCfg;
2005 tANI_U8 *value = command;
2006 int val = 0, ret = 0, temp = 0;
2007
2008 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini))
2009 {
2010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2011 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2012 ret = -EINVAL;
2013 return ret;
2014 }
2015
2016 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2017 {
2018 value = value + 24;
2019 temp = kstrtou32(value, 10, &val);
2020 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2021 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2022 {
2023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2024 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2025 ret = -EFAULT;
2026 return ret;
2027 }
2028 pCfg->nActiveMaxChnTime = val;
2029 }
2030 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2031 {
2032 value = value + 24;
2033 temp = kstrtou32(value, 10, &val);
2034 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2035 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2036 {
2037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2038 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2039 ret = -EFAULT;
2040 return ret;
2041 }
2042 pCfg->nActiveMinChnTime = val;
2043 }
2044 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2045 {
2046 value = value + 25;
2047 temp = kstrtou32(value, 10, &val);
2048 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2049 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2050 {
2051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2052 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2053 ret = -EFAULT;
2054 return ret;
2055 }
2056 pCfg->nPassiveMaxChnTime = val;
2057 }
2058 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2059 {
2060 value = value + 25;
2061 temp = kstrtou32(value, 10, &val);
2062 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2063 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2064 {
2065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2066 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2067 ret = -EFAULT;
2068 return ret;
2069 }
2070 pCfg->nPassiveMinChnTime = val;
2071 }
2072 else
2073 {
2074 ret = -EINVAL;
2075 }
2076
2077 return ret;
2078}
2079
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002080static int hdd_driver_command(hdd_adapter_t *pAdapter,
2081 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002082{
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 hdd_priv_data_t priv_data;
2084 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002085 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002086
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002087 /*
2088 * Note that valid pointers are provided by caller
2089 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002090
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002091 /* copy to local struct to avoid numerous changes to legacy code */
2092 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002093
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002094 if (priv_data.total_len <= 0 ||
2095 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002096 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002097 hddLog(VOS_TRACE_LEVEL_WARN,
2098 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2099 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002100 ret = -EINVAL;
2101 goto exit;
2102 }
2103
2104 /* Allocate +1 for '\0' */
2105 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 if (!command)
2107 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002108 hddLog(VOS_TRACE_LEVEL_ERROR,
2109 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002110 ret = -ENOMEM;
2111 goto exit;
2112 }
2113
2114 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2115 {
2116 ret = -EFAULT;
2117 goto exit;
2118 }
2119
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002120 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002121 command[priv_data.total_len] = '\0';
2122
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002123 /* at one time the following block of code was conditional. braces
2124 * have been retained to avoid re-indenting the legacy code
2125 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 {
2127 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2128
2129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002130 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002131
2132 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2133 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2135 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2136 pAdapter->sessionId, (unsigned)
2137 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2138 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2139 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2140 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002141 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2142 sizeof(tSirMacAddr)))
2143 {
2144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002145 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002146 ret = -EFAULT;
2147 }
2148 }
Amar Singhal0974e402013-02-12 14:27:46 -08002149 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 {
Amar Singhal0974e402013-02-12 14:27:46 -08002151 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002152
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002154
2155 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002156 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002158 "%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 -07002159 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002160 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302161 if(ret != 0)
2162 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002163 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002164 }
Kiet Lamf040f472013-11-20 21:15:23 +05302165 else if(strncmp(command, "SETWMMPS", 8) == 0)
2166 {
2167 tANI_U8 *ptr = command;
2168 ret = hdd_wmmps_helper(pAdapter, ptr);
2169 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002170 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2171 {
2172 char *country_code;
2173
2174 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002175
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002176 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002177 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002178#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302179 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002180#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002181 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2182 (void *)(tSmeChangeCountryCallback)
2183 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302184 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002185 if (eHAL_STATUS_SUCCESS == ret)
2186 {
2187 ret = wait_for_completion_interruptible_timeout(
2188 &pAdapter->change_country_code,
2189 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2190 if (0 >= ret)
2191 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302193 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002194 }
2195 }
2196 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002197 {
2198 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002199 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002200 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002201 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002202
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002203 }
2204 /*
2205 command should be a string having format
2206 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2207 */
Amar Singhal0974e402013-02-12 14:27:46 -08002208 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002209 {
Amar Singhal0974e402013-02-12 14:27:46 -08002210 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002211
2212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002213 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002214
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002215 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002216 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002217 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2218 {
2219 int suspend = 0;
2220 tANI_U8 *ptr = (tANI_U8*)command + 15;
2221
2222 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302223 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2224 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2225 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002226 hdd_set_wlan_suspend_mode(suspend);
2227 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002228#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2229 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2230 {
2231 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002232 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002233 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2234 eHalStatus status = eHAL_STATUS_SUCCESS;
2235
2236 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2237 value = value + 15;
2238
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002239 /* Convert the value from ascii to integer */
2240 ret = kstrtos8(value, 10, &rssi);
2241 if (ret < 0)
2242 {
2243 /* If the input value is greater than max value of datatype, then also
2244 kstrtou8 fails */
2245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2246 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002247 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002248 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2249 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2250 ret = -EINVAL;
2251 goto exit;
2252 }
2253
Srinivas Girigowdade697412013-02-14 16:31:48 -08002254 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002255
Srinivas Girigowdade697412013-02-14 16:31:48 -08002256 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2257 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2258 {
2259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2260 "Neighbor lookup threshold value %d is out of range"
2261 " (Min: %d Max: %d)", lookUpThreshold,
2262 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2263 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2264 ret = -EINVAL;
2265 goto exit;
2266 }
2267
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302268 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2269 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2270 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2272 "%s: Received Command to Set Roam trigger"
2273 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2274
2275 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2276 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2277 if (eHAL_STATUS_SUCCESS != status)
2278 {
2279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2280 "%s: Failed to set roam trigger, try again", __func__);
2281 ret = -EPERM;
2282 goto exit;
2283 }
2284
2285 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2286 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2287 }
2288 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2289 {
2290 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2291 int rssi = (-1) * lookUpThreshold;
2292 char extra[32];
2293 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302294 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2295 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2296 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002297 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002298 if (copy_to_user(priv_data.buf, &extra, len + 1))
2299 {
2300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2301 "%s: failed to copy data to user buffer", __func__);
2302 ret = -EFAULT;
2303 goto exit;
2304 }
2305 }
2306 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2307 {
2308 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002309 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002310 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002311
Srinivas Girigowdade697412013-02-14 16:31:48 -08002312 /* input refresh period is in terms of seconds */
2313 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2314 value = value + 18;
2315 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002316 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002317 if (ret < 0)
2318 {
2319 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002320 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002322 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002323 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002324 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2325 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002326 ret = -EINVAL;
2327 goto exit;
2328 }
2329
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002330 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2331 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002332 {
2333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002334 "Roam scan period value %d is out of range"
2335 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002336 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2337 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002338 ret = -EINVAL;
2339 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302340 }
2341 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2342 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2343 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002344 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002345
2346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2347 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002348 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002349
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002350 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2351 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002352 }
2353 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2354 {
2355 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2356 char extra[32];
2357 tANI_U8 len = 0;
2358
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302359 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2360 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2361 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002362 len = scnprintf(extra, sizeof(extra), "%s %d",
2363 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002364 /* Returned value is in units of seconds */
2365 if (copy_to_user(priv_data.buf, &extra, len + 1))
2366 {
2367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2368 "%s: failed to copy data to user buffer", __func__);
2369 ret = -EFAULT;
2370 goto exit;
2371 }
2372 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002373 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2374 {
2375 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002376 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002377 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002378
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002379 /* input refresh period is in terms of seconds */
2380 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2381 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002382
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002383 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002384 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002385 if (ret < 0)
2386 {
2387 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002388 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002390 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002391 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002392 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2393 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2394 ret = -EINVAL;
2395 goto exit;
2396 }
2397
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002398 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2399 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2400 {
2401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2402 "Neighbor scan results refresh period value %d is out of range"
2403 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2404 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2405 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2406 ret = -EINVAL;
2407 goto exit;
2408 }
2409 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2410
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2412 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002413 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002414
2415 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2416 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2417 }
2418 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2419 {
2420 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2421 char extra[32];
2422 tANI_U8 len = 0;
2423
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002424 len = scnprintf(extra, sizeof(extra), "%s %d",
2425 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002426 /* Returned value is in units of seconds */
2427 if (copy_to_user(priv_data.buf, &extra, len + 1))
2428 {
2429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: failed to copy data to user buffer", __func__);
2431 ret = -EFAULT;
2432 goto exit;
2433 }
2434 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002435#ifdef FEATURE_WLAN_LFR
2436 /* SETROAMMODE */
2437 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2438 {
2439 tANI_U8 *value = command;
2440 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2441
2442 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2443 value = value + SIZE_OF_SETROAMMODE + 1;
2444
2445 /* Convert the value from ascii to integer */
2446 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2447 if (ret < 0)
2448 {
2449 /* If the input value is greater than max value of datatype, then also
2450 kstrtou8 fails */
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2452 "%s: kstrtou8 failed range [%d - %d]", __func__,
2453 CFG_LFR_FEATURE_ENABLED_MIN,
2454 CFG_LFR_FEATURE_ENABLED_MAX);
2455 ret = -EINVAL;
2456 goto exit;
2457 }
2458 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2459 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2460 {
2461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2462 "Roam Mode value %d is out of range"
2463 " (Min: %d Max: %d)", roamMode,
2464 CFG_LFR_FEATURE_ENABLED_MIN,
2465 CFG_LFR_FEATURE_ENABLED_MAX);
2466 ret = -EINVAL;
2467 goto exit;
2468 }
2469
2470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2471 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2472 /*
2473 * Note that
2474 * SETROAMMODE 0 is to enable LFR while
2475 * SETROAMMODE 1 is to disable LFR, but
2476 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2477 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2478 */
2479 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2480 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2481 else
2482 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2483
2484 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2485 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2486 }
2487 /* GETROAMMODE */
2488 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2489 {
2490 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2491 char extra[32];
2492 tANI_U8 len = 0;
2493
2494 /*
2495 * roamMode value shall be inverted because the sementics is different.
2496 */
2497 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2498 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2499 else
2500 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2501
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002502 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002503 if (copy_to_user(priv_data.buf, &extra, len + 1))
2504 {
2505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2506 "%s: failed to copy data to user buffer", __func__);
2507 ret = -EFAULT;
2508 goto exit;
2509 }
2510 }
2511#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002512#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002513#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002514 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2515 {
2516 tANI_U8 *value = command;
2517 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2518
2519 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2520 value = value + 13;
2521 /* Convert the value from ascii to integer */
2522 ret = kstrtou8(value, 10, &roamRssiDiff);
2523 if (ret < 0)
2524 {
2525 /* If the input value is greater than max value of datatype, then also
2526 kstrtou8 fails */
2527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2528 "%s: kstrtou8 failed range [%d - %d]", __func__,
2529 CFG_ROAM_RSSI_DIFF_MIN,
2530 CFG_ROAM_RSSI_DIFF_MAX);
2531 ret = -EINVAL;
2532 goto exit;
2533 }
2534
2535 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2536 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2537 {
2538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2539 "Roam rssi diff value %d is out of range"
2540 " (Min: %d Max: %d)", roamRssiDiff,
2541 CFG_ROAM_RSSI_DIFF_MIN,
2542 CFG_ROAM_RSSI_DIFF_MAX);
2543 ret = -EINVAL;
2544 goto exit;
2545 }
2546
2547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2548 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2549
2550 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2551 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2552 }
2553 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2554 {
2555 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2556 char extra[32];
2557 tANI_U8 len = 0;
2558
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302559 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2560 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2561 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002562 len = scnprintf(extra, sizeof(extra), "%s %d",
2563 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002564 if (copy_to_user(priv_data.buf, &extra, len + 1))
2565 {
2566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2567 "%s: failed to copy data to user buffer", __func__);
2568 ret = -EFAULT;
2569 goto exit;
2570 }
2571 }
2572#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002573#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002574 else if (strncmp(command, "GETBAND", 7) == 0)
2575 {
2576 int band = -1;
2577 char extra[32];
2578 tANI_U8 len = 0;
2579 hdd_getBand_helper(pHddCtx, &band);
2580
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302581 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2582 TRACE_CODE_HDD_GETBAND_IOCTL,
2583 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002584 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002585 if (copy_to_user(priv_data.buf, &extra, len + 1))
2586 {
2587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2588 "%s: failed to copy data to user buffer", __func__);
2589 ret = -EFAULT;
2590 goto exit;
2591 }
2592 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002593 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2594 {
2595 tANI_U8 *value = command;
2596 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2597 tANI_U8 numChannels = 0;
2598 eHalStatus status = eHAL_STATUS_SUCCESS;
2599
2600 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2601 if (eHAL_STATUS_SUCCESS != status)
2602 {
2603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2604 "%s: Failed to parse channel list information", __func__);
2605 ret = -EINVAL;
2606 goto exit;
2607 }
2608
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2610 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2611 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002612 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2613 {
2614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2615 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2616 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2617 ret = -EINVAL;
2618 goto exit;
2619 }
2620 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2621 numChannels);
2622 if (eHAL_STATUS_SUCCESS != status)
2623 {
2624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2625 "%s: Failed to update channel list information", __func__);
2626 ret = -EINVAL;
2627 goto exit;
2628 }
2629 }
2630 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2631 {
2632 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2633 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002634 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002635 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002636 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002637
2638 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2639 ChannelList, &numChannels ))
2640 {
2641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2642 "%s: failed to get roam scan channel list", __func__);
2643 ret = -EFAULT;
2644 goto exit;
2645 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302646 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2647 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2648 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002649 /* output channel list is of the format
2650 [Number of roam scan channels][Channel1][Channel2]... */
2651 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002652 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002653 for (j = 0; (j < numChannels); j++)
2654 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002655 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2656 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002657 }
2658
2659 if (copy_to_user(priv_data.buf, &extra, len + 1))
2660 {
2661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2662 "%s: failed to copy data to user buffer", __func__);
2663 ret = -EFAULT;
2664 goto exit;
2665 }
2666 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002667 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2668 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002669 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002670 char extra[32];
2671 tANI_U8 len = 0;
2672
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002673 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002674 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002675 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002676 hdd_is_okc_mode_enabled(pHddCtx) &&
2677 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2678 {
2679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002680 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002681 " hence this operation is not permitted!", __func__);
2682 ret = -EPERM;
2683 goto exit;
2684 }
2685
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002686 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002687 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002688 if (copy_to_user(priv_data.buf, &extra, len + 1))
2689 {
2690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2691 "%s: failed to copy data to user buffer", __func__);
2692 ret = -EFAULT;
2693 goto exit;
2694 }
2695 }
2696 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2697 {
2698 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2699 char extra[32];
2700 tANI_U8 len = 0;
2701
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002702 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002703 then this operation is not permitted (return FAILURE) */
2704 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002705 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002706 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2707 {
2708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002709 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002710 " hence this operation is not permitted!", __func__);
2711 ret = -EPERM;
2712 goto exit;
2713 }
2714
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002715 len = scnprintf(extra, sizeof(extra), "%s %d",
2716 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002717 if (copy_to_user(priv_data.buf, &extra, len + 1))
2718 {
2719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2720 "%s: failed to copy data to user buffer", __func__);
2721 ret = -EFAULT;
2722 goto exit;
2723 }
2724 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002725 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002726 {
2727 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2728 char extra[32];
2729 tANI_U8 len = 0;
2730
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002731 len = scnprintf(extra, sizeof(extra), "%s %d",
2732 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002733 if (copy_to_user(priv_data.buf, &extra, len + 1))
2734 {
2735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2736 "%s: failed to copy data to user buffer", __func__);
2737 ret = -EFAULT;
2738 goto exit;
2739 }
2740 }
2741 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2742 {
2743 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2744 char extra[32];
2745 tANI_U8 len = 0;
2746
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002747 len = scnprintf(extra, sizeof(extra), "%s %d",
2748 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002749 if (copy_to_user(priv_data.buf, &extra, len + 1))
2750 {
2751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2752 "%s: failed to copy data to user buffer", __func__);
2753 ret = -EFAULT;
2754 goto exit;
2755 }
2756 }
2757 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2758 {
2759 tANI_U8 *value = command;
2760 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2761
2762 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2763 value = value + 26;
2764 /* Convert the value from ascii to integer */
2765 ret = kstrtou8(value, 10, &minTime);
2766 if (ret < 0)
2767 {
2768 /* If the input value is greater than max value of datatype, then also
2769 kstrtou8 fails */
2770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2771 "%s: kstrtou8 failed range [%d - %d]", __func__,
2772 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2773 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2774 ret = -EINVAL;
2775 goto exit;
2776 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002777 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2778 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "scan min channel time value %d is out of range"
2782 " (Min: %d Max: %d)", minTime,
2783 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2784 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2785 ret = -EINVAL;
2786 goto exit;
2787 }
2788
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302789 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2790 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2791 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2793 "%s: Received Command to change channel min time = %d", __func__, minTime);
2794
2795 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2796 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2797 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002798 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2799 {
2800 tANI_U8 *value = command;
2801 tANI_U8 channel = 0;
2802 tANI_U8 dwellTime = 0;
2803 tANI_U8 bufLen = 0;
2804 tANI_U8 *buf = NULL;
2805 tSirMacAddr targetApBssid;
2806 eHalStatus status = eHAL_STATUS_SUCCESS;
2807 struct ieee80211_channel chan;
2808 tANI_U8 finalLen = 0;
2809 tANI_U8 *finalBuf = NULL;
2810 tANI_U8 temp = 0;
2811 u64 cookie;
2812 hdd_station_ctx_t *pHddStaCtx = NULL;
2813 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2814
2815 /* if not associated, no need to send action frame */
2816 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2817 {
2818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2819 ret = -EINVAL;
2820 goto exit;
2821 }
2822
2823 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2824 &dwellTime, &buf, &bufLen);
2825 if (eHAL_STATUS_SUCCESS != status)
2826 {
2827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: Failed to parse send action frame data", __func__);
2829 ret = -EINVAL;
2830 goto exit;
2831 }
2832
2833 /* if the target bssid is different from currently associated AP,
2834 then no need to send action frame */
2835 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2836 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2837 {
2838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2839 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002840 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002841 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002842 goto exit;
2843 }
2844
2845 /* if the channel number is different from operating channel then
2846 no need to send action frame */
2847 if (channel != pHddStaCtx->conn_info.operationChannel)
2848 {
2849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2850 "%s: channel(%d) is different from operating channel(%d)",
2851 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2852 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002853 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002854 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002855 goto exit;
2856 }
2857 chan.center_freq = sme_ChnToFreq(channel);
2858
2859 finalLen = bufLen + 24;
2860 finalBuf = vos_mem_malloc(finalLen);
2861 if (NULL == finalBuf)
2862 {
2863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2864 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002865 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002866 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002867 goto exit;
2868 }
2869 vos_mem_zero(finalBuf, finalLen);
2870
2871 /* Fill subtype */
2872 temp = SIR_MAC_MGMT_ACTION << 4;
2873 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2874
2875 /* Fill type */
2876 temp = SIR_MAC_MGMT_FRAME;
2877 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2878
2879 /* Fill destination address (bssid of the AP) */
2880 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2881
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002882 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002883 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2884
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002885 /* Fill BSSID (AP mac address) */
2886 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002887
2888 /* Fill received buffer from 24th address */
2889 vos_mem_copy(finalBuf + 24, buf, bufLen);
2890
Jeff Johnson11c33152013-04-16 17:52:40 -07002891 /* done with the parsed buffer */
2892 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002893 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002894
DARAM SUDHA39eede62014-02-12 11:16:40 +05302895 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002896#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2897 &(pAdapter->wdev),
2898#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002899 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002900#endif
2901 &chan, 0,
2902#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2903 NL80211_CHAN_HT20, 1,
2904#endif
2905 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002906 1, &cookie );
2907 vos_mem_free(finalBuf);
2908 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002909 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2910 {
2911 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2912 char extra[32];
2913 tANI_U8 len = 0;
2914
2915 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002916 len = scnprintf(extra, sizeof(extra), "%s %d",
2917 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302918 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2919 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2920 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 if (copy_to_user(priv_data.buf, &extra, len + 1))
2922 {
2923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2924 "%s: failed to copy data to user buffer", __func__);
2925 ret = -EFAULT;
2926 goto exit;
2927 }
2928 }
2929 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2930 {
2931 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002932 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002933
2934 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2935 value = value + 19;
2936 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002937 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002938 if (ret < 0)
2939 {
2940 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002941 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002943 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002944 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2945 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2946 ret = -EINVAL;
2947 goto exit;
2948 }
2949
2950 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2951 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2952 {
2953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2954 "lfr mode value %d is out of range"
2955 " (Min: %d Max: %d)", maxTime,
2956 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2957 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2958 ret = -EINVAL;
2959 goto exit;
2960 }
2961
2962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2963 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2964
2965 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2966 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2967 }
2968 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2969 {
2970 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2971 char extra[32];
2972 tANI_U8 len = 0;
2973
2974 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002975 len = scnprintf(extra, sizeof(extra), "%s %d",
2976 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002977 if (copy_to_user(priv_data.buf, &extra, len + 1))
2978 {
2979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2980 "%s: failed to copy data to user buffer", __func__);
2981 ret = -EFAULT;
2982 goto exit;
2983 }
2984 }
2985 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2986 {
2987 tANI_U8 *value = command;
2988 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2989
2990 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2991 value = value + 16;
2992 /* Convert the value from ascii to integer */
2993 ret = kstrtou16(value, 10, &val);
2994 if (ret < 0)
2995 {
2996 /* If the input value is greater than max value of datatype, then also
2997 kstrtou16 fails */
2998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "%s: kstrtou16 failed range [%d - %d]", __func__,
3000 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3001 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3002 ret = -EINVAL;
3003 goto exit;
3004 }
3005
3006 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3007 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3008 {
3009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3010 "scan home time value %d is out of range"
3011 " (Min: %d Max: %d)", val,
3012 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3013 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3014 ret = -EINVAL;
3015 goto exit;
3016 }
3017
3018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3019 "%s: Received Command to change scan home time = %d", __func__, val);
3020
3021 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3022 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3023 }
3024 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3025 {
3026 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3027 char extra[32];
3028 tANI_U8 len = 0;
3029
3030 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003031 len = scnprintf(extra, sizeof(extra), "%s %d",
3032 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003033 if (copy_to_user(priv_data.buf, &extra, len + 1))
3034 {
3035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3036 "%s: failed to copy data to user buffer", __func__);
3037 ret = -EFAULT;
3038 goto exit;
3039 }
3040 }
3041 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3042 {
3043 tANI_U8 *value = command;
3044 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3045
3046 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3047 value = value + 17;
3048 /* Convert the value from ascii to integer */
3049 ret = kstrtou8(value, 10, &val);
3050 if (ret < 0)
3051 {
3052 /* If the input value is greater than max value of datatype, then also
3053 kstrtou8 fails */
3054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3055 "%s: kstrtou8 failed range [%d - %d]", __func__,
3056 CFG_ROAM_INTRA_BAND_MIN,
3057 CFG_ROAM_INTRA_BAND_MAX);
3058 ret = -EINVAL;
3059 goto exit;
3060 }
3061
3062 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3063 (val > CFG_ROAM_INTRA_BAND_MAX))
3064 {
3065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3066 "intra band mode value %d is out of range"
3067 " (Min: %d Max: %d)", val,
3068 CFG_ROAM_INTRA_BAND_MIN,
3069 CFG_ROAM_INTRA_BAND_MAX);
3070 ret = -EINVAL;
3071 goto exit;
3072 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3074 "%s: Received Command to change intra band = %d", __func__, val);
3075
3076 pHddCtx->cfg_ini->nRoamIntraBand = val;
3077 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3078 }
3079 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3080 {
3081 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3082 char extra[32];
3083 tANI_U8 len = 0;
3084
3085 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003086 len = scnprintf(extra, sizeof(extra), "%s %d",
3087 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003088 if (copy_to_user(priv_data.buf, &extra, len + 1))
3089 {
3090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3091 "%s: failed to copy data to user buffer", __func__);
3092 ret = -EFAULT;
3093 goto exit;
3094 }
3095 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003096 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3097 {
3098 tANI_U8 *value = command;
3099 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3100
3101 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3102 value = value + 15;
3103 /* Convert the value from ascii to integer */
3104 ret = kstrtou8(value, 10, &nProbes);
3105 if (ret < 0)
3106 {
3107 /* If the input value is greater than max value of datatype, then also
3108 kstrtou8 fails */
3109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3110 "%s: kstrtou8 failed range [%d - %d]", __func__,
3111 CFG_ROAM_SCAN_N_PROBES_MIN,
3112 CFG_ROAM_SCAN_N_PROBES_MAX);
3113 ret = -EINVAL;
3114 goto exit;
3115 }
3116
3117 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3118 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3119 {
3120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3121 "NProbes value %d is out of range"
3122 " (Min: %d Max: %d)", nProbes,
3123 CFG_ROAM_SCAN_N_PROBES_MIN,
3124 CFG_ROAM_SCAN_N_PROBES_MAX);
3125 ret = -EINVAL;
3126 goto exit;
3127 }
3128
3129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3130 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3131
3132 pHddCtx->cfg_ini->nProbes = nProbes;
3133 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3134 }
3135 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3136 {
3137 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3138 char extra[32];
3139 tANI_U8 len = 0;
3140
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003141 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003142 if (copy_to_user(priv_data.buf, &extra, len + 1))
3143 {
3144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3145 "%s: failed to copy data to user buffer", __func__);
3146 ret = -EFAULT;
3147 goto exit;
3148 }
3149 }
3150 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3151 {
3152 tANI_U8 *value = command;
3153 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3154
3155 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3156 /* input value is in units of msec */
3157 value = value + 20;
3158 /* Convert the value from ascii to integer */
3159 ret = kstrtou16(value, 10, &homeAwayTime);
3160 if (ret < 0)
3161 {
3162 /* If the input value is greater than max value of datatype, then also
3163 kstrtou8 fails */
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "%s: kstrtou8 failed range [%d - %d]", __func__,
3166 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3167 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3168 ret = -EINVAL;
3169 goto exit;
3170 }
3171
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003172 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3173 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3174 {
3175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3176 "homeAwayTime value %d is out of range"
3177 " (Min: %d Max: %d)", homeAwayTime,
3178 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3179 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3180 ret = -EINVAL;
3181 goto exit;
3182 }
3183
3184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3185 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003186 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3187 {
3188 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3189 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3190 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003191 }
3192 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3193 {
3194 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3195 char extra[32];
3196 tANI_U8 len = 0;
3197
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003198 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003199 if (copy_to_user(priv_data.buf, &extra, len + 1))
3200 {
3201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3202 "%s: failed to copy data to user buffer", __func__);
3203 ret = -EFAULT;
3204 goto exit;
3205 }
3206 }
3207 else if (strncmp(command, "REASSOC", 7) == 0)
3208 {
3209 tANI_U8 *value = command;
3210 tANI_U8 channel = 0;
3211 tSirMacAddr targetApBssid;
3212 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003213#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3214 tCsrHandoffRequest handoffInfo;
3215#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003216 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003217 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3218
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003219 /* if not associated, no need to proceed with reassoc */
3220 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3221 {
3222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3223 ret = -EINVAL;
3224 goto exit;
3225 }
3226
3227 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3228 if (eHAL_STATUS_SUCCESS != status)
3229 {
3230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3231 "%s: Failed to parse reassoc command data", __func__);
3232 ret = -EINVAL;
3233 goto exit;
3234 }
3235
3236 /* if the target bssid is same as currently associated AP,
3237 then no need to proceed with reassoc */
3238 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3239 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3240 {
3241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 /* Check channel number is a valid channel number */
3247 if(VOS_STATUS_SUCCESS !=
3248 wlan_hdd_validate_operation_channel(pAdapter, channel))
3249 {
3250 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003251 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003252 return -EINVAL;
3253 }
3254
3255 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003256#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3257 handoffInfo.channel = channel;
3258 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3259 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3260#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003261 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003262 else if (strncmp(command, "SETWESMODE", 10) == 0)
3263 {
3264 tANI_U8 *value = command;
3265 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3266
3267 /* Move pointer to ahead of SETWESMODE<delimiter> */
3268 value = value + 11;
3269 /* Convert the value from ascii to integer */
3270 ret = kstrtou8(value, 10, &wesMode);
3271 if (ret < 0)
3272 {
3273 /* If the input value is greater than max value of datatype, then also
3274 kstrtou8 fails */
3275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3276 "%s: kstrtou8 failed range [%d - %d]", __func__,
3277 CFG_ENABLE_WES_MODE_NAME_MIN,
3278 CFG_ENABLE_WES_MODE_NAME_MAX);
3279 ret = -EINVAL;
3280 goto exit;
3281 }
3282
3283 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3284 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3285 {
3286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3287 "WES Mode value %d is out of range"
3288 " (Min: %d Max: %d)", wesMode,
3289 CFG_ENABLE_WES_MODE_NAME_MIN,
3290 CFG_ENABLE_WES_MODE_NAME_MAX);
3291 ret = -EINVAL;
3292 goto exit;
3293 }
3294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3295 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3296
3297 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3298 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3299 }
3300 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3301 {
3302 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3303 char extra[32];
3304 tANI_U8 len = 0;
3305
Arif Hussain826d9412013-11-12 16:44:54 -08003306 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003307 if (copy_to_user(priv_data.buf, &extra, len + 1))
3308 {
3309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3310 "%s: failed to copy data to user buffer", __func__);
3311 ret = -EFAULT;
3312 goto exit;
3313 }
3314 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003315#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003316#ifdef FEATURE_WLAN_LFR
3317 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3318 {
3319 tANI_U8 *value = command;
3320 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3321
3322 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3323 value = value + 12;
3324 /* Convert the value from ascii to integer */
3325 ret = kstrtou8(value, 10, &lfrMode);
3326 if (ret < 0)
3327 {
3328 /* If the input value is greater than max value of datatype, then also
3329 kstrtou8 fails */
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "%s: kstrtou8 failed range [%d - %d]", __func__,
3332 CFG_LFR_FEATURE_ENABLED_MIN,
3333 CFG_LFR_FEATURE_ENABLED_MAX);
3334 ret = -EINVAL;
3335 goto exit;
3336 }
3337
3338 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3339 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "lfr mode value %d is out of range"
3343 " (Min: %d Max: %d)", lfrMode,
3344 CFG_LFR_FEATURE_ENABLED_MIN,
3345 CFG_LFR_FEATURE_ENABLED_MAX);
3346 ret = -EINVAL;
3347 goto exit;
3348 }
3349
3350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3351 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3352
3353 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3354 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3355 }
3356#endif
3357#ifdef WLAN_FEATURE_VOWIFI_11R
3358 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3359 {
3360 tANI_U8 *value = command;
3361 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3362
3363 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3364 value = value + 18;
3365 /* Convert the value from ascii to integer */
3366 ret = kstrtou8(value, 10, &ft);
3367 if (ret < 0)
3368 {
3369 /* If the input value is greater than max value of datatype, then also
3370 kstrtou8 fails */
3371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3372 "%s: kstrtou8 failed range [%d - %d]", __func__,
3373 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3374 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3375 ret = -EINVAL;
3376 goto exit;
3377 }
3378
3379 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3380 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3381 {
3382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3383 "ft mode value %d is out of range"
3384 " (Min: %d Max: %d)", ft,
3385 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3386 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3387 ret = -EINVAL;
3388 goto exit;
3389 }
3390
3391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3392 "%s: Received Command to change ft mode = %d", __func__, ft);
3393
3394 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3395 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3396 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303397
3398 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3399 {
3400 tANI_U8 *value = command;
3401 tSirMacAddr targetApBssid;
3402 tANI_U8 trigger = 0;
3403 eHalStatus status = eHAL_STATUS_SUCCESS;
3404 hdd_station_ctx_t *pHddStaCtx = NULL;
3405 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3406
3407 /* if not associated, no need to proceed with reassoc */
3408 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3409 {
3410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3411 ret = -EINVAL;
3412 goto exit;
3413 }
3414
3415 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3416 if (eHAL_STATUS_SUCCESS != status)
3417 {
3418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3419 "%s: Failed to parse reassoc command data", __func__);
3420 ret = -EINVAL;
3421 goto exit;
3422 }
3423
3424 /* if the target bssid is same as currently associated AP,
3425 then no need to proceed with reassoc */
3426 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3427 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3428 {
3429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3430 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3431 __func__);
3432 ret = -EINVAL;
3433 goto exit;
3434 }
3435
3436 /* Proceed with scan/roam */
3437 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3438 &targetApBssid[0],
3439 (tSmeFastRoamTrigger)(trigger));
3440 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003441#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003442#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003443 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3444 {
3445 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003446 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003447
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003448 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003449 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003450 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003451 hdd_is_okc_mode_enabled(pHddCtx) &&
3452 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3453 {
3454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003455 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003456 " hence this operation is not permitted!", __func__);
3457 ret = -EPERM;
3458 goto exit;
3459 }
3460
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003461 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3462 value = value + 11;
3463 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003464 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003465 if (ret < 0)
3466 {
3467 /* If the input value is greater than max value of datatype, then also
3468 kstrtou8 fails */
3469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3470 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003471 CFG_ESE_FEATURE_ENABLED_MIN,
3472 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003473 ret = -EINVAL;
3474 goto exit;
3475 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003476 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3477 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003478 {
3479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003480 "Ese mode value %d is out of range"
3481 " (Min: %d Max: %d)", eseMode,
3482 CFG_ESE_FEATURE_ENABLED_MIN,
3483 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003484 ret = -EINVAL;
3485 goto exit;
3486 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003488 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003489
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003490 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3491 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003492 }
3493#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003494 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3495 {
3496 tANI_U8 *value = command;
3497 tANI_BOOLEAN roamScanControl = 0;
3498
3499 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3500 value = value + 19;
3501 /* Convert the value from ascii to integer */
3502 ret = kstrtou8(value, 10, &roamScanControl);
3503 if (ret < 0)
3504 {
3505 /* If the input value is greater than max value of datatype, then also
3506 kstrtou8 fails */
3507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3508 "%s: kstrtou8 failed ", __func__);
3509 ret = -EINVAL;
3510 goto exit;
3511 }
3512
3513 if (0 != roamScanControl)
3514 {
3515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3516 "roam scan control invalid value = %d",
3517 roamScanControl);
3518 ret = -EINVAL;
3519 goto exit;
3520 }
3521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3522 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3523
3524 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3525 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003526#ifdef FEATURE_WLAN_OKC
3527 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3528 {
3529 tANI_U8 *value = command;
3530 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3531
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003532 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003533 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003534 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003535 hdd_is_okc_mode_enabled(pHddCtx) &&
3536 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3537 {
3538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003539 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003540 " hence this operation is not permitted!", __func__);
3541 ret = -EPERM;
3542 goto exit;
3543 }
3544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003545 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3546 value = value + 11;
3547 /* Convert the value from ascii to integer */
3548 ret = kstrtou8(value, 10, &okcMode);
3549 if (ret < 0)
3550 {
3551 /* If the input value is greater than max value of datatype, then also
3552 kstrtou8 fails */
3553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3554 "%s: kstrtou8 failed range [%d - %d]", __func__,
3555 CFG_OKC_FEATURE_ENABLED_MIN,
3556 CFG_OKC_FEATURE_ENABLED_MAX);
3557 ret = -EINVAL;
3558 goto exit;
3559 }
3560
3561 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3562 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3563 {
3564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3565 "Okc mode value %d is out of range"
3566 " (Min: %d Max: %d)", okcMode,
3567 CFG_OKC_FEATURE_ENABLED_MIN,
3568 CFG_OKC_FEATURE_ENABLED_MAX);
3569 ret = -EINVAL;
3570 goto exit;
3571 }
3572
3573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3574 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3575
3576 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3577 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003578#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003579 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3580 {
3581 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3582 char extra[32];
3583 tANI_U8 len = 0;
3584
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003585 len = scnprintf(extra, sizeof(extra), "%s %d",
3586 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003587 if (copy_to_user(priv_data.buf, &extra, len + 1))
3588 {
3589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3590 "%s: failed to copy data to user buffer", __func__);
3591 ret = -EFAULT;
3592 goto exit;
3593 }
3594 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303595#ifdef WLAN_FEATURE_PACKET_FILTERING
3596 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3597 {
3598 tANI_U8 filterType = 0;
3599 tANI_U8 *value = command;
3600
3601 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3602 value = value + 22;
3603
3604 /* Convert the value from ascii to integer */
3605 ret = kstrtou8(value, 10, &filterType);
3606 if (ret < 0)
3607 {
3608 /* If the input value is greater than max value of datatype,
3609 * then also kstrtou8 fails
3610 */
3611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3612 "%s: kstrtou8 failed range ", __func__);
3613 ret = -EINVAL;
3614 goto exit;
3615 }
3616
3617 if (filterType != 0 && filterType != 1)
3618 {
3619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3620 "%s: Accepted Values are 0 and 1 ", __func__);
3621 ret = -EINVAL;
3622 goto exit;
3623 }
3624 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3625 pAdapter->sessionId);
3626 }
3627#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303628 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3629 {
Kiet Lam94fd2922014-06-18 19:12:43 -07003630 char *bcMode;
3631 bcMode = command + 11;
3632 if ('1' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303633 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003635 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303636
3637 pHddCtx->btCoexModeSet = TRUE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303638 }
Kiet Lam94fd2922014-06-18 19:12:43 -07003639 else if ('2' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303640 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003642 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303643
3644 pHddCtx->btCoexModeSet = FALSE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303645 }
3646 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003647 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3648 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3650 FL("making default scan to ACTIVE"));
3651 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003652 }
3653 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3654 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3656 FL("making default scan to PASSIVE"));
3657 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003658 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303659 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3660 {
3661 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3662 char extra[32];
3663 tANI_U8 len = 0;
3664
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303665 memset(extra, 0, sizeof(extra));
3666 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3667 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303668 {
3669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3670 "%s: failed to copy data to user buffer", __func__);
3671 ret = -EFAULT;
3672 goto exit;
3673 }
3674 ret = len;
3675 }
3676 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3677 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303678 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303679 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003680 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3681 {
3682 tANI_U8 filterType = 0;
3683 tANI_U8 *value;
3684 value = command + 9;
3685
3686 /* Convert the value from ascii to integer */
3687 ret = kstrtou8(value, 10, &filterType);
3688 if (ret < 0)
3689 {
3690 /* If the input value is greater than max value of datatype,
3691 * then also kstrtou8 fails
3692 */
3693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3694 "%s: kstrtou8 failed range ", __func__);
3695 ret = -EINVAL;
3696 goto exit;
3697 }
3698 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3699 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3700 {
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3702 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3703 " 2-Sink ", __func__);
3704 ret = -EINVAL;
3705 goto exit;
3706 }
3707 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3708 pHddCtx->drvr_miracast = filterType;
3709 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3710 }
Leo Chang614d2072013-08-22 14:59:44 -07003711 else if (strncmp(command, "SETMCRATE", 9) == 0)
3712 {
Leo Chang614d2072013-08-22 14:59:44 -07003713 tANI_U8 *value = command;
3714 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003715 tSirRateUpdateInd *rateUpdate;
3716 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003717
3718 /* Only valid for SAP mode */
3719 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3720 {
3721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3722 "%s: SAP mode is not running", __func__);
3723 ret = -EFAULT;
3724 goto exit;
3725 }
3726
3727 /* Move pointer to ahead of SETMCRATE<delimiter> */
3728 /* input value is in units of hundred kbps */
3729 value = value + 10;
3730 /* Convert the value from ascii to integer, decimal base */
3731 ret = kstrtouint(value, 10, &targetRate);
3732
Leo Chang1f98cbd2013-10-17 15:03:52 -07003733 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3734 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003735 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003736 hddLog(VOS_TRACE_LEVEL_ERROR,
3737 "%s: SETMCRATE indication alloc fail", __func__);
3738 ret = -EFAULT;
3739 goto exit;
3740 }
3741 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3742
3743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3744 "MC Target rate %d", targetRate);
3745 /* Ignore unicast */
3746 rateUpdate->ucastDataRate = -1;
3747 rateUpdate->mcastDataRate24GHz = targetRate;
3748 rateUpdate->mcastDataRate5GHz = targetRate;
3749 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3750 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3751 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3752 if (eHAL_STATUS_SUCCESS != status)
3753 {
3754 hddLog(VOS_TRACE_LEVEL_ERROR,
3755 "%s: SET_MC_RATE failed", __func__);
3756 vos_mem_free(rateUpdate);
3757 ret = -EFAULT;
3758 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003759 }
3760 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303761#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003762 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303763 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003764 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303765 }
3766#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003767#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003768 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3769 {
3770 tANI_U8 *value = command;
3771 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3772 tANI_U8 numChannels = 0;
3773 eHalStatus status = eHAL_STATUS_SUCCESS;
3774
3775 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3776 if (eHAL_STATUS_SUCCESS != status)
3777 {
3778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3779 "%s: Failed to parse channel list information", __func__);
3780 ret = -EINVAL;
3781 goto exit;
3782 }
3783
3784 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3785 {
3786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3787 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3788 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3789 ret = -EINVAL;
3790 goto exit;
3791 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003792 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003793 ChannelList,
3794 numChannels);
3795 if (eHAL_STATUS_SUCCESS != status)
3796 {
3797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3798 "%s: Failed to update channel list information", __func__);
3799 ret = -EINVAL;
3800 goto exit;
3801 }
3802 }
3803 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3804 {
3805 tANI_U8 *value = command;
3806 char extra[128] = {0};
3807 int len = 0;
3808 tANI_U8 tid = 0;
3809 hdd_station_ctx_t *pHddStaCtx = NULL;
3810 tAniTrafStrmMetrics tsmMetrics;
3811 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3812
3813 /* if not associated, return error */
3814 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3815 {
3816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3817 ret = -EINVAL;
3818 goto exit;
3819 }
3820
3821 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3822 value = value + 12;
3823 /* Convert the value from ascii to integer */
3824 ret = kstrtou8(value, 10, &tid);
3825 if (ret < 0)
3826 {
3827 /* If the input value is greater than max value of datatype, then also
3828 kstrtou8 fails */
3829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3830 "%s: kstrtou8 failed range [%d - %d]", __func__,
3831 TID_MIN_VALUE,
3832 TID_MAX_VALUE);
3833 ret = -EINVAL;
3834 goto exit;
3835 }
3836
3837 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3838 {
3839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3840 "tid value %d is out of range"
3841 " (Min: %d Max: %d)", tid,
3842 TID_MIN_VALUE,
3843 TID_MAX_VALUE);
3844 ret = -EINVAL;
3845 goto exit;
3846 }
3847
3848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3849 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3850
3851 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "%s: failed to get tsm stats", __func__);
3855 ret = -EFAULT;
3856 goto exit;
3857 }
3858
3859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3860 "UplinkPktQueueDly(%d)\n"
3861 "UplinkPktQueueDlyHist[0](%d)\n"
3862 "UplinkPktQueueDlyHist[1](%d)\n"
3863 "UplinkPktQueueDlyHist[2](%d)\n"
3864 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303865 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003866 "UplinkPktLoss(%d)\n"
3867 "UplinkPktCount(%d)\n"
3868 "RoamingCount(%d)\n"
3869 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3870 tsmMetrics.UplinkPktQueueDlyHist[0],
3871 tsmMetrics.UplinkPktQueueDlyHist[1],
3872 tsmMetrics.UplinkPktQueueDlyHist[2],
3873 tsmMetrics.UplinkPktQueueDlyHist[3],
3874 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3875 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3876
3877 /* Output TSM stats is of the format
3878 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3879 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003880 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003881 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3882 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3883 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3884 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3885 tsmMetrics.RoamingDly);
3886
3887 if (copy_to_user(priv_data.buf, &extra, len + 1))
3888 {
3889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3890 "%s: failed to copy data to user buffer", __func__);
3891 ret = -EFAULT;
3892 goto exit;
3893 }
3894 }
3895 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3896 {
3897 tANI_U8 *value = command;
3898 tANI_U8 *cckmIe = NULL;
3899 tANI_U8 cckmIeLen = 0;
3900 eHalStatus status = eHAL_STATUS_SUCCESS;
3901
3902 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3903 if (eHAL_STATUS_SUCCESS != status)
3904 {
3905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3906 "%s: Failed to parse cckm ie data", __func__);
3907 ret = -EINVAL;
3908 goto exit;
3909 }
3910
3911 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3912 {
3913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 "%s: CCKM Ie input length is more than max[%d]", __func__,
3915 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003916 vos_mem_free(cckmIe);
3917 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003918 ret = -EINVAL;
3919 goto exit;
3920 }
3921 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003922 vos_mem_free(cckmIe);
3923 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003924 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003925 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3926 {
3927 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003928 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003929 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003930
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003931 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003932 if (eHAL_STATUS_SUCCESS != status)
3933 {
3934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003935 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003936 ret = -EINVAL;
3937 goto exit;
3938 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003939 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3940 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3941 hdd_indicateEseBcnReportNoResults (pAdapter,
3942 eseBcnReq.bcnReq[0].measurementToken,
3943 0x02, //BIT(1) set for measurement done
3944 0); // no BSS
3945 goto exit;
3946 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003947
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003948 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3949 if (eHAL_STATUS_SUCCESS != status)
3950 {
3951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3952 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3953 ret = -EINVAL;
3954 goto exit;
3955 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003956 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003957#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303958 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3959 {
3960 eHalStatus status;
3961 char buf[32], len;
3962 long waitRet;
3963 bcnMissRateContext_t getBcnMissRateCtx;
3964
3965 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3966
3967 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3968 {
3969 hddLog(VOS_TRACE_LEVEL_WARN,
3970 FL("GETBCNMISSRATE: STA is not in connected state"));
3971 ret = -1;
3972 goto exit;
3973 }
3974
3975 init_completion(&(getBcnMissRateCtx.completion));
3976 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
3977
3978 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
3979 pAdapter->sessionId,
3980 (void *)getBcnMissRateCB,
3981 (void *)(&getBcnMissRateCtx));
3982 if( eHAL_STATUS_SUCCESS != status)
3983 {
3984 hddLog(VOS_TRACE_LEVEL_INFO,
3985 FL("GETBCNMISSRATE: fail to post WDA cmd"));
3986 ret = -EINVAL;
3987 goto exit;
3988 }
3989
3990 waitRet = wait_for_completion_interruptible_timeout
3991 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
3992 if(waitRet <= 0)
3993 {
3994 hddLog(VOS_TRACE_LEVEL_ERROR,
3995 FL("failed to wait on bcnMissRateComp %d"), ret);
3996
3997 //Make magic number to zero so that callback is not called.
3998 spin_lock(&hdd_context_lock);
3999 getBcnMissRateCtx.magic = 0x0;
4000 spin_unlock(&hdd_context_lock);
4001 ret = -EINVAL;
4002 goto exit;
4003 }
4004
4005 hddLog(VOS_TRACE_LEVEL_INFO,
4006 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4007
4008 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4009 if (copy_to_user(priv_data.buf, &buf, len + 1))
4010 {
4011 hddLog(VOS_TRACE_LEVEL_ERROR,
4012 "%s: failed to copy data to user buffer", __func__);
4013 ret = -EFAULT;
4014 goto exit;
4015 }
4016 ret = len;
4017 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004018 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4020 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4021 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004022 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4023 __func__, command);
4024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 }
4026exit:
4027 if (command)
4028 {
4029 kfree(command);
4030 }
4031 return ret;
4032}
4033
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004034#ifdef CONFIG_COMPAT
4035static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4036{
4037 struct {
4038 compat_uptr_t buf;
4039 int used_len;
4040 int total_len;
4041 } compat_priv_data;
4042 hdd_priv_data_t priv_data;
4043 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004044
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004045 /*
4046 * Note that pAdapter and ifr have already been verified by caller,
4047 * and HDD context has also been validated
4048 */
4049 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4050 sizeof(compat_priv_data))) {
4051 ret = -EFAULT;
4052 goto exit;
4053 }
4054 priv_data.buf = compat_ptr(compat_priv_data.buf);
4055 priv_data.used_len = compat_priv_data.used_len;
4056 priv_data.total_len = compat_priv_data.total_len;
4057 ret = hdd_driver_command(pAdapter, &priv_data);
4058 exit:
4059 return ret;
4060}
4061#else /* CONFIG_COMPAT */
4062static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4063{
4064 /* will never be invoked */
4065 return 0;
4066}
4067#endif /* CONFIG_COMPAT */
4068
4069static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4070{
4071 hdd_priv_data_t priv_data;
4072 int ret = 0;
4073
4074 /*
4075 * Note that pAdapter and ifr have already been verified by caller,
4076 * and HDD context has also been validated
4077 */
4078 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4079 ret = -EFAULT;
4080 } else {
4081 ret = hdd_driver_command(pAdapter, &priv_data);
4082 }
4083 return ret;
4084}
4085
4086int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4087{
4088 hdd_adapter_t *pAdapter;
4089 hdd_context_t *pHddCtx;
4090 int ret;
4091
4092 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4093 if (NULL == pAdapter) {
4094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4095 "%s: HDD adapter context is Null", __func__);
4096 ret = -ENODEV;
4097 goto exit;
4098 }
4099 if (dev != pAdapter->dev) {
4100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4101 "%s: HDD adapter/dev inconsistency", __func__);
4102 ret = -ENODEV;
4103 goto exit;
4104 }
4105
4106 if ((!ifr) || (!ifr->ifr_data)) {
4107 ret = -EINVAL;
4108 goto exit;
4109 }
4110
4111 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4112 ret = wlan_hdd_validate_context(pHddCtx);
4113 if (ret) {
4114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4115 "%s: invalid context", __func__);
4116 ret = -EBUSY;
4117 goto exit;
4118 }
4119
4120 switch (cmd) {
4121 case (SIOCDEVPRIVATE + 1):
4122 if (is_compat_task())
4123 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4124 else
4125 ret = hdd_driver_ioctl(pAdapter, ifr);
4126 break;
4127 default:
4128 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4129 __func__, cmd);
4130 ret = -EINVAL;
4131 break;
4132 }
4133 exit:
4134 return ret;
4135}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004136
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004137#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004138/**---------------------------------------------------------------------------
4139
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004140 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004141
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004142 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004143 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4144 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4145 <space>Scan Mode N<space>Meas Duration N
4146 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4147 then take N.
4148 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4149 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4150 This function does not take care of removing duplicate channels from the list
4151
4152 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004153 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004154
4155 \return - 0 for success non-zero for failure
4156
4157 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004158static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4159 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004160{
4161 tANI_U8 *inPtr = pValue;
4162 int tempInt = 0;
4163 int j = 0, i = 0, v = 0;
4164 char buf[32];
4165
4166 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4167 /*no argument after the command*/
4168 if (NULL == inPtr)
4169 {
4170 return -EINVAL;
4171 }
4172 /*no space after the command*/
4173 else if (SPACE_ASCII_VALUE != *inPtr)
4174 {
4175 return -EINVAL;
4176 }
4177
4178 /*removing empty spaces*/
4179 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4180
4181 /*no argument followed by spaces*/
4182 if ('\0' == *inPtr) return -EINVAL;
4183
4184 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004185 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004186 if (1 != v) return -EINVAL;
4187
4188 v = kstrtos32(buf, 10, &tempInt);
4189 if ( v < 0) return -EINVAL;
4190
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004191 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004192
4193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004194 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004195
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004196 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004197 {
4198 for (i = 0; i < 4; i++)
4199 {
4200 /*inPtr pointing to the beginning of first space after number of ie fields*/
4201 inPtr = strpbrk( inPtr, " " );
4202 /*no ie data after the number of ie fields argument*/
4203 if (NULL == inPtr) return -EINVAL;
4204
4205 /*removing empty space*/
4206 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4207
4208 /*no ie data after the number of ie fields argument and spaces*/
4209 if ( '\0' == *inPtr ) return -EINVAL;
4210
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004211 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004212 if (1 != v) return -EINVAL;
4213
4214 v = kstrtos32(buf, 10, &tempInt);
4215 if (v < 0) return -EINVAL;
4216
4217 switch (i)
4218 {
4219 case 0: /* Measurement token */
4220 if (tempInt <= 0)
4221 {
4222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4223 "Invalid Measurement Token(%d)", tempInt);
4224 return -EINVAL;
4225 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004226 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004227 break;
4228
4229 case 1: /* Channel number */
4230 if ((tempInt <= 0) ||
4231 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4232 {
4233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4234 "Invalid Channel Number(%d)", tempInt);
4235 return -EINVAL;
4236 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004237 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004238 break;
4239
4240 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004241 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004242 {
4243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4244 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4245 return -EINVAL;
4246 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004247 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004248 break;
4249
4250 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004251 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4252 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004253 {
4254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4255 "Invalid Measurement Duration(%d)", tempInt);
4256 return -EINVAL;
4257 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004258 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004259 break;
4260 }
4261 }
4262 }
4263
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004264 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004265 {
4266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304267 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004268 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004269 pEseBcnReq->bcnReq[j].measurementToken,
4270 pEseBcnReq->bcnReq[j].channel,
4271 pEseBcnReq->bcnReq[j].scanMode,
4272 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004273 }
4274
4275 return VOS_STATUS_SUCCESS;
4276}
4277
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004278static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4279{
4280 struct statsContext *pStatsContext = NULL;
4281 hdd_adapter_t *pAdapter = NULL;
4282
4283 if (NULL == pContext)
4284 {
4285 hddLog(VOS_TRACE_LEVEL_ERROR,
4286 "%s: Bad param, pContext [%p]",
4287 __func__, pContext);
4288 return;
4289 }
4290
Jeff Johnson72a40512013-12-19 10:14:15 -08004291 /* there is a race condition that exists between this callback
4292 function and the caller since the caller could time out either
4293 before or while this code is executing. we use a spinlock to
4294 serialize these actions */
4295 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004296
4297 pStatsContext = pContext;
4298 pAdapter = pStatsContext->pAdapter;
4299 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4300 {
4301 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004302 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004303 hddLog(VOS_TRACE_LEVEL_WARN,
4304 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4305 __func__, pAdapter, pStatsContext->magic);
4306 return;
4307 }
4308
Jeff Johnson72a40512013-12-19 10:14:15 -08004309 /* context is valid so caller is still waiting */
4310
4311 /* paranoia: invalidate the magic */
4312 pStatsContext->magic = 0;
4313
4314 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004315 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4316 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4317 tsmMetrics.UplinkPktQueueDlyHist,
4318 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4319 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4320 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4321 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4322 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4323 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4324 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4325
Jeff Johnson72a40512013-12-19 10:14:15 -08004326 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004327 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004328
4329 /* serialization is complete */
4330 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004331}
4332
4333
4334
4335static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4336 tAniTrafStrmMetrics* pTsmMetrics)
4337{
4338 hdd_station_ctx_t *pHddStaCtx = NULL;
4339 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004340 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004341 long lrc;
4342 struct statsContext context;
4343 hdd_context_t *pHddCtx = NULL;
4344
4345 if (NULL == pAdapter)
4346 {
4347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4348 return VOS_STATUS_E_FAULT;
4349 }
4350
4351 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4352 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4353
4354 /* we are connected prepare our callback context */
4355 init_completion(&context.completion);
4356 context.pAdapter = pAdapter;
4357 context.magic = STATS_CONTEXT_MAGIC;
4358
4359 /* query tsm stats */
4360 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4361 pHddStaCtx->conn_info.staId[ 0 ],
4362 pHddStaCtx->conn_info.bssId,
4363 &context, pHddCtx->pvosContext, tid);
4364
4365 if (eHAL_STATUS_SUCCESS != hstatus)
4366 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4368 __func__);
4369 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004370 }
4371 else
4372 {
4373 /* request was sent -- wait for the response */
4374 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4375 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004376 if (lrc <= 0)
4377 {
4378 hddLog(VOS_TRACE_LEVEL_ERROR,
4379 "%s: SME %s while retrieving statistics",
4380 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004381 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004382 }
4383 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004384
Jeff Johnson72a40512013-12-19 10:14:15 -08004385 /* either we never sent a request, we sent a request and received a
4386 response or we sent a request and timed out. if we never sent a
4387 request or if we sent a request and got a response, we want to
4388 clear the magic out of paranoia. if we timed out there is a
4389 race condition such that the callback function could be
4390 executing at the same time we are. of primary concern is if the
4391 callback function had already verified the "magic" but had not
4392 yet set the completion variable when a timeout occurred. we
4393 serialize these activities by invalidating the magic while
4394 holding a shared spinlock which will cause us to block if the
4395 callback is currently executing */
4396 spin_lock(&hdd_context_lock);
4397 context.magic = 0;
4398 spin_unlock(&hdd_context_lock);
4399
4400 if (VOS_STATUS_SUCCESS == vstatus)
4401 {
4402 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4403 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4404 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4405 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4406 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4407 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4408 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4409 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4410 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4411 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4412 }
4413 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004414}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004415#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004416
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004417#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004418void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4419{
4420 eCsrBand band = -1;
4421 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4422 switch (band)
4423 {
4424 case eCSR_BAND_ALL:
4425 *pBand = WLAN_HDD_UI_BAND_AUTO;
4426 break;
4427
4428 case eCSR_BAND_24:
4429 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4430 break;
4431
4432 case eCSR_BAND_5G:
4433 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4434 break;
4435
4436 default:
4437 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4438 *pBand = -1;
4439 break;
4440 }
4441}
4442
4443/**---------------------------------------------------------------------------
4444
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004445 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4446
4447 This function parses the send action frame data passed in the format
4448 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4449
Srinivas Girigowda56076852013-08-20 14:00:50 -07004450 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004451 \param - pTargetApBssid Pointer to target Ap bssid
4452 \param - pChannel Pointer to the Target AP channel
4453 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4454 \param - pBuf Pointer to data
4455 \param - pBufLen Pointer to data length
4456
4457 \return - 0 for success non-zero for failure
4458
4459 --------------------------------------------------------------------------*/
4460VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4461 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4462{
4463 tANI_U8 *inPtr = pValue;
4464 tANI_U8 *dataEnd;
4465 int tempInt;
4466 int j = 0;
4467 int i = 0;
4468 int v = 0;
4469 tANI_U8 tempBuf[32];
4470 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004471 /* 12 hexa decimal digits, 5 ':' and '\0' */
4472 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004473
4474 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4475 /*no argument after the command*/
4476 if (NULL == inPtr)
4477 {
4478 return -EINVAL;
4479 }
4480
4481 /*no space after the command*/
4482 else if (SPACE_ASCII_VALUE != *inPtr)
4483 {
4484 return -EINVAL;
4485 }
4486
4487 /*removing empty spaces*/
4488 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4489
4490 /*no argument followed by spaces*/
4491 if ('\0' == *inPtr)
4492 {
4493 return -EINVAL;
4494 }
4495
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004496 v = sscanf(inPtr, "%17s", macAddress);
4497 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004498 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4500 "Invalid MAC address or All hex inputs are not read (%d)", v);
4501 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004502 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004503
4504 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4505 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4506 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4507 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4508 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4509 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004510
4511 /* point to the next argument */
4512 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4513 /*no argument after the command*/
4514 if (NULL == inPtr) return -EINVAL;
4515
4516 /*removing empty spaces*/
4517 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4518
4519 /*no argument followed by spaces*/
4520 if ('\0' == *inPtr)
4521 {
4522 return -EINVAL;
4523 }
4524
4525 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004526 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004527 if (1 != v) return -EINVAL;
4528
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004529 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304530 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304531 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004532
4533 *pChannel = tempInt;
4534
4535 /* point to the next argument */
4536 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4537 /*no argument after the command*/
4538 if (NULL == inPtr) return -EINVAL;
4539 /*removing empty spaces*/
4540 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4541
4542 /*no argument followed by spaces*/
4543 if ('\0' == *inPtr)
4544 {
4545 return -EINVAL;
4546 }
4547
4548 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004549 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004550 if (1 != v) return -EINVAL;
4551
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004552 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004553 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004554
4555 *pDwellTime = tempInt;
4556
4557 /* point to the next argument */
4558 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4559 /*no argument after the command*/
4560 if (NULL == inPtr) return -EINVAL;
4561 /*removing empty spaces*/
4562 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4563
4564 /*no argument followed by spaces*/
4565 if ('\0' == *inPtr)
4566 {
4567 return -EINVAL;
4568 }
4569
4570 /* find the length of data */
4571 dataEnd = inPtr;
4572 while(('\0' != *dataEnd) )
4573 {
4574 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004575 }
Kiet Lambe150c22013-11-21 16:30:32 +05304576 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004577 if ( *pBufLen <= 0) return -EINVAL;
4578
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004579 /* Allocate the number of bytes based on the number of input characters
4580 whether it is even or odd.
4581 if the number of input characters are even, then we need N/2 byte.
4582 if the number of input characters are odd, then we need do (N+1)/2 to
4583 compensate rounding off.
4584 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4585 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4586 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004587 if (NULL == *pBuf)
4588 {
4589 hddLog(VOS_TRACE_LEVEL_FATAL,
4590 "%s: vos_mem_alloc failed ", __func__);
4591 return -EINVAL;
4592 }
4593
4594 /* the buffer received from the upper layer is character buffer,
4595 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4596 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4597 and f0 in 3rd location */
4598 for (i = 0, j = 0; j < *pBufLen; j += 2)
4599 {
Kiet Lambe150c22013-11-21 16:30:32 +05304600 if( j+1 == *pBufLen)
4601 {
4602 tempByte = hdd_parse_hex(inPtr[j]);
4603 }
4604 else
4605 {
4606 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4607 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004608 (*pBuf)[i++] = tempByte;
4609 }
4610 *pBufLen = i;
4611 return VOS_STATUS_SUCCESS;
4612}
4613
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004614/**---------------------------------------------------------------------------
4615
Srinivas Girigowdade697412013-02-14 16:31:48 -08004616 \brief hdd_parse_channellist() - HDD Parse channel list
4617
4618 This function parses the channel list passed in the format
4619 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004620 if the Number of channels (N) does not match with the actual number of channels passed
4621 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4622 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4623 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4624 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004625
4626 \param - pValue Pointer to input channel list
4627 \param - ChannelList Pointer to local output array to record channel list
4628 \param - pNumChannels Pointer to number of roam scan channels
4629
4630 \return - 0 for success non-zero for failure
4631
4632 --------------------------------------------------------------------------*/
4633VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4634{
4635 tANI_U8 *inPtr = pValue;
4636 int tempInt;
4637 int j = 0;
4638 int v = 0;
4639 char buf[32];
4640
4641 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4642 /*no argument after the command*/
4643 if (NULL == inPtr)
4644 {
4645 return -EINVAL;
4646 }
4647
4648 /*no space after the command*/
4649 else if (SPACE_ASCII_VALUE != *inPtr)
4650 {
4651 return -EINVAL;
4652 }
4653
4654 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004655 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004656
4657 /*no argument followed by spaces*/
4658 if ('\0' == *inPtr)
4659 {
4660 return -EINVAL;
4661 }
4662
4663 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004664 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004665 if (1 != v) return -EINVAL;
4666
Srinivas Girigowdade697412013-02-14 16:31:48 -08004667 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004668 if ((v < 0) ||
4669 (tempInt <= 0) ||
4670 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4671 {
4672 return -EINVAL;
4673 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004674
4675 *pNumChannels = tempInt;
4676
4677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4678 "Number of channels are: %d", *pNumChannels);
4679
4680 for (j = 0; j < (*pNumChannels); j++)
4681 {
4682 /*inPtr pointing to the beginning of first space after number of channels*/
4683 inPtr = strpbrk( inPtr, " " );
4684 /*no channel list after the number of channels argument*/
4685 if (NULL == inPtr)
4686 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004687 if (0 != j)
4688 {
4689 *pNumChannels = j;
4690 return VOS_STATUS_SUCCESS;
4691 }
4692 else
4693 {
4694 return -EINVAL;
4695 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004696 }
4697
4698 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004699 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004700
4701 /*no channel list after the number of channels argument and spaces*/
4702 if ( '\0' == *inPtr )
4703 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004704 if (0 != j)
4705 {
4706 *pNumChannels = j;
4707 return VOS_STATUS_SUCCESS;
4708 }
4709 else
4710 {
4711 return -EINVAL;
4712 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004713 }
4714
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004715 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004716 if (1 != v) return -EINVAL;
4717
Srinivas Girigowdade697412013-02-14 16:31:48 -08004718 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004719 if ((v < 0) ||
4720 (tempInt <= 0) ||
4721 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4722 {
4723 return -EINVAL;
4724 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004725 pChannelList[j] = tempInt;
4726
4727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4728 "Channel %d added to preferred channel list",
4729 pChannelList[j] );
4730 }
4731
Srinivas Girigowdade697412013-02-14 16:31:48 -08004732 return VOS_STATUS_SUCCESS;
4733}
4734
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004735
4736/**---------------------------------------------------------------------------
4737
4738 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4739
4740 This function parses the reasoc command data passed in the format
4741 REASSOC<space><bssid><space><channel>
4742
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004743 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004744 \param - pTargetApBssid Pointer to target Ap bssid
4745 \param - pChannel Pointer to the Target AP channel
4746
4747 \return - 0 for success non-zero for failure
4748
4749 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004750VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4751 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004752{
4753 tANI_U8 *inPtr = pValue;
4754 int tempInt;
4755 int v = 0;
4756 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004757 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004758 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004759
4760 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4761 /*no argument after the command*/
4762 if (NULL == inPtr)
4763 {
4764 return -EINVAL;
4765 }
4766
4767 /*no space after the command*/
4768 else if (SPACE_ASCII_VALUE != *inPtr)
4769 {
4770 return -EINVAL;
4771 }
4772
4773 /*removing empty spaces*/
4774 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4775
4776 /*no argument followed by spaces*/
4777 if ('\0' == *inPtr)
4778 {
4779 return -EINVAL;
4780 }
4781
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004782 v = sscanf(inPtr, "%17s", macAddress);
4783 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004784 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4786 "Invalid MAC address or All hex inputs are not read (%d)", v);
4787 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004788 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004789
4790 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4791 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4792 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4793 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4794 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4795 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004796
4797 /* point to the next argument */
4798 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4799 /*no argument after the command*/
4800 if (NULL == inPtr) return -EINVAL;
4801
4802 /*removing empty spaces*/
4803 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4804
4805 /*no argument followed by spaces*/
4806 if ('\0' == *inPtr)
4807 {
4808 return -EINVAL;
4809 }
4810
4811 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004812 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004813 if (1 != v) return -EINVAL;
4814
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004815 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004816 if ((v < 0) ||
4817 (tempInt <= 0) ||
4818 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4819 {
4820 return -EINVAL;
4821 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004822
4823 *pChannel = tempInt;
4824 return VOS_STATUS_SUCCESS;
4825}
4826
4827#endif
4828
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004829#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004830/**---------------------------------------------------------------------------
4831
4832 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4833
4834 This function parses the SETCCKM IE command
4835 SETCCKMIE<space><ie data>
4836
4837 \param - pValue Pointer to input data
4838 \param - pCckmIe Pointer to output cckm Ie
4839 \param - pCckmIeLen Pointer to output cckm ie length
4840
4841 \return - 0 for success non-zero for failure
4842
4843 --------------------------------------------------------------------------*/
4844VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4845 tANI_U8 *pCckmIeLen)
4846{
4847 tANI_U8 *inPtr = pValue;
4848 tANI_U8 *dataEnd;
4849 int j = 0;
4850 int i = 0;
4851 tANI_U8 tempByte = 0;
4852
4853 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4854 /*no argument after the command*/
4855 if (NULL == inPtr)
4856 {
4857 return -EINVAL;
4858 }
4859
4860 /*no space after the command*/
4861 else if (SPACE_ASCII_VALUE != *inPtr)
4862 {
4863 return -EINVAL;
4864 }
4865
4866 /*removing empty spaces*/
4867 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4868
4869 /*no argument followed by spaces*/
4870 if ('\0' == *inPtr)
4871 {
4872 return -EINVAL;
4873 }
4874
4875 /* find the length of data */
4876 dataEnd = inPtr;
4877 while(('\0' != *dataEnd) )
4878 {
4879 dataEnd++;
4880 ++(*pCckmIeLen);
4881 }
4882 if ( *pCckmIeLen <= 0) return -EINVAL;
4883
4884 /* Allocate the number of bytes based on the number of input characters
4885 whether it is even or odd.
4886 if the number of input characters are even, then we need N/2 byte.
4887 if the number of input characters are odd, then we need do (N+1)/2 to
4888 compensate rounding off.
4889 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4890 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4891 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4892 if (NULL == *pCckmIe)
4893 {
4894 hddLog(VOS_TRACE_LEVEL_FATAL,
4895 "%s: vos_mem_alloc failed ", __func__);
4896 return -EINVAL;
4897 }
4898 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4899 /* the buffer received from the upper layer is character buffer,
4900 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4901 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4902 and f0 in 3rd location */
4903 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4904 {
4905 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4906 (*pCckmIe)[i++] = tempByte;
4907 }
4908 *pCckmIeLen = i;
4909
4910 return VOS_STATUS_SUCCESS;
4911}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004912#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004913
Jeff Johnson295189b2012-06-20 16:38:30 -07004914/**---------------------------------------------------------------------------
4915
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004916 \brief hdd_is_valid_mac_address() - Validate MAC address
4917
4918 This function validates whether the given MAC address is valid or not
4919 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4920 where X is the hexa decimal digit character and separated by ':'
4921 This algorithm works even if MAC address is not separated by ':'
4922
4923 This code checks given input string mac contains exactly 12 hexadecimal digits.
4924 and a separator colon : appears in the input string only after
4925 an even number of hex digits.
4926
4927 \param - pMacAddr pointer to the input MAC address
4928 \return - 1 for valid and 0 for invalid
4929
4930 --------------------------------------------------------------------------*/
4931
4932v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4933{
4934 int xdigit = 0;
4935 int separator = 0;
4936 while (*pMacAddr)
4937 {
4938 if (isxdigit(*pMacAddr))
4939 {
4940 xdigit++;
4941 }
4942 else if (':' == *pMacAddr)
4943 {
4944 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4945 break;
4946
4947 ++separator;
4948 }
4949 else
4950 {
4951 separator = -1;
4952 /* Invalid MAC found */
4953 return 0;
4954 }
4955 ++pMacAddr;
4956 }
4957 return (xdigit == 12 && (separator == 5 || separator == 0));
4958}
4959
4960/**---------------------------------------------------------------------------
4961
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 \brief hdd_open() - HDD Open function
4963
4964 This is called in response to ifconfig up
4965
4966 \param - dev Pointer to net_device structure
4967
4968 \return - 0 for success non-zero for failure
4969
4970 --------------------------------------------------------------------------*/
4971int hdd_open (struct net_device *dev)
4972{
4973 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4974 hdd_context_t *pHddCtx;
4975 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4976 VOS_STATUS status;
4977 v_BOOL_t in_standby = TRUE;
4978
4979 if (NULL == pAdapter)
4980 {
4981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304982 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 return -ENODEV;
4984 }
4985
4986 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304987 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4988 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 if (NULL == pHddCtx)
4990 {
4991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004992 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004993 return -ENODEV;
4994 }
4995
4996 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4997 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4998 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004999 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5000 {
5001 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305002 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005003 in_standby = FALSE;
5004 break;
5005 }
5006 else
5007 {
5008 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5009 pAdapterNode = pNext;
5010 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 }
5012
5013 if (TRUE == in_standby)
5014 {
5015 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5016 {
5017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5018 "wlan out of power save", __func__);
5019 return -EINVAL;
5020 }
5021 }
5022
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005023 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005024 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5025 {
5026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005027 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 /* Enable TX queues only when we are connected */
5029 netif_tx_start_all_queues(dev);
5030 }
5031
5032 return 0;
5033}
5034
5035int hdd_mon_open (struct net_device *dev)
5036{
5037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5038
5039 if(pAdapter == NULL) {
5040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005041 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005042 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005043 }
5044
5045 netif_start_queue(dev);
5046
5047 return 0;
5048}
5049/**---------------------------------------------------------------------------
5050
5051 \brief hdd_stop() - HDD stop function
5052
5053 This is called in response to ifconfig down
5054
5055 \param - dev Pointer to net_device structure
5056
5057 \return - 0 for success non-zero for failure
5058
5059 --------------------------------------------------------------------------*/
5060
5061int hdd_stop (struct net_device *dev)
5062{
5063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5064 hdd_context_t *pHddCtx;
5065 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5066 VOS_STATUS status;
5067 v_BOOL_t enter_standby = TRUE;
5068
5069 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 if (NULL == pAdapter)
5071 {
5072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305073 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005074 return -ENODEV;
5075 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305076 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5077 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5079 if (NULL == pHddCtx)
5080 {
5081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005082 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005083 return -ENODEV;
5084 }
5085
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005086 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
5088 netif_tx_disable(pAdapter->dev);
5089 netif_carrier_off(pAdapter->dev);
5090
5091
5092 /* SoftAP ifaces should never go in power save mode
5093 making sure same here. */
5094 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5095 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 )
5098 {
5099 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5101 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 EXIT();
5103 return 0;
5104 }
5105
5106 /* Find if any iface is up then
5107 if any iface is up then can't put device to sleep/ power save mode. */
5108 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5109 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5110 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005111 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5112 {
5113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305114 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005115 enter_standby = FALSE;
5116 break;
5117 }
5118 else
5119 {
5120 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5121 pAdapterNode = pNext;
5122 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 }
5124
5125 if (TRUE == enter_standby)
5126 {
5127 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5128 "entering standby", __func__);
5129 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5130 {
5131 /*log and return success*/
5132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5133 "wlan in power save", __func__);
5134 }
5135 }
5136
5137 EXIT();
5138 return 0;
5139}
5140
5141/**---------------------------------------------------------------------------
5142
5143 \brief hdd_uninit() - HDD uninit function
5144
5145 This is called during the netdev unregister to uninitialize all data
5146associated with the device
5147
5148 \param - dev Pointer to net_device structure
5149
5150 \return - void
5151
5152 --------------------------------------------------------------------------*/
5153static void hdd_uninit (struct net_device *dev)
5154{
5155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5156
5157 ENTER();
5158
5159 do
5160 {
5161 if (NULL == pAdapter)
5162 {
5163 hddLog(VOS_TRACE_LEVEL_FATAL,
5164 "%s: NULL pAdapter", __func__);
5165 break;
5166 }
5167
5168 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5169 {
5170 hddLog(VOS_TRACE_LEVEL_FATAL,
5171 "%s: Invalid magic", __func__);
5172 break;
5173 }
5174
5175 if (NULL == pAdapter->pHddCtx)
5176 {
5177 hddLog(VOS_TRACE_LEVEL_FATAL,
5178 "%s: NULL pHddCtx", __func__);
5179 break;
5180 }
5181
5182 if (dev != pAdapter->dev)
5183 {
5184 hddLog(VOS_TRACE_LEVEL_FATAL,
5185 "%s: Invalid device reference", __func__);
5186 /* we haven't validated all cases so let this go for now */
5187 }
5188
5189 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5190
5191 /* after uninit our adapter structure will no longer be valid */
5192 pAdapter->dev = NULL;
5193 pAdapter->magic = 0;
5194 } while (0);
5195
5196 EXIT();
5197}
5198
5199/**---------------------------------------------------------------------------
5200
5201 \brief hdd_release_firmware() -
5202
5203 This function calls the release firmware API to free the firmware buffer.
5204
5205 \param - pFileName Pointer to the File Name.
5206 pCtx - Pointer to the adapter .
5207
5208
5209 \return - 0 for success, non zero for failure
5210
5211 --------------------------------------------------------------------------*/
5212
5213VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5214{
5215 VOS_STATUS status = VOS_STATUS_SUCCESS;
5216 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5217 ENTER();
5218
5219
5220 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5221
5222 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5223
5224 if(pHddCtx->fw) {
5225 release_firmware(pHddCtx->fw);
5226 pHddCtx->fw = NULL;
5227 }
5228 else
5229 status = VOS_STATUS_E_FAILURE;
5230 }
5231 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5232 if(pHddCtx->nv) {
5233 release_firmware(pHddCtx->nv);
5234 pHddCtx->nv = NULL;
5235 }
5236 else
5237 status = VOS_STATUS_E_FAILURE;
5238
5239 }
5240
5241 EXIT();
5242 return status;
5243}
5244
5245/**---------------------------------------------------------------------------
5246
5247 \brief hdd_request_firmware() -
5248
5249 This function reads the firmware file using the request firmware
5250 API and returns the the firmware data and the firmware file size.
5251
5252 \param - pfileName - Pointer to the file name.
5253 - pCtx - Pointer to the adapter .
5254 - ppfw_data - Pointer to the pointer of the firmware data.
5255 - pSize - Pointer to the file size.
5256
5257 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5258
5259 --------------------------------------------------------------------------*/
5260
5261
5262VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5263{
5264 int status;
5265 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5266 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5267 ENTER();
5268
5269 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5270
5271 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5272
5273 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5274 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5275 __func__, pfileName);
5276 retval = VOS_STATUS_E_FAILURE;
5277 }
5278
5279 else {
5280 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5281 *pSize = pHddCtx->fw->size;
5282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5283 __func__, *pSize);
5284 }
5285 }
5286 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5287
5288 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5289
5290 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5291 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5292 __func__, pfileName);
5293 retval = VOS_STATUS_E_FAILURE;
5294 }
5295
5296 else {
5297 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5298 *pSize = pHddCtx->nv->size;
5299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5300 __func__, *pSize);
5301 }
5302 }
5303
5304 EXIT();
5305 return retval;
5306}
5307/**---------------------------------------------------------------------------
5308 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5309
5310 This is the function invoked by SME to inform the result of a full power
5311 request issued by HDD
5312
5313 \param - callbackcontext - Pointer to cookie
5314 status - result of request
5315
5316 \return - None
5317
5318--------------------------------------------------------------------------*/
5319void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5320{
5321 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5322
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005323 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005324 if(&pHddCtx->full_pwr_comp_var)
5325 {
5326 complete(&pHddCtx->full_pwr_comp_var);
5327 }
5328}
5329
5330/**---------------------------------------------------------------------------
5331
5332 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5333
5334 This is the function invoked by SME to inform the result of BMPS
5335 request issued by HDD
5336
5337 \param - callbackcontext - Pointer to cookie
5338 status - result of request
5339
5340 \return - None
5341
5342--------------------------------------------------------------------------*/
5343void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5344{
5345
5346 struct completion *completion_var = (struct completion*) callbackContext;
5347
Arif Hussain6d2a3322013-11-17 19:50:10 -08005348 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 if(completion_var != NULL)
5350 {
5351 complete(completion_var);
5352 }
5353}
5354
5355/**---------------------------------------------------------------------------
5356
5357 \brief hdd_get_cfg_file_size() -
5358
5359 This function reads the configuration file using the request firmware
5360 API and returns the configuration file size.
5361
5362 \param - pCtx - Pointer to the adapter .
5363 - pFileName - Pointer to the file name.
5364 - pBufSize - Pointer to the buffer size.
5365
5366 \return - 0 for success, non zero for failure
5367
5368 --------------------------------------------------------------------------*/
5369
5370VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5371{
5372 int status;
5373 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5374
5375 ENTER();
5376
5377 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5378
5379 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5380 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5381 status = VOS_STATUS_E_FAILURE;
5382 }
5383 else {
5384 *pBufSize = pHddCtx->fw->size;
5385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5386 release_firmware(pHddCtx->fw);
5387 pHddCtx->fw = NULL;
5388 }
5389
5390 EXIT();
5391 return VOS_STATUS_SUCCESS;
5392}
5393
5394/**---------------------------------------------------------------------------
5395
5396 \brief hdd_read_cfg_file() -
5397
5398 This function reads the configuration file using the request firmware
5399 API and returns the cfg data and the buffer size of the configuration file.
5400
5401 \param - pCtx - Pointer to the adapter .
5402 - pFileName - Pointer to the file name.
5403 - pBuffer - Pointer to the data buffer.
5404 - pBufSize - Pointer to the buffer size.
5405
5406 \return - 0 for success, non zero for failure
5407
5408 --------------------------------------------------------------------------*/
5409
5410VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5411 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5412{
5413 int status;
5414 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5415
5416 ENTER();
5417
5418 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5419
5420 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5421 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5422 return VOS_STATUS_E_FAILURE;
5423 }
5424 else {
5425 if(*pBufSize != pHddCtx->fw->size) {
5426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5427 "file size", __func__);
5428 release_firmware(pHddCtx->fw);
5429 pHddCtx->fw = NULL;
5430 return VOS_STATUS_E_FAILURE;
5431 }
5432 else {
5433 if(pBuffer) {
5434 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5435 }
5436 release_firmware(pHddCtx->fw);
5437 pHddCtx->fw = NULL;
5438 }
5439 }
5440
5441 EXIT();
5442
5443 return VOS_STATUS_SUCCESS;
5444}
5445
5446/**---------------------------------------------------------------------------
5447
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 \brief hdd_set_mac_address() -
5449
5450 This function sets the user specified mac address using
5451 the command ifconfig wlanX hw ether <mac adress>.
5452
5453 \param - dev - Pointer to the net device.
5454 - addr - Pointer to the sockaddr.
5455 \return - 0 for success, non zero for failure
5456
5457 --------------------------------------------------------------------------*/
5458
5459static int hdd_set_mac_address(struct net_device *dev, void *addr)
5460{
5461 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5462 struct sockaddr *psta_mac_addr = addr;
5463 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5464
5465 ENTER();
5466
5467 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5469
5470 EXIT();
5471 return halStatus;
5472}
5473
5474tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5475{
5476 int i;
5477 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5478 {
Abhishek Singheb183782014-02-06 13:37:21 +05305479 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 break;
5481 }
5482
5483 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5484 return NULL;
5485
5486 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5487 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5488}
5489
5490void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5491{
5492 int i;
5493 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5494 {
5495 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5496 {
5497 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5498 break;
5499 }
5500 }
5501 return;
5502}
5503
5504#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5505 static struct net_device_ops wlan_drv_ops = {
5506 .ndo_open = hdd_open,
5507 .ndo_stop = hdd_stop,
5508 .ndo_uninit = hdd_uninit,
5509 .ndo_start_xmit = hdd_hard_start_xmit,
5510 .ndo_tx_timeout = hdd_tx_timeout,
5511 .ndo_get_stats = hdd_stats,
5512 .ndo_do_ioctl = hdd_ioctl,
5513 .ndo_set_mac_address = hdd_set_mac_address,
5514 .ndo_select_queue = hdd_select_queue,
5515#ifdef WLAN_FEATURE_PACKET_FILTERING
5516#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5517 .ndo_set_rx_mode = hdd_set_multicast_list,
5518#else
5519 .ndo_set_multicast_list = hdd_set_multicast_list,
5520#endif //LINUX_VERSION_CODE
5521#endif
5522 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 static struct net_device_ops wlan_mon_drv_ops = {
5524 .ndo_open = hdd_mon_open,
5525 .ndo_stop = hdd_stop,
5526 .ndo_uninit = hdd_uninit,
5527 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5528 .ndo_tx_timeout = hdd_tx_timeout,
5529 .ndo_get_stats = hdd_stats,
5530 .ndo_do_ioctl = hdd_ioctl,
5531 .ndo_set_mac_address = hdd_set_mac_address,
5532 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005533
5534#endif
5535
5536void hdd_set_station_ops( struct net_device *pWlanDev )
5537{
5538#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 pWlanDev->netdev_ops = &wlan_drv_ops;
5540#else
5541 pWlanDev->open = hdd_open;
5542 pWlanDev->stop = hdd_stop;
5543 pWlanDev->uninit = hdd_uninit;
5544 pWlanDev->hard_start_xmit = NULL;
5545 pWlanDev->tx_timeout = hdd_tx_timeout;
5546 pWlanDev->get_stats = hdd_stats;
5547 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 pWlanDev->set_mac_address = hdd_set_mac_address;
5549#endif
5550}
5551
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005552static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005553{
5554 struct net_device *pWlanDev = NULL;
5555 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 /*
5557 * cfg80211 initialization and registration....
5558 */
5559 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5560
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 if(pWlanDev != NULL)
5562 {
5563
5564 //Save the pointer to the net_device in the HDD adapter
5565 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5566
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5568
5569 pAdapter->dev = pWlanDev;
5570 pAdapter->pHddCtx = pHddCtx;
5571 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5572
5573 init_completion(&pAdapter->session_open_comp_var);
5574 init_completion(&pAdapter->session_close_comp_var);
5575 init_completion(&pAdapter->disconnect_comp_var);
5576 init_completion(&pAdapter->linkup_event_var);
5577 init_completion(&pAdapter->cancel_rem_on_chan_var);
5578 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305579 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5581 init_completion(&pAdapter->offchannel_tx_event);
5582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005584#ifdef FEATURE_WLAN_TDLS
5585 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005586 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005587 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305588 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005589#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 init_completion(&pHddCtx->mc_sus_event_var);
5591 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305592 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005593 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005594 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005595
Rajeev79dbe4c2013-10-05 11:03:42 +05305596#ifdef FEATURE_WLAN_BATCH_SCAN
5597 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5598 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5599 pAdapter->pBatchScanRsp = NULL;
5600 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005601 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005602 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305603 mutex_init(&pAdapter->hdd_batch_scan_lock);
5604#endif
5605
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 pAdapter->isLinkUpSvcNeeded = FALSE;
5607 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5608 //Init the net_device structure
5609 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5610
5611 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5612 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5613 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5614 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5615
5616 hdd_set_station_ops( pAdapter->dev );
5617
5618 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5620 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5621 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 /* set pWlanDev's parent to underlying device */
5623 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5624 }
5625
5626 return pAdapter;
5627}
5628
5629VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5630{
5631 struct net_device *pWlanDev = pAdapter->dev;
5632 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5633 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5634 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5635
5636 if( rtnl_lock_held )
5637 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005638 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5640 {
5641 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5642 return VOS_STATUS_E_FAILURE;
5643 }
5644 }
5645 if (register_netdevice(pWlanDev))
5646 {
5647 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5648 return VOS_STATUS_E_FAILURE;
5649 }
5650 }
5651 else
5652 {
5653 if(register_netdev(pWlanDev))
5654 {
5655 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5656 return VOS_STATUS_E_FAILURE;
5657 }
5658 }
5659 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5660
5661 return VOS_STATUS_SUCCESS;
5662}
5663
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005664static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005665{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005666 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005667
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005668 if (NULL == pAdapter)
5669 {
5670 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5671 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005673
5674 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5675 {
5676 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5677 return eHAL_STATUS_NOT_INITIALIZED;
5678 }
5679
5680 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5681
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005682#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005683 /* need to make sure all of our scheduled work has completed.
5684 * This callback is called from MC thread context, so it is safe to
5685 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005686 *
5687 * Even though this is called from MC thread context, if there is a faulty
5688 * work item in the system, that can hang this call forever. So flushing
5689 * this global work queue is not safe; and now we make sure that
5690 * individual work queues are stopped correctly. But the cancel work queue
5691 * is a GPL only API, so the proprietary version of the driver would still
5692 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005693 */
5694 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005695#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005696
5697 /* We can be blocked while waiting for scheduled work to be
5698 * flushed, and the adapter structure can potentially be freed, in
5699 * which case the magic will have been reset. So make sure the
5700 * magic is still good, and hence the adapter structure is still
5701 * valid, before signaling completion */
5702 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5703 {
5704 complete(&pAdapter->session_close_comp_var);
5705 }
5706
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 return eHAL_STATUS_SUCCESS;
5708}
5709
5710VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5711{
5712 struct net_device *pWlanDev = pAdapter->dev;
5713 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5714 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5715 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5716 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305717 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005718
5719 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005720 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 //Open a SME session for future operation
5722 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005723 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5725 {
5726 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005727 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 halStatus, halStatus );
5729 status = VOS_STATUS_E_FAILURE;
5730 goto error_sme_open;
5731 }
5732
5733 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305734 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 &pAdapter->session_open_comp_var,
5736 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305737 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 {
5739 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305740 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 status = VOS_STATUS_E_FAILURE;
5742 goto error_sme_open;
5743 }
5744
5745 // Register wireless extensions
5746 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5747 {
5748 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005749 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 halStatus, halStatus );
5751 status = VOS_STATUS_E_FAILURE;
5752 goto error_register_wext;
5753 }
5754 //Safe to register the hard_start_xmit function again
5755#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5756 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5757#else
5758 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5759#endif
5760
5761 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305762 hddLog(VOS_TRACE_LEVEL_INFO,
5763 "%s: Set HDD connState to eConnectionState_NotConnected",
5764 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5766
5767 //Set the default operation channel
5768 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5769
5770 /* Make the default Auth Type as OPEN*/
5771 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5772
5773 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5774 {
5775 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005776 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 status, status );
5778 goto error_init_txrx;
5779 }
5780
5781 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5782
5783 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5784 {
5785 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005786 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 status, status );
5788 goto error_wmm_init;
5789 }
5790
5791 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5792
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005793#ifdef FEATURE_WLAN_TDLS
5794 if(0 != wlan_hdd_tdls_init(pAdapter))
5795 {
5796 status = VOS_STATUS_E_FAILURE;
5797 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5798 goto error_tdls_init;
5799 }
5800 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5801#endif
5802
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 return VOS_STATUS_SUCCESS;
5804
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005805#ifdef FEATURE_WLAN_TDLS
5806error_tdls_init:
5807 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5808 hdd_wmm_adapter_close(pAdapter);
5809#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005810error_wmm_init:
5811 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5812 hdd_deinit_tx_rx(pAdapter);
5813error_init_txrx:
5814 hdd_UnregisterWext(pWlanDev);
5815error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005816 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 {
5818 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005819 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005821 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305823 unsigned long rc;
5824
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305826 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005828 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305829 if (rc <= 0)
5830 hddLog(VOS_TRACE_LEVEL_ERROR,
5831 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 }
5833}
5834error_sme_open:
5835 return status;
5836}
5837
Jeff Johnson295189b2012-06-20 16:38:30 -07005838void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5839{
5840 hdd_cfg80211_state_t *cfgState;
5841
5842 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5843
5844 if( NULL != cfgState->buf )
5845 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305846 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5848 rc = wait_for_completion_interruptible_timeout(
5849 &pAdapter->tx_action_cnf_event,
5850 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305851 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305854 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5855 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 }
5857 }
5858 return;
5859}
Jeff Johnson295189b2012-06-20 16:38:30 -07005860
5861void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5862{
5863 ENTER();
5864 switch ( pAdapter->device_mode )
5865 {
5866 case WLAN_HDD_INFRA_STATION:
5867 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005868 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 {
5870 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5871 {
5872 hdd_deinit_tx_rx( pAdapter );
5873 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5874 }
5875
5876 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5877 {
5878 hdd_wmm_adapter_close( pAdapter );
5879 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5880 }
5881
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005883#ifdef FEATURE_WLAN_TDLS
5884 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5885 {
5886 wlan_hdd_tdls_exit(pAdapter);
5887 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5888 }
5889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005890
5891 break;
5892 }
5893
5894 case WLAN_HDD_SOFTAP:
5895 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305897
5898 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5899 {
5900 hdd_wmm_adapter_close( pAdapter );
5901 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5902 }
5903
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005905
5906 hdd_unregister_hostapd(pAdapter);
5907 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 break;
5910 }
5911
5912 case WLAN_HDD_MONITOR:
5913 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5916 {
5917 hdd_deinit_tx_rx( pAdapter );
5918 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 if(NULL != pAdapterforTx)
5921 {
5922 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5923 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 break;
5925 }
5926
5927
5928 default:
5929 break;
5930 }
5931
5932 EXIT();
5933}
5934
5935void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5936{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005937 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305938
5939 ENTER();
5940 if (NULL == pAdapter)
5941 {
5942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5943 "%s: HDD adapter is Null", __func__);
5944 return;
5945 }
5946
5947 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005948
Rajeev79dbe4c2013-10-05 11:03:42 +05305949#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305950 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5951 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005952 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305953 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5954 )
5955 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005956 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305957 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005958 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5959 {
5960 hdd_deinit_batch_scan(pAdapter);
5961 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305962 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005963 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305964#endif
5965
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5967 if( rtnl_held )
5968 {
5969 unregister_netdevice(pWlanDev);
5970 }
5971 else
5972 {
5973 unregister_netdev(pWlanDev);
5974 }
5975 // note that the pAdapter is no longer valid at this point
5976 // since the memory has been reclaimed
5977 }
5978
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305979 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005980}
5981
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005982void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5983{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305984 VOS_STATUS status;
5985 hdd_adapter_t *pAdapter = NULL;
5986 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005987
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305988 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005989
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305990 /*loop through all adapters.*/
5991 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005992 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305993 pAdapter = pAdapterNode->pAdapter;
5994 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5995 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005996
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305997 { // we skip this registration for modes other than STA and P2P client modes.
5998 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5999 pAdapterNode = pNext;
6000 continue;
6001 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006002
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306003 //Apply Dynamic DTIM For P2P
6004 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6005 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6006 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6007 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6008 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6009 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6010 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6011 (eConnectionState_Associated ==
6012 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6013 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6014 {
6015 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006016
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306017 powerRequest.uIgnoreDTIM = 1;
6018 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6019
6020 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6021 {
6022 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6023 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6024 }
6025 else
6026 {
6027 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6028 }
6029
6030 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6031 * specified during Enter/Exit BMPS when LCD off*/
6032 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6033 NULL, eANI_BOOLEAN_FALSE);
6034 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6035 NULL, eANI_BOOLEAN_FALSE);
6036
6037 /* switch to the DTIM specified in cfg.ini */
6038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6039 "Switch to DTIM %d", powerRequest.uListenInterval);
6040 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6041 break;
6042
6043 }
6044
6045 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6046 pAdapterNode = pNext;
6047 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006048}
6049
6050void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6051{
6052 /*Switch back to DTIM 1*/
6053 tSirSetPowerParamsReq powerRequest = { 0 };
6054
6055 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6056 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006057 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006058
6059 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6060 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6061 NULL, eANI_BOOLEAN_FALSE);
6062 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6063 NULL, eANI_BOOLEAN_FALSE);
6064
6065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6066 "Switch to DTIM%d",powerRequest.uListenInterval);
6067 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6068
6069}
6070
Jeff Johnson295189b2012-06-20 16:38:30 -07006071VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6072{
6073 VOS_STATUS status = VOS_STATUS_SUCCESS;
6074
6075 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6076 {
6077 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6078 }
6079
6080 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6081 {
6082 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6083 }
6084
6085 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6086 {
6087 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6088 }
6089
6090 return status;
6091}
6092
6093VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6094{
6095 hdd_adapter_t *pAdapter = NULL;
6096 eHalStatus halStatus;
6097 VOS_STATUS status = VOS_STATUS_E_INVAL;
6098 v_BOOL_t disableBmps = FALSE;
6099 v_BOOL_t disableImps = FALSE;
6100
6101 switch(session_type)
6102 {
6103 case WLAN_HDD_INFRA_STATION:
6104 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 case WLAN_HDD_P2P_CLIENT:
6106 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 //Exit BMPS -> Is Sta/P2P Client is already connected
6108 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6109 if((NULL != pAdapter)&&
6110 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6111 {
6112 disableBmps = TRUE;
6113 }
6114
6115 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6116 if((NULL != pAdapter)&&
6117 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6118 {
6119 disableBmps = TRUE;
6120 }
6121
6122 //Exit both Bmps and Imps incase of Go/SAP Mode
6123 if((WLAN_HDD_SOFTAP == session_type) ||
6124 (WLAN_HDD_P2P_GO == session_type))
6125 {
6126 disableBmps = TRUE;
6127 disableImps = TRUE;
6128 }
6129
6130 if(TRUE == disableImps)
6131 {
6132 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6133 {
6134 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6135 }
6136 }
6137
6138 if(TRUE == disableBmps)
6139 {
6140 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6141 {
6142 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6143
6144 if(eHAL_STATUS_SUCCESS != halStatus)
6145 {
6146 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006147 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 VOS_ASSERT(0);
6149 return status;
6150 }
6151 }
6152
6153 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6154 {
6155 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6156
6157 if(eHAL_STATUS_SUCCESS != halStatus)
6158 {
6159 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006160 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 VOS_ASSERT(0);
6162 return status;
6163 }
6164 }
6165 }
6166
6167 if((TRUE == disableBmps) ||
6168 (TRUE == disableImps))
6169 {
6170 /* Now, get the chip into Full Power now */
6171 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6172 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6173 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6174
6175 if(halStatus != eHAL_STATUS_SUCCESS)
6176 {
6177 if(halStatus == eHAL_STATUS_PMC_PENDING)
6178 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306179 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306181 ret = wait_for_completion_interruptible_timeout(
6182 &pHddCtx->full_pwr_comp_var,
6183 msecs_to_jiffies(1000));
6184 if (ret <= 0)
6185 {
6186 hddLog(VOS_TRACE_LEVEL_ERROR,
6187 "%s: wait on full_pwr_comp_var failed %ld",
6188 __func__, ret);
6189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 }
6191 else
6192 {
6193 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006194 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 VOS_ASSERT(0);
6196 return status;
6197 }
6198 }
6199
6200 status = VOS_STATUS_SUCCESS;
6201 }
6202
6203 break;
6204 }
6205 return status;
6206}
6207
6208hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006209 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 tANI_U8 rtnl_held )
6211{
6212 hdd_adapter_t *pAdapter = NULL;
6213 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6214 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6215 VOS_STATUS exitbmpsStatus;
6216
Arif Hussain6d2a3322013-11-17 19:50:10 -08006217 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006218
Nirav Shah436658f2014-02-28 17:05:45 +05306219 if(macAddr == NULL)
6220 {
6221 /* Not received valid macAddr */
6222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6223 "%s:Unable to add virtual intf: Not able to get"
6224 "valid mac address",__func__);
6225 return NULL;
6226 }
6227
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 //Disable BMPS incase of Concurrency
6229 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6230
6231 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6232 {
6233 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306234 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006235 VOS_ASSERT(0);
6236 return NULL;
6237 }
6238
6239 switch(session_type)
6240 {
6241 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006243 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 {
6245 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6246
6247 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306248 {
6249 hddLog(VOS_TRACE_LEVEL_FATAL,
6250 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306252 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006253
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306254#ifdef FEATURE_WLAN_TDLS
6255 /* A Mutex Lock is introduced while changing/initializing the mode to
6256 * protect the concurrent access for the Adapters by TDLS module.
6257 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306258 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306259#endif
6260
Jeff Johnsone7245742012-09-05 17:12:55 -07006261 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6262 NL80211_IFTYPE_P2P_CLIENT:
6263 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006264
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306266#ifdef FEATURE_WLAN_TDLS
6267 mutex_unlock(&pHddCtx->tdls_lock);
6268#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306269
6270 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 if( VOS_STATUS_SUCCESS != status )
6272 goto err_free_netdev;
6273
6274 status = hdd_register_interface( pAdapter, rtnl_held );
6275 if( VOS_STATUS_SUCCESS != status )
6276 {
6277 hdd_deinit_adapter(pHddCtx, pAdapter);
6278 goto err_free_netdev;
6279 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306280
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306281 // Workqueue which gets scheduled in IPv4 notification callback.
6282 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6283
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306284#ifdef WLAN_NS_OFFLOAD
6285 // Workqueue which gets scheduled in IPv6 notification callback.
6286 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6287#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 //Stop the Interface TX queue.
6289 netif_tx_disable(pAdapter->dev);
6290 //netif_tx_disable(pWlanDev);
6291 netif_carrier_off(pAdapter->dev);
6292
6293 break;
6294 }
6295
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006297 case WLAN_HDD_SOFTAP:
6298 {
6299 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6300 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306301 {
6302 hddLog(VOS_TRACE_LEVEL_FATAL,
6303 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006306
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6308 NL80211_IFTYPE_AP:
6309 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 pAdapter->device_mode = session_type;
6311
6312 status = hdd_init_ap_mode(pAdapter);
6313 if( VOS_STATUS_SUCCESS != status )
6314 goto err_free_netdev;
6315
6316 status = hdd_register_hostapd( pAdapter, rtnl_held );
6317 if( VOS_STATUS_SUCCESS != status )
6318 {
6319 hdd_deinit_adapter(pHddCtx, pAdapter);
6320 goto err_free_netdev;
6321 }
6322
6323 netif_tx_disable(pAdapter->dev);
6324 netif_carrier_off(pAdapter->dev);
6325
6326 hdd_set_conparam( 1 );
6327 break;
6328 }
6329 case WLAN_HDD_MONITOR:
6330 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6332 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306333 {
6334 hddLog(VOS_TRACE_LEVEL_FATAL,
6335 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006338
6339 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6340 pAdapter->device_mode = session_type;
6341 status = hdd_register_interface( pAdapter, rtnl_held );
6342#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6343 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6344#else
6345 pAdapter->dev->open = hdd_mon_open;
6346 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6347#endif
6348 hdd_init_tx_rx( pAdapter );
6349 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6350 //Set adapter to be used for data tx. It will use either GO or softap.
6351 pAdapter->sessionCtx.monitor.pAdapterForTx =
6352 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6354 {
6355 pAdapter->sessionCtx.monitor.pAdapterForTx =
6356 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 /* This workqueue will be used to transmit management packet over
6359 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006360 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6361 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6362 return NULL;
6363 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006364
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6366 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 }
6368 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 case WLAN_HDD_FTM:
6370 {
6371 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6372
6373 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306374 {
6375 hddLog(VOS_TRACE_LEVEL_FATAL,
6376 FL("failed to allocate adapter for session %d"), session_type);
6377 return NULL;
6378 }
6379
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6381 * message while loading driver in FTM mode. */
6382 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6383 pAdapter->device_mode = session_type;
6384 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306385
6386 hdd_init_tx_rx( pAdapter );
6387
6388 //Stop the Interface TX queue.
6389 netif_tx_disable(pAdapter->dev);
6390 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 }
6392 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 default:
6394 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306395 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6396 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 VOS_ASSERT(0);
6398 return NULL;
6399 }
6400 }
6401
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 if( VOS_STATUS_SUCCESS == status )
6403 {
6404 //Add it to the hdd's session list.
6405 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6406 if( NULL == pHddAdapterNode )
6407 {
6408 status = VOS_STATUS_E_NOMEM;
6409 }
6410 else
6411 {
6412 pHddAdapterNode->pAdapter = pAdapter;
6413 status = hdd_add_adapter_back ( pHddCtx,
6414 pHddAdapterNode );
6415 }
6416 }
6417
6418 if( VOS_STATUS_SUCCESS != status )
6419 {
6420 if( NULL != pAdapter )
6421 {
6422 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6423 pAdapter = NULL;
6424 }
6425 if( NULL != pHddAdapterNode )
6426 {
6427 vos_mem_free( pHddAdapterNode );
6428 }
6429
6430 goto resume_bmps;
6431 }
6432
6433 if(VOS_STATUS_SUCCESS == status)
6434 {
6435 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6436
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006437 //Initialize the WoWL service
6438 if(!hdd_init_wowl(pAdapter))
6439 {
6440 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6441 goto err_free_netdev;
6442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 return pAdapter;
6445
6446err_free_netdev:
6447 free_netdev(pAdapter->dev);
6448 wlan_hdd_release_intf_addr( pHddCtx,
6449 pAdapter->macAddressCurrent.bytes );
6450
6451resume_bmps:
6452 //If bmps disabled enable it
6453 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6454 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306455 if (pHddCtx->hdd_wlan_suspended)
6456 {
6457 hdd_set_pwrparams(pHddCtx);
6458 }
6459 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 }
6461 return NULL;
6462}
6463
6464VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6465 tANI_U8 rtnl_held )
6466{
6467 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6468 VOS_STATUS status;
6469
6470 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6471 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306472 {
6473 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6474 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006477
6478 while ( pCurrent->pAdapter != pAdapter )
6479 {
6480 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6481 if( VOS_STATUS_SUCCESS != status )
6482 break;
6483
6484 pCurrent = pNext;
6485 }
6486 pAdapterNode = pCurrent;
6487 if( VOS_STATUS_SUCCESS == status )
6488 {
6489 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6490 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306491
6492#ifdef FEATURE_WLAN_TDLS
6493
6494 /* A Mutex Lock is introduced while changing/initializing the mode to
6495 * protect the concurrent access for the Adapters by TDLS module.
6496 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306497 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306498#endif
6499
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 hdd_remove_adapter( pHddCtx, pAdapterNode );
6501 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006502 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006503
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306504#ifdef FEATURE_WLAN_TDLS
6505 mutex_unlock(&pHddCtx->tdls_lock);
6506#endif
6507
Jeff Johnson295189b2012-06-20 16:38:30 -07006508
6509 /* If there is a single session of STA/P2P client, re-enable BMPS */
6510 if ((!vos_concurrent_sessions_running()) &&
6511 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6512 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6513 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306514 if (pHddCtx->hdd_wlan_suspended)
6515 {
6516 hdd_set_pwrparams(pHddCtx);
6517 }
6518 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 }
6520
6521 return VOS_STATUS_SUCCESS;
6522 }
6523
6524 return VOS_STATUS_E_FAILURE;
6525}
6526
6527VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6528{
6529 hdd_adapter_list_node_t *pHddAdapterNode;
6530 VOS_STATUS status;
6531
6532 ENTER();
6533
6534 do
6535 {
6536 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6537 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6538 {
6539 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6540 vos_mem_free( pHddAdapterNode );
6541 }
6542 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6543
6544 EXIT();
6545
6546 return VOS_STATUS_SUCCESS;
6547}
6548
6549void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6550{
6551 v_U8_t addIE[1] = {0};
6552
6553 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6554 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6555 eANI_BOOLEAN_FALSE) )
6556 {
6557 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006558 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 }
6560
6561 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6562 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6563 eANI_BOOLEAN_FALSE) )
6564 {
6565 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006566 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 }
6568
6569 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6570 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6571 eANI_BOOLEAN_FALSE) )
6572 {
6573 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006574 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006575 }
6576}
6577
6578VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6579{
6580 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6581 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6582 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306583 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306584 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006585
6586 ENTER();
6587
6588 switch(pAdapter->device_mode)
6589 {
6590 case WLAN_HDD_INFRA_STATION:
6591 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006592 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306593 {
6594 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6595 if( hdd_connIsConnected(pstation) ||
6596 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 {
6598 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6599 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6600 pAdapter->sessionId,
6601 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6602 else
6603 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6604 pAdapter->sessionId,
6605 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6606 //success implies disconnect command got queued up successfully
6607 if(halStatus == eHAL_STATUS_SUCCESS)
6608 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306609 ret = wait_for_completion_interruptible_timeout(
6610 &pAdapter->disconnect_comp_var,
6611 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6612 if (ret <= 0)
6613 {
6614 hddLog(VOS_TRACE_LEVEL_ERROR,
6615 "%s: wait on disconnect_comp_var failed %ld",
6616 __func__, ret);
6617 }
6618 }
6619 else
6620 {
6621 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6622 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 }
6624 memset(&wrqu, '\0', sizeof(wrqu));
6625 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6626 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6627 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6628 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306629 else if(pstation->conn_info.connState ==
6630 eConnectionState_Disconnecting)
6631 {
6632 ret = wait_for_completion_interruptible_timeout(
6633 &pAdapter->disconnect_comp_var,
6634 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6635 if (ret <= 0)
6636 {
6637 hddLog(VOS_TRACE_LEVEL_ERROR,
6638 FL("wait on disconnect_comp_var failed %ld"), ret);
6639 }
6640 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006641 else
6642 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306643 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6644 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306646 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6647 {
6648 while (pAdapter->is_roc_inprogress)
6649 {
6650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6651 "%s: ROC in progress for session %d!!!",
6652 __func__, pAdapter->sessionId);
6653 // waiting for ROC to expire
6654 msleep(500);
6655 /* In GO present case , if retry exceeds 3,
6656 it means something went wrong. */
6657 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6658 {
6659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6660 "%s: ROC completion is not received.!!!", __func__);
6661 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6662 pAdapter->sessionId);
6663 wait_for_completion_interruptible_timeout(
6664 &pAdapter->cancel_rem_on_chan_var,
6665 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6666 break;
6667 }
6668 }
6669 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306670#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306671#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306672 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6673#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306674 if (pAdapter->ipv6_notifier_registered)
6675 {
6676 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6677 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6678 pAdapter->ipv6_notifier_registered = false;
6679 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306680#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306681 if (pAdapter->ipv4_notifier_registered)
6682 {
6683 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6684 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6685 pAdapter->ipv4_notifier_registered = false;
6686 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306687#ifdef WLAN_OPEN_SOURCE
6688 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6689#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6691 {
6692 INIT_COMPLETION(pAdapter->session_close_comp_var);
6693 if (eHAL_STATUS_SUCCESS ==
6694 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6695 hdd_smeCloseSessionCallback, pAdapter))
6696 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306697 unsigned long ret;
6698
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306700 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 &pAdapter->session_close_comp_var,
6702 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306703 if ( 0 >= ret)
6704 {
6705 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6706 __func__, ret);
6707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 }
6709 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306710 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 break;
6712
6713 case WLAN_HDD_SOFTAP:
6714 case WLAN_HDD_P2P_GO:
6715 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306716 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6717 while (pAdapter->is_roc_inprogress) {
6718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6719 "%s: ROC in progress for session %d!!!",
6720 __func__, pAdapter->sessionId);
6721 msleep(500);
6722 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6724 "%s: ROC completion is not received.!!!", __func__);
6725 WLANSAP_CancelRemainOnChannel(
6726 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6727 wait_for_completion_interruptible_timeout(
6728 &pAdapter->cancel_rem_on_chan_var,
6729 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6730 break;
6731 }
6732 }
6733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 mutex_lock(&pHddCtx->sap_lock);
6735 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6736 {
6737 VOS_STATUS status;
6738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6739
6740 //Stop Bss.
6741 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6742 if (VOS_IS_STATUS_SUCCESS(status))
6743 {
6744 hdd_hostapd_state_t *pHostapdState =
6745 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6746
6747 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6748
6749 if (!VOS_IS_STATUS_SUCCESS(status))
6750 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306751 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6752 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006753 }
6754 }
6755 else
6756 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006757 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 }
6759 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6760
6761 if (eHAL_STATUS_FAILURE ==
6762 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6763 0, NULL, eANI_BOOLEAN_FALSE))
6764 {
6765 hddLog(LOGE,
6766 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006767 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 }
6769
6770 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6771 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6772 eANI_BOOLEAN_FALSE) )
6773 {
6774 hddLog(LOGE,
6775 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6776 }
6777
6778 // Reset WNI_CFG_PROBE_RSP Flags
6779 wlan_hdd_reset_prob_rspies(pAdapter);
6780 kfree(pAdapter->sessionCtx.ap.beacon);
6781 pAdapter->sessionCtx.ap.beacon = NULL;
6782 }
6783 mutex_unlock(&pHddCtx->sap_lock);
6784 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006785
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006787#ifdef WLAN_OPEN_SOURCE
6788 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6789#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006791
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 default:
6793 break;
6794 }
6795
6796 EXIT();
6797 return VOS_STATUS_SUCCESS;
6798}
6799
6800VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6801{
6802 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6803 VOS_STATUS status;
6804 hdd_adapter_t *pAdapter;
6805
6806 ENTER();
6807
6808 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6809
6810 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6811 {
6812 pAdapter = pAdapterNode->pAdapter;
6813 netif_tx_disable(pAdapter->dev);
6814 netif_carrier_off(pAdapter->dev);
6815
6816 hdd_stop_adapter( pHddCtx, pAdapter );
6817
6818 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6819 pAdapterNode = pNext;
6820 }
6821
6822 EXIT();
6823
6824 return VOS_STATUS_SUCCESS;
6825}
6826
Rajeev Kumarf999e582014-01-09 17:33:29 -08006827
6828#ifdef FEATURE_WLAN_BATCH_SCAN
6829/**---------------------------------------------------------------------------
6830
6831 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6832 structures
6833
6834 \param - pAdapter Pointer to HDD adapter
6835
6836 \return - None
6837
6838 --------------------------------------------------------------------------*/
6839void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6840{
6841 tHddBatchScanRsp *pNode;
6842 tHddBatchScanRsp *pPrev;
6843
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306844 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006845 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306846 hddLog(VOS_TRACE_LEVEL_ERROR,
6847 "%s: Adapter context is Null", __func__);
6848 return;
6849 }
6850
6851 pNode = pAdapter->pBatchScanRsp;
6852 while (pNode)
6853 {
6854 pPrev = pNode;
6855 pNode = pNode->pNext;
6856 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006857 }
6858
6859 pAdapter->pBatchScanRsp = NULL;
6860 pAdapter->numScanList = 0;
6861 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6862 pAdapter->prev_batch_id = 0;
6863
6864 return;
6865}
6866#endif
6867
6868
Jeff Johnson295189b2012-06-20 16:38:30 -07006869VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6870{
6871 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6872 VOS_STATUS status;
6873 hdd_adapter_t *pAdapter;
6874
6875 ENTER();
6876
6877 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6878
6879 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6880 {
6881 pAdapter = pAdapterNode->pAdapter;
6882 netif_tx_disable(pAdapter->dev);
6883 netif_carrier_off(pAdapter->dev);
6884
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006885 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6886
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306888 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6889 {
6890 hdd_wmm_adapter_close( pAdapter );
6891 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006893
Rajeev Kumarf999e582014-01-09 17:33:29 -08006894#ifdef FEATURE_WLAN_BATCH_SCAN
6895 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6896 {
6897 hdd_deinit_batch_scan(pAdapter);
6898 }
6899#endif
6900
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6902 pAdapterNode = pNext;
6903 }
6904
6905 EXIT();
6906
6907 return VOS_STATUS_SUCCESS;
6908}
6909
6910VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6911{
6912 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6913 VOS_STATUS status;
6914 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306915 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006916
6917 ENTER();
6918
6919 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6920
6921 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6922 {
6923 pAdapter = pAdapterNode->pAdapter;
6924
6925 switch(pAdapter->device_mode)
6926 {
6927 case WLAN_HDD_INFRA_STATION:
6928 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006929 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306930
6931 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6932
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 hdd_init_station_mode(pAdapter);
6934 /* Open the gates for HDD to receive Wext commands */
6935 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006936 pHddCtx->scan_info.mScanPending = FALSE;
6937 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006938
6939 //Trigger the initial scan
6940 hdd_wlan_initial_scan(pAdapter);
6941
6942 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306943 if (eConnectionState_Associated == connState ||
6944 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006945 {
6946 union iwreq_data wrqu;
6947 memset(&wrqu, '\0', sizeof(wrqu));
6948 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6949 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6950 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006951 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006952
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 /* indicate disconnected event to nl80211 */
6954 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6955 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306957 else if (eConnectionState_Connecting == connState)
6958 {
6959 /*
6960 * Indicate connect failure to supplicant if we were in the
6961 * process of connecting
6962 */
6963 cfg80211_connect_result(pAdapter->dev, NULL,
6964 NULL, 0, NULL, 0,
6965 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6966 GFP_KERNEL);
6967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 break;
6969
6970 case WLAN_HDD_SOFTAP:
6971 /* softAP can handle SSR */
6972 break;
6973
6974 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006977 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 break;
6979
6980 case WLAN_HDD_MONITOR:
6981 /* monitor interface start */
6982 break;
6983 default:
6984 break;
6985 }
6986
6987 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6988 pAdapterNode = pNext;
6989 }
6990
6991 EXIT();
6992
6993 return VOS_STATUS_SUCCESS;
6994}
6995
6996VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6997{
6998 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6999 hdd_adapter_t *pAdapter;
7000 VOS_STATUS status;
7001 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307002 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007003
7004 ENTER();
7005
7006 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7007
7008 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7009 {
7010 pAdapter = pAdapterNode->pAdapter;
7011
7012 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7013 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7014 {
7015 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7016 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7017
Abhishek Singhf4669da2014-05-26 15:07:49 +05307018 hddLog(VOS_TRACE_LEVEL_INFO,
7019 "%s: Set HDD connState to eConnectionState_NotConnected",
7020 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7022 init_completion(&pAdapter->disconnect_comp_var);
7023 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7024 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7025
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307026 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 &pAdapter->disconnect_comp_var,
7028 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307029 if (0 >= ret)
7030 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7031 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032
7033 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7034 pHddCtx->isAmpAllowed = VOS_FALSE;
7035 sme_RoamConnect(pHddCtx->hHal,
7036 pAdapter->sessionId, &(pWextState->roamProfile),
7037 &roamId);
7038 }
7039
7040 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7041 pAdapterNode = pNext;
7042 }
7043
7044 EXIT();
7045
7046 return VOS_STATUS_SUCCESS;
7047}
7048
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007049void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7050{
7051 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7052 VOS_STATUS status;
7053 hdd_adapter_t *pAdapter;
7054 hdd_station_ctx_t *pHddStaCtx;
7055 hdd_ap_ctx_t *pHddApCtx;
7056 hdd_hostapd_state_t * pHostapdState;
7057 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7058 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7059 const char *p2pMode = "DEV";
7060 const char *ccMode = "Standalone";
7061 int n;
7062
7063 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7064 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7065 {
7066 pAdapter = pAdapterNode->pAdapter;
7067 switch (pAdapter->device_mode) {
7068 case WLAN_HDD_INFRA_STATION:
7069 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7070 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7071 staChannel = pHddStaCtx->conn_info.operationChannel;
7072 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7073 }
7074 break;
7075 case WLAN_HDD_P2P_CLIENT:
7076 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7077 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7078 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7079 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7080 p2pMode = "CLI";
7081 }
7082 break;
7083 case WLAN_HDD_P2P_GO:
7084 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7085 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7086 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7087 p2pChannel = pHddApCtx->operatingChannel;
7088 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7089 }
7090 p2pMode = "GO";
7091 break;
7092 case WLAN_HDD_SOFTAP:
7093 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7094 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7095 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7096 apChannel = pHddApCtx->operatingChannel;
7097 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7098 }
7099 break;
7100 default:
7101 break;
7102 }
7103 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7104 pAdapterNode = pNext;
7105 }
7106 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7107 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7108 }
7109 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7110 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7111 if (p2pChannel > 0) {
7112 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7113 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7114 }
7115 if (apChannel > 0) {
7116 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7117 apChannel, MAC_ADDR_ARRAY(apBssid));
7118 }
7119
7120 if (p2pChannel > 0 && apChannel > 0) {
7121 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7122 }
7123}
7124
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007125bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007126{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007127 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007128}
7129
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007130/* Once SSR is disabled then it cannot be set. */
7131void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007132{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007133 if (HDD_SSR_DISABLED == isSsrRequired)
7134 return;
7135
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 isSsrRequired = value;
7137}
7138
7139VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7140 hdd_adapter_list_node_t** ppAdapterNode)
7141{
7142 VOS_STATUS status;
7143 spin_lock(&pHddCtx->hddAdapters.lock);
7144 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7145 (hdd_list_node_t**) ppAdapterNode );
7146 spin_unlock(&pHddCtx->hddAdapters.lock);
7147 return status;
7148}
7149
7150VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7151 hdd_adapter_list_node_t* pAdapterNode,
7152 hdd_adapter_list_node_t** pNextAdapterNode)
7153{
7154 VOS_STATUS status;
7155 spin_lock(&pHddCtx->hddAdapters.lock);
7156 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7157 (hdd_list_node_t*) pAdapterNode,
7158 (hdd_list_node_t**)pNextAdapterNode );
7159
7160 spin_unlock(&pHddCtx->hddAdapters.lock);
7161 return status;
7162}
7163
7164VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7165 hdd_adapter_list_node_t* pAdapterNode)
7166{
7167 VOS_STATUS status;
7168 spin_lock(&pHddCtx->hddAdapters.lock);
7169 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7170 &pAdapterNode->node );
7171 spin_unlock(&pHddCtx->hddAdapters.lock);
7172 return status;
7173}
7174
7175VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7176 hdd_adapter_list_node_t** ppAdapterNode)
7177{
7178 VOS_STATUS status;
7179 spin_lock(&pHddCtx->hddAdapters.lock);
7180 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7181 (hdd_list_node_t**) ppAdapterNode );
7182 spin_unlock(&pHddCtx->hddAdapters.lock);
7183 return status;
7184}
7185
7186VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7187 hdd_adapter_list_node_t* pAdapterNode)
7188{
7189 VOS_STATUS status;
7190 spin_lock(&pHddCtx->hddAdapters.lock);
7191 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7192 (hdd_list_node_t*) pAdapterNode );
7193 spin_unlock(&pHddCtx->hddAdapters.lock);
7194 return status;
7195}
7196
7197VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7198 hdd_adapter_list_node_t* pAdapterNode)
7199{
7200 VOS_STATUS status;
7201 spin_lock(&pHddCtx->hddAdapters.lock);
7202 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7203 (hdd_list_node_t*) pAdapterNode );
7204 spin_unlock(&pHddCtx->hddAdapters.lock);
7205 return status;
7206}
7207
7208hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7209 tSirMacAddr macAddr )
7210{
7211 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7212 hdd_adapter_t *pAdapter;
7213 VOS_STATUS status;
7214
7215 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7216
7217 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7218 {
7219 pAdapter = pAdapterNode->pAdapter;
7220
7221 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7222 macAddr, sizeof(tSirMacAddr) ) )
7223 {
7224 return pAdapter;
7225 }
7226 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7227 pAdapterNode = pNext;
7228 }
7229
7230 return NULL;
7231
7232}
7233
7234hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7235{
7236 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7237 hdd_adapter_t *pAdapter;
7238 VOS_STATUS status;
7239
7240 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7241
7242 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7243 {
7244 pAdapter = pAdapterNode->pAdapter;
7245
7246 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7247 IFNAMSIZ ) )
7248 {
7249 return pAdapter;
7250 }
7251 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7252 pAdapterNode = pNext;
7253 }
7254
7255 return NULL;
7256
7257}
7258
7259hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7260{
7261 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7262 hdd_adapter_t *pAdapter;
7263 VOS_STATUS status;
7264
7265 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7266
7267 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7268 {
7269 pAdapter = pAdapterNode->pAdapter;
7270
7271 if( pAdapter && (mode == pAdapter->device_mode) )
7272 {
7273 return pAdapter;
7274 }
7275 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7276 pAdapterNode = pNext;
7277 }
7278
7279 return NULL;
7280
7281}
7282
7283//Remove this function later
7284hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7285{
7286 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7287 hdd_adapter_t *pAdapter;
7288 VOS_STATUS status;
7289
7290 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7291
7292 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7293 {
7294 pAdapter = pAdapterNode->pAdapter;
7295
7296 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7297 {
7298 return pAdapter;
7299 }
7300
7301 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7302 pAdapterNode = pNext;
7303 }
7304
7305 return NULL;
7306
7307}
7308
Jeff Johnson295189b2012-06-20 16:38:30 -07007309/**---------------------------------------------------------------------------
7310
7311 \brief hdd_set_monitor_tx_adapter() -
7312
7313 This API initializes the adapter to be used while transmitting on monitor
7314 adapter.
7315
7316 \param - pHddCtx - Pointer to the HDD context.
7317 pAdapter - Adapter that will used for TX. This can be NULL.
7318 \return - None.
7319 --------------------------------------------------------------------------*/
7320void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7321{
7322 hdd_adapter_t *pMonAdapter;
7323
7324 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7325
7326 if( NULL != pMonAdapter )
7327 {
7328 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7329 }
7330}
Jeff Johnson295189b2012-06-20 16:38:30 -07007331/**---------------------------------------------------------------------------
7332
7333 \brief hdd_select_queue() -
7334
7335 This API returns the operating channel of the requested device mode
7336
7337 \param - pHddCtx - Pointer to the HDD context.
7338 - mode - Device mode for which operating channel is required
7339 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7340 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7341 \return - channel number. "0" id the requested device is not found OR it is not connected.
7342 --------------------------------------------------------------------------*/
7343v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7344{
7345 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7346 VOS_STATUS status;
7347 hdd_adapter_t *pAdapter;
7348 v_U8_t operatingChannel = 0;
7349
7350 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7351
7352 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7353 {
7354 pAdapter = pAdapterNode->pAdapter;
7355
7356 if( mode == pAdapter->device_mode )
7357 {
7358 switch(pAdapter->device_mode)
7359 {
7360 case WLAN_HDD_INFRA_STATION:
7361 case WLAN_HDD_P2P_CLIENT:
7362 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7363 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7364 break;
7365 case WLAN_HDD_SOFTAP:
7366 case WLAN_HDD_P2P_GO:
7367 /*softap connection info */
7368 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7369 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7370 break;
7371 default:
7372 break;
7373 }
7374
7375 break; //Found the device of interest. break the loop
7376 }
7377
7378 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7379 pAdapterNode = pNext;
7380 }
7381 return operatingChannel;
7382}
7383
7384#ifdef WLAN_FEATURE_PACKET_FILTERING
7385/**---------------------------------------------------------------------------
7386
7387 \brief hdd_set_multicast_list() -
7388
7389 This used to set the multicast address list.
7390
7391 \param - dev - Pointer to the WLAN device.
7392 - skb - Pointer to OS packet (sk_buff).
7393 \return - success/fail
7394
7395 --------------------------------------------------------------------------*/
7396static void hdd_set_multicast_list(struct net_device *dev)
7397{
7398 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 int mc_count;
7400 int i = 0;
7401 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307402
7403 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 {
7405 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307406 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 return;
7408 }
7409
7410 if (dev->flags & IFF_ALLMULTI)
7411 {
7412 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007413 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307414 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 }
7416 else
7417 {
7418 mc_count = netdev_mc_count(dev);
7419 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007420 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7422 {
7423 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007424 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307425 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 return;
7427 }
7428
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307429 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007430
7431 netdev_for_each_mc_addr(ha, dev) {
7432 if (i == mc_count)
7433 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307434 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7435 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007437 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307438 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 i++;
7440 }
7441 }
7442 return;
7443}
7444#endif
7445
7446/**---------------------------------------------------------------------------
7447
7448 \brief hdd_select_queue() -
7449
7450 This function is registered with the Linux OS for network
7451 core to decide which queue to use first.
7452
7453 \param - dev - Pointer to the WLAN device.
7454 - skb - Pointer to OS packet (sk_buff).
7455 \return - ac, Queue Index/access category corresponding to UP in IP header
7456
7457 --------------------------------------------------------------------------*/
7458v_U16_t hdd_select_queue(struct net_device *dev,
7459 struct sk_buff *skb)
7460{
7461 return hdd_wmm_select_queue(dev, skb);
7462}
7463
7464
7465/**---------------------------------------------------------------------------
7466
7467 \brief hdd_wlan_initial_scan() -
7468
7469 This function triggers the initial scan
7470
7471 \param - pAdapter - Pointer to the HDD adapter.
7472
7473 --------------------------------------------------------------------------*/
7474void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7475{
7476 tCsrScanRequest scanReq;
7477 tCsrChannelInfo channelInfo;
7478 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007479 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7481
7482 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7483 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7484 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7485
7486 if(sme_Is11dSupported(pHddCtx->hHal))
7487 {
7488 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7489 if ( HAL_STATUS_SUCCESS( halStatus ) )
7490 {
7491 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7492 if( !scanReq.ChannelInfo.ChannelList )
7493 {
7494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7495 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007496 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 return;
7498 }
7499 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7500 channelInfo.numOfChannels);
7501 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7502 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007503 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007504 }
7505
7506 scanReq.scanType = eSIR_PASSIVE_SCAN;
7507 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7508 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7509 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7510 }
7511 else
7512 {
7513 scanReq.scanType = eSIR_ACTIVE_SCAN;
7514 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7515 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7516 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7517 }
7518
7519 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7520 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7521 {
7522 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7523 __func__, halStatus );
7524 }
7525
7526 if(sme_Is11dSupported(pHddCtx->hHal))
7527 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7528}
7529
Jeff Johnson295189b2012-06-20 16:38:30 -07007530/**---------------------------------------------------------------------------
7531
7532 \brief hdd_full_power_callback() - HDD full power callback function
7533
7534 This is the function invoked by SME to inform the result of a full power
7535 request issued by HDD
7536
7537 \param - callbackcontext - Pointer to cookie
7538 \param - status - result of request
7539
7540 \return - None
7541
7542 --------------------------------------------------------------------------*/
7543static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7544{
Jeff Johnson72a40512013-12-19 10:14:15 -08007545 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007546
7547 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307548 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007549
7550 if (NULL == callbackContext)
7551 {
7552 hddLog(VOS_TRACE_LEVEL_ERROR,
7553 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007554 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007555 return;
7556 }
7557
Jeff Johnson72a40512013-12-19 10:14:15 -08007558 /* there is a race condition that exists between this callback
7559 function and the caller since the caller could time out either
7560 before or while this code is executing. we use a spinlock to
7561 serialize these actions */
7562 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007563
7564 if (POWER_CONTEXT_MAGIC != pContext->magic)
7565 {
7566 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007567 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 hddLog(VOS_TRACE_LEVEL_WARN,
7569 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007570 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 return;
7572 }
7573
Jeff Johnson72a40512013-12-19 10:14:15 -08007574 /* context is valid so caller is still waiting */
7575
7576 /* paranoia: invalidate the magic */
7577 pContext->magic = 0;
7578
7579 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007581
7582 /* serialization is complete */
7583 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007584}
7585
7586/**---------------------------------------------------------------------------
7587
7588 \brief hdd_wlan_exit() - HDD WLAN exit function
7589
7590 This is the driver exit point (invoked during rmmod)
7591
7592 \param - pHddCtx - Pointer to the HDD Context
7593
7594 \return - None
7595
7596 --------------------------------------------------------------------------*/
7597void hdd_wlan_exit(hdd_context_t *pHddCtx)
7598{
7599 eHalStatus halStatus;
7600 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7601 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307602 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007603 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007604 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307606 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007607
7608 ENTER();
7609
Jeff Johnson88ba7742013-02-27 14:36:02 -08007610 if (VOS_FTM_MODE != hdd_get_conparam())
7611 {
7612 // Unloading, restart logic is no more required.
7613 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007614
c_hpothu5ab05e92014-06-13 17:34:05 +05307615 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7616 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307618 pAdapter = pAdapterNode->pAdapter;
7619 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007620 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307621 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7622 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7623 {
7624 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7625 hdd_UnregisterWext(pAdapter->dev);
7626 }
7627 // Cancel any outstanding scan requests. We are about to close all
7628 // of our adapters, but an adapter structure is what SME passes back
7629 // to our callback function. Hence if there are any outstanding scan
7630 // requests then there is a race condition between when the adapter
7631 // is closed and when the callback is invoked.We try to resolve that
7632 // race condition here by canceling any outstanding scans before we
7633 // close the adapters.
7634 // Note that the scans may be cancelled in an asynchronous manner,
7635 // so ideally there needs to be some kind of synchronization. Rather
7636 // than introduce a new synchronization here, we will utilize the
7637 // fact that we are about to Request Full Power, and since that is
7638 // synchronized, the expectation is that by the time Request Full
7639 // Power has completed all scans will be cancelled.
7640 if (pHddCtx->scan_info.mScanPending)
7641 {
7642 hddLog(VOS_TRACE_LEVEL_INFO,
7643 FL("abort scan mode: %d sessionId: %d"),
7644 pAdapter->device_mode,
7645 pAdapter->sessionId);
7646 hdd_abort_mac_scan(pHddCtx,
7647 pAdapter->sessionId,
7648 eCSR_SCAN_ABORT_DEFAULT);
7649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307651 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7652 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 }
7654 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307655 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007656 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307657 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007658 wlan_hdd_ftm_close(pHddCtx);
7659 goto free_hdd_ctx;
7660 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307661
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 /* DeRegister with platform driver as client for Suspend/Resume */
7663 vosStatus = hddDeregisterPmOps(pHddCtx);
7664 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7665 {
7666 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7667 VOS_ASSERT(0);
7668 }
7669
7670 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7671 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7672 {
7673 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007675
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007676 //Stop the traffic monitor timer
7677 if ( VOS_TIMER_STATE_RUNNING ==
7678 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7679 {
7680 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7681 }
7682
7683 // Destroy the traffic monitor timer
7684 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7685 &pHddCtx->tx_rx_trafficTmr)))
7686 {
7687 hddLog(VOS_TRACE_LEVEL_ERROR,
7688 "%s: Cannot deallocate Traffic monitor timer", __func__);
7689 }
7690
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 //Disable IMPS/BMPS as we do not want the device to enter any power
7692 //save mode during shutdown
7693 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7694 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7695 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7696
7697 //Ensure that device is in full power as we will touch H/W during vos_Stop
7698 init_completion(&powerContext.completion);
7699 powerContext.magic = POWER_CONTEXT_MAGIC;
7700
7701 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7702 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7703
7704 if (eHAL_STATUS_SUCCESS != halStatus)
7705 {
7706 if (eHAL_STATUS_PMC_PENDING == halStatus)
7707 {
7708 /* request was sent -- wait for the response */
7709 lrc = wait_for_completion_interruptible_timeout(
7710 &powerContext.completion,
7711 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 if (lrc <= 0)
7713 {
7714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007715 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 }
7717 }
7718 else
7719 {
7720 hddLog(VOS_TRACE_LEVEL_ERROR,
7721 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007722 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007723 /* continue -- need to clean up as much as possible */
7724 }
7725 }
7726
Jeff Johnson72a40512013-12-19 10:14:15 -08007727 /* either we never sent a request, we sent a request and received a
7728 response or we sent a request and timed out. if we never sent a
7729 request or if we sent a request and got a response, we want to
7730 clear the magic out of paranoia. if we timed out there is a
7731 race condition such that the callback function could be
7732 executing at the same time we are. of primary concern is if the
7733 callback function had already verified the "magic" but had not
7734 yet set the completion variable when a timeout occurred. we
7735 serialize these activities by invalidating the magic while
7736 holding a shared spinlock which will cause us to block if the
7737 callback is currently executing */
7738 spin_lock(&hdd_context_lock);
7739 powerContext.magic = 0;
7740 spin_unlock(&hdd_context_lock);
7741
Yue Ma0d4891e2013-08-06 17:01:45 -07007742 hdd_debugfs_exit(pHddCtx);
7743
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 // Unregister the Net Device Notifier
7745 unregister_netdevice_notifier(&hdd_netdev_notifier);
7746
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 hdd_stop_all_adapters( pHddCtx );
7748
Jeff Johnson295189b2012-06-20 16:38:30 -07007749#ifdef WLAN_BTAMP_FEATURE
7750 vosStatus = WLANBAP_Stop(pVosContext);
7751 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7752 {
7753 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7754 "%s: Failed to stop BAP",__func__);
7755 }
7756#endif //WLAN_BTAMP_FEATURE
7757
7758 //Stop all the modules
7759 vosStatus = vos_stop( pVosContext );
7760 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7761 {
7762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7763 "%s: Failed to stop VOSS",__func__);
7764 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7765 }
7766
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 //Assert Deep sleep signal now to put Libra HW in lowest power state
7768 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7769 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7770
7771 //Vote off any PMIC voltage supplies
7772 vos_chipPowerDown(NULL, NULL, NULL);
7773
7774 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7775
Leo Chang59cdc7e2013-07-10 10:08:21 -07007776
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007778 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007779
7780 //Close the scheduler before calling vos_close to make sure no thread is
7781 // scheduled after the each module close is called i.e after all the data
7782 // structures are freed.
7783 vosStatus = vos_sched_close( pVosContext );
7784 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7785 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7786 "%s: Failed to close VOSS Scheduler",__func__);
7787 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7788 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007789#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007790#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7791 /* Destroy the wake lock */
7792 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7793#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007794 /* Destroy the wake lock */
7795 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007796#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007797
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307798#ifdef CONFIG_ENABLE_LINUX_REG
7799 vosStatus = vos_nv_close();
7800 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7801 {
7802 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7803 "%s: Failed to close NV", __func__);
7804 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7805 }
7806#endif
7807
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 //Close VOSS
7809 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7810 vos_close(pVosContext);
7811
Jeff Johnson295189b2012-06-20 16:38:30 -07007812 //Close Watchdog
7813 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7814 vos_watchdog_close(pVosContext);
7815
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307816 //Clean up HDD Nlink Service
7817 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007818#ifdef WLAN_KD_READY_NOTIFIER
7819 nl_srv_exit(pHddCtx->ptt_pid);
7820#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307821 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007822#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307823
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307824#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307825 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307826 {
7827 wlan_logging_sock_deactivate_svc();
7828 }
7829#endif
7830
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 /* Cancel the vote for XO Core ON.
7832 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7833 * exited at this point
7834 */
7835 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007836 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7838 {
7839 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7840 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007841 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 }
7843
7844 hdd_close_all_adapters( pHddCtx );
7845
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 /* free the power on lock from platform driver */
7847 if (free_riva_power_on_lock("wlan"))
7848 {
7849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7850 __func__);
7851 }
7852
Jeff Johnson88ba7742013-02-27 14:36:02 -08007853free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307854
7855 //Free up dynamically allocated members inside HDD Adapter
7856 if (pHddCtx->cfg_ini)
7857 {
7858 kfree(pHddCtx->cfg_ini);
7859 pHddCtx->cfg_ini= NULL;
7860 }
7861
Leo Changf04ddad2013-09-18 13:46:38 -07007862 /* FTM mode, WIPHY did not registered
7863 If un-register here, system crash will happen */
7864 if (VOS_FTM_MODE != hdd_get_conparam())
7865 {
7866 wiphy_unregister(wiphy) ;
7867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 if (hdd_is_ssr_required())
7870 {
7871 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007872 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 msleep(5000);
7874 }
7875 hdd_set_ssr_required (VOS_FALSE);
7876}
7877
7878
7879/**---------------------------------------------------------------------------
7880
7881 \brief hdd_update_config_from_nv() - Function to update the contents of
7882 the running configuration with parameters taken from NV storage
7883
7884 \param - pHddCtx - Pointer to the HDD global context
7885
7886 \return - VOS_STATUS_SUCCESS if successful
7887
7888 --------------------------------------------------------------------------*/
7889static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7890{
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 v_BOOL_t itemIsValid = VOS_FALSE;
7892 VOS_STATUS status;
7893 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7894 v_U8_t macLoop;
7895
7896 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7897 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7898 if(status != VOS_STATUS_SUCCESS)
7899 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007900 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 return VOS_STATUS_E_FAILURE;
7902 }
7903
7904 if (itemIsValid == VOS_TRUE)
7905 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007906 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7908 VOS_MAX_CONCURRENCY_PERSONA);
7909 if(status != VOS_STATUS_SUCCESS)
7910 {
7911 /* Get MAC from NV fail, not update CFG info
7912 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007913 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 return VOS_STATUS_E_FAILURE;
7915 }
7916
7917 /* If first MAC is not valid, treat all others are not valid
7918 * Then all MACs will be got from ini file */
7919 if(vos_is_macaddr_zero(&macFromNV[0]))
7920 {
7921 /* MAC address in NV file is not configured yet */
7922 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7923 return VOS_STATUS_E_INVAL;
7924 }
7925
7926 /* Get MAC address from NV, update CFG info */
7927 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7928 {
7929 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7930 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307931 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 /* This MAC is not valid, skip it
7933 * This MAC will be got from ini file */
7934 }
7935 else
7936 {
7937 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7938 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7939 VOS_MAC_ADDR_SIZE);
7940 }
7941 }
7942 }
7943 else
7944 {
7945 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7946 return VOS_STATUS_E_FAILURE;
7947 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007948
Jeff Johnson295189b2012-06-20 16:38:30 -07007949
7950 return VOS_STATUS_SUCCESS;
7951}
7952
7953/**---------------------------------------------------------------------------
7954
7955 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7956
7957 \param - pAdapter - Pointer to the HDD
7958
7959 \return - None
7960
7961 --------------------------------------------------------------------------*/
7962VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7963{
7964 eHalStatus halStatus;
7965 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307966 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007967
Jeff Johnson295189b2012-06-20 16:38:30 -07007968
7969 // Send ready indication to the HDD. This will kick off the MAC
7970 // into a 'running' state and should kick off an initial scan.
7971 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7972 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7973 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307974 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 "code %08d [x%08x]",__func__, halStatus, halStatus );
7976 return VOS_STATUS_E_FAILURE;
7977 }
7978
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307979 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7981 // And RIVA will crash
7982 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7983 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307984 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7985 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7986
7987
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 return VOS_STATUS_SUCCESS;
7989}
7990
Jeff Johnson295189b2012-06-20 16:38:30 -07007991/* wake lock APIs for HDD */
7992void hdd_prevent_suspend(void)
7993{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007994#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007996#else
7997 wcnss_prevent_suspend();
7998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007999}
8000
8001void hdd_allow_suspend(void)
8002{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008003#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008005#else
8006 wcnss_allow_suspend();
8007#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008008}
8009
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308010void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008011{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008012#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008013 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008014#else
8015 /* Do nothing as there is no API in wcnss for timeout*/
8016#endif
8017}
8018
Jeff Johnson295189b2012-06-20 16:38:30 -07008019/**---------------------------------------------------------------------------
8020
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008021 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8022 information between Host and Riva
8023
8024 This function gets reported version of FW
8025 It also finds the version of Riva headers used to compile the host
8026 It compares the above two and prints a warning if they are different
8027 It gets the SW and HW version string
8028 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8029 indicating the features they support through a bitmap
8030
8031 \param - pHddCtx - Pointer to HDD context
8032
8033 \return - void
8034
8035 --------------------------------------------------------------------------*/
8036
8037void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8038{
8039
8040 tSirVersionType versionCompiled;
8041 tSirVersionType versionReported;
8042 tSirVersionString versionString;
8043 tANI_U8 fwFeatCapsMsgSupported = 0;
8044 VOS_STATUS vstatus;
8045
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008046 memset(&versionCompiled, 0, sizeof(versionCompiled));
8047 memset(&versionReported, 0, sizeof(versionReported));
8048
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008049 /* retrieve and display WCNSS version information */
8050 do {
8051
8052 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8053 &versionCompiled);
8054 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8055 {
8056 hddLog(VOS_TRACE_LEVEL_FATAL,
8057 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008058 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008059 break;
8060 }
8061
8062 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8063 &versionReported);
8064 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8065 {
8066 hddLog(VOS_TRACE_LEVEL_FATAL,
8067 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008068 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008069 break;
8070 }
8071
8072 if ((versionCompiled.major != versionReported.major) ||
8073 (versionCompiled.minor != versionReported.minor) ||
8074 (versionCompiled.version != versionReported.version) ||
8075 (versionCompiled.revision != versionReported.revision))
8076 {
8077 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8078 "Host expected %u.%u.%u.%u\n",
8079 WLAN_MODULE_NAME,
8080 (int)versionReported.major,
8081 (int)versionReported.minor,
8082 (int)versionReported.version,
8083 (int)versionReported.revision,
8084 (int)versionCompiled.major,
8085 (int)versionCompiled.minor,
8086 (int)versionCompiled.version,
8087 (int)versionCompiled.revision);
8088 }
8089 else
8090 {
8091 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8092 WLAN_MODULE_NAME,
8093 (int)versionReported.major,
8094 (int)versionReported.minor,
8095 (int)versionReported.version,
8096 (int)versionReported.revision);
8097 }
8098
8099 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8100 versionString,
8101 sizeof(versionString));
8102 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8103 {
8104 hddLog(VOS_TRACE_LEVEL_FATAL,
8105 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008106 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008107 break;
8108 }
8109
8110 pr_info("%s: WCNSS software version %s\n",
8111 WLAN_MODULE_NAME, versionString);
8112
8113 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8114 versionString,
8115 sizeof(versionString));
8116 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8117 {
8118 hddLog(VOS_TRACE_LEVEL_FATAL,
8119 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008120 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008121 break;
8122 }
8123
8124 pr_info("%s: WCNSS hardware version %s\n",
8125 WLAN_MODULE_NAME, versionString);
8126
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008127 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8128 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008129 send the message only if it the riva is 1.1
8130 minor numbers for different riva branches:
8131 0 -> (1.0)Mainline Build
8132 1 -> (1.1)Mainline Build
8133 2->(1.04) Stability Build
8134 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008135 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008136 ((versionReported.minor>=1) && (versionReported.version>=1)))
8137 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8138 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008139
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008140 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008141 {
8142#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8143 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8144 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8145#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008146 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8147 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8148 {
8149 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8150 }
8151
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008152 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008153 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008154
8155 } while (0);
8156
8157}
8158
8159/**---------------------------------------------------------------------------
8160
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308161 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8162
8163 \param - pHddCtx - Pointer to the hdd context
8164
8165 \return - true if hardware supports 5GHz
8166
8167 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308168boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308169{
8170 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8171 * then hardware support 5Ghz.
8172 */
8173 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8174 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308176 return true;
8177 }
8178 else
8179 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308180 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308181 __func__);
8182 return false;
8183 }
8184}
8185
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308186/**---------------------------------------------------------------------------
8187
8188 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8189 generate function
8190
8191 This is generate the random mac address for WLAN interface
8192
8193 \param - pHddCtx - Pointer to HDD context
8194 idx - Start interface index to get auto
8195 generated mac addr.
8196 mac_addr - Mac address
8197
8198 \return - 0 for success, < 0 for failure
8199
8200 --------------------------------------------------------------------------*/
8201
8202static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8203 int idx, v_MACADDR_t mac_addr)
8204{
8205 int i;
8206 unsigned int serialno;
8207 serialno = wcnss_get_serial_number();
8208
8209 if (0 != serialno)
8210 {
8211 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8212 bytes of the serial number that can be used to generate
8213 the other 3 bytes of the MAC address. Mask off all but
8214 the lower 3 bytes (this will also make sure we don't
8215 overflow in the next step) */
8216 serialno &= 0x00FFFFFF;
8217
8218 /* we need a unique address for each session */
8219 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8220
8221 /* autogen other Mac addresses */
8222 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8223 {
8224 /* start with the entire default address */
8225 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8226 /* then replace the lower 3 bytes */
8227 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8228 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8229 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8230
8231 serialno++;
8232 hddLog(VOS_TRACE_LEVEL_ERROR,
8233 "%s: Derived Mac Addr: "
8234 MAC_ADDRESS_STR, __func__,
8235 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8236 }
8237
8238 }
8239 else
8240 {
8241 hddLog(LOGE, FL("Failed to Get Serial NO"));
8242 return -1;
8243 }
8244 return 0;
8245}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308246
8247/**---------------------------------------------------------------------------
8248
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308249 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8250 completed to flush out the scan results
8251
8252 11d scan is done during driver load and is a passive scan on all
8253 channels supported by the device, 11d scans may find some APs on
8254 frequencies which are forbidden to be used in the regulatory domain
8255 the device is operating in. If these APs are notified to the supplicant
8256 it may try to connect to these APs, thus flush out all the scan results
8257 which are present in SME after 11d scan is done.
8258
8259 \return - eHalStatus
8260
8261 --------------------------------------------------------------------------*/
8262static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8263 tANI_U32 scanId, eCsrScanStatus status)
8264{
8265 ENTER();
8266
8267 sme_ScanFlushResult(halHandle, 0);
8268
8269 EXIT();
8270
8271 return eHAL_STATUS_SUCCESS;
8272}
8273
8274/**---------------------------------------------------------------------------
8275
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 \brief hdd_wlan_startup() - HDD init function
8277
8278 This is the driver startup code executed once a WLAN device has been detected
8279
8280 \param - dev - Pointer to the underlying device
8281
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008282 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008283
8284 --------------------------------------------------------------------------*/
8285
8286int hdd_wlan_startup(struct device *dev )
8287{
8288 VOS_STATUS status;
8289 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008290 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 hdd_context_t *pHddCtx = NULL;
8292 v_CONTEXT_t pVosContext= NULL;
8293#ifdef WLAN_BTAMP_FEATURE
8294 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8295 WLANBAP_ConfigType btAmpConfig;
8296 hdd_config_t *pConfig;
8297#endif
8298 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008299 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308300 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008301
8302 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 /*
8304 * cfg80211: wiphy allocation
8305 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308306 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008307
8308 if(wiphy == NULL)
8309 {
8310 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008311 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 }
8313
8314 pHddCtx = wiphy_priv(wiphy);
8315
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 //Initialize the adapter context to zeros.
8317 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8318
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008320 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308321 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008322
8323 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8324
8325 /*Get vos context here bcoz vos_open requires it*/
8326 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8327
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008328 if(pVosContext == NULL)
8329 {
8330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8331 goto err_free_hdd_context;
8332 }
8333
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 //Save the Global VOSS context in adapter context for future.
8335 pHddCtx->pvosContext = pVosContext;
8336
8337 //Save the adapter context in global context for future.
8338 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8339
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 pHddCtx->parent_dev = dev;
8341
8342 init_completion(&pHddCtx->full_pwr_comp_var);
8343 init_completion(&pHddCtx->standby_comp_var);
8344 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008345 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008346 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308347 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308348 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008349
8350#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008351 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008352#else
8353 init_completion(&pHddCtx->driver_crda_req);
8354#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008355
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308356 spin_lock_init(&pHddCtx->schedScan_lock);
8357
Jeff Johnson295189b2012-06-20 16:38:30 -07008358 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8359
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308360#ifdef FEATURE_WLAN_TDLS
8361 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8362 * invoked by other instances also) to protect the concurrent
8363 * access for the Adapters by TDLS module.
8364 */
8365 mutex_init(&pHddCtx->tdls_lock);
8366#endif
8367
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308368 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 // Load all config first as TL config is needed during vos_open
8370 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8371 if(pHddCtx->cfg_ini == NULL)
8372 {
8373 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8374 goto err_free_hdd_context;
8375 }
8376
8377 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8378
8379 // Read and parse the qcom_cfg.ini file
8380 status = hdd_parse_config_ini( pHddCtx );
8381 if ( VOS_STATUS_SUCCESS != status )
8382 {
8383 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8384 __func__, WLAN_INI_FILE);
8385 goto err_config;
8386 }
Arif Hussaind5218912013-12-05 01:10:55 -08008387#ifdef MEMORY_DEBUG
8388 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8389 vos_mem_init();
8390
8391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8392 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008394
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308395 /* INI has been read, initialise the configuredMcastBcastFilter with
8396 * INI value as this will serve as the default value
8397 */
8398 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8399 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8400 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308401
8402 if (false == hdd_is_5g_supported(pHddCtx))
8403 {
8404 //5Ghz is not supported.
8405 if (1 != pHddCtx->cfg_ini->nBandCapability)
8406 {
8407 hddLog(VOS_TRACE_LEVEL_INFO,
8408 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8409 pHddCtx->cfg_ini->nBandCapability = 1;
8410 }
8411 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308412
8413 /* If SNR Monitoring is enabled, FW has to parse all beacons
8414 * for calcaluting and storing the average SNR, so set Nth beacon
8415 * filter to 1 to enable FW to parse all the beaocons
8416 */
8417 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8418 {
8419 /* The log level is deliberately set to WARN as overriding
8420 * nthBeaconFilter to 1 will increase power cosumption and this
8421 * might just prove helpful to detect the power issue.
8422 */
8423 hddLog(VOS_TRACE_LEVEL_WARN,
8424 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8425 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308428 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008430 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008432 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8433 {
8434 hddLog(VOS_TRACE_LEVEL_FATAL,
8435 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8436 goto err_config;
8437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008439
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008440 // Update VOS trace levels based upon the cfg.ini
8441 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8442 pHddCtx->cfg_ini->vosTraceEnableBAP);
8443 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8444 pHddCtx->cfg_ini->vosTraceEnableTL);
8445 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8446 pHddCtx->cfg_ini->vosTraceEnableWDI);
8447 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8448 pHddCtx->cfg_ini->vosTraceEnableHDD);
8449 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8450 pHddCtx->cfg_ini->vosTraceEnableSME);
8451 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8452 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308453 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8454 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008455 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8456 pHddCtx->cfg_ini->vosTraceEnableWDA);
8457 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8458 pHddCtx->cfg_ini->vosTraceEnableSYS);
8459 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8460 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008461 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8462 pHddCtx->cfg_ini->vosTraceEnableSAP);
8463 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8464 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008465
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 // Update WDI trace levels based upon the cfg.ini
8467 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8468 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8469 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8470 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8471 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8472 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8473 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8474 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008475
Jeff Johnson88ba7742013-02-27 14:36:02 -08008476 if (VOS_FTM_MODE == hdd_get_conparam())
8477 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8479 {
8480 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8481 goto err_free_hdd_context;
8482 }
8483 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308484
8485 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008488
Jeff Johnson88ba7742013-02-27 14:36:02 -08008489 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8491 {
8492 status = vos_watchdog_open(pVosContext,
8493 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8494
8495 if(!VOS_IS_STATUS_SUCCESS( status ))
8496 {
8497 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308498 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 }
8500 }
8501
8502 pHddCtx->isLogpInProgress = FALSE;
8503 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8504
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8506 if(!VOS_IS_STATUS_SUCCESS(status))
8507 {
8508 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 }
8511
Amar Singhala49cbc52013-10-08 18:37:44 -07008512#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008513 /* initialize the NV module. This is required so that
8514 we can initialize the channel information in wiphy
8515 from the NV.bin data. The channel information in
8516 wiphy needs to be initialized before wiphy registration */
8517
8518 status = vos_nv_open();
8519 if (!VOS_IS_STATUS_SUCCESS(status))
8520 {
8521 /* NV module cannot be initialized */
8522 hddLog( VOS_TRACE_LEVEL_FATAL,
8523 "%s: vos_nv_open failed", __func__);
8524 goto err_clkvote;
8525 }
8526
8527 status = vos_init_wiphy_from_nv_bin();
8528 if (!VOS_IS_STATUS_SUCCESS(status))
8529 {
8530 /* NV module cannot be initialized */
8531 hddLog( VOS_TRACE_LEVEL_FATAL,
8532 "%s: vos_init_wiphy failed", __func__);
8533 goto err_vos_nv_close;
8534 }
8535
Amar Singhala49cbc52013-10-08 18:37:44 -07008536#endif
8537
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308538 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008539 if ( !VOS_IS_STATUS_SUCCESS( status ))
8540 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008541 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308542 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008543 }
8544
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8546
8547 if ( NULL == pHddCtx->hHal )
8548 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008549 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 goto err_vosclose;
8551 }
8552
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008553 status = vos_preStart( pHddCtx->pvosContext );
8554 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8555 {
8556 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308557 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008558 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008559
Arif Hussaineaf68602013-12-30 23:10:44 -08008560 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8561 {
8562 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8563 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8564 __func__, enable_dfs_chan_scan);
8565 }
8566 if (0 == enable_11d || 1 == enable_11d)
8567 {
8568 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8569 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8570 __func__, enable_11d);
8571 }
8572
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008573 /* Note that the vos_preStart() sequence triggers the cfg download.
8574 The cfg download must occur before we update the SME config
8575 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 status = hdd_set_sme_config( pHddCtx );
8577
8578 if ( VOS_STATUS_SUCCESS != status )
8579 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008580 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308581 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008583
8584 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008585 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8586 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008587 if (!VOS_IS_STATUS_SUCCESS(status))
8588 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008589 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308590 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 }
8592
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 /* In the integrated architecture we update the configuration from
8594 the INI file and from NV before vOSS has been started so that
8595 the final contents are available to send down to the cCPU */
8596
8597 // Apply the cfg.ini to cfg.dat
8598 if (FALSE == hdd_update_config_dat(pHddCtx))
8599 {
8600 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308601 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 }
8603
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308604 // Get mac addr from platform driver
8605 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8606
8607 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008608 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308609 /* Store the mac addr for first interface */
8610 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8611
8612 hddLog(VOS_TRACE_LEVEL_ERROR,
8613 "%s: WLAN Mac Addr: "
8614 MAC_ADDRESS_STR, __func__,
8615 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8616
8617 /* Here, passing Arg2 as 1 because we do not want to change the
8618 last 3 bytes (means non OUI bytes) of first interface mac
8619 addr.
8620 */
8621 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8622 {
8623 hddLog(VOS_TRACE_LEVEL_ERROR,
8624 "%s: Failed to generate wlan interface mac addr "
8625 "using MAC from ini file ", __func__);
8626 }
8627 }
8628 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8629 {
8630 // Apply the NV to cfg.dat
8631 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008632#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8633 /* There was not a valid set of MAC Addresses in NV. See if the
8634 default addresses were modified by the cfg.ini settings. If so,
8635 we'll use them, but if not, we'll autogenerate a set of MAC
8636 addresses based upon the device serial number */
8637
8638 static const v_MACADDR_t default_address =
8639 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008640
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308641 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8642 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 {
8644 /* cfg.ini has the default address, invoke autogen logic */
8645
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308646 /* Here, passing Arg2 as 0 because we want to change the
8647 last 3 bytes (means non OUI bytes) of all the interfaces
8648 mac addr.
8649 */
8650 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8651 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308653 hddLog(VOS_TRACE_LEVEL_ERROR,
8654 "%s: Failed to generate wlan interface mac addr "
8655 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8656 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 }
8659 else
8660#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8661 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008662 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 "%s: Invalid MAC address in NV, using MAC from ini file "
8664 MAC_ADDRESS_STR, __func__,
8665 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8666 }
8667 }
8668 {
8669 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308670
8671 /* Set the MAC Address Currently this is used by HAL to
8672 * add self sta. Remove this once self sta is added as
8673 * part of session open.
8674 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8676 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8677 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308678
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 if (!HAL_STATUS_SUCCESS( halStatus ))
8680 {
8681 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8682 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308683 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 }
8685 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008686
8687 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8688 Note: Firmware image will be read and downloaded inside vos_start API */
8689 status = vos_start( pHddCtx->pvosContext );
8690 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8691 {
8692 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308693 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 }
8695
Leo Chang6cec3e22014-01-21 15:33:49 -08008696#ifdef FEATURE_WLAN_CH_AVOID
8697 /* Plug in avoid channel notification callback
8698 * This should happen before ADD_SELF_STA
8699 * FW will send first IND with ADD_SELF_STA REQ from host */
8700 sme_AddChAvoidCallback(pHddCtx->hHal,
8701 hdd_hostapd_ch_avoid_cb);
8702#endif /* FEATURE_WLAN_CH_AVOID */
8703
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008704 /* Exchange capability info between Host and FW and also get versioning info from FW */
8705 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008706
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308707#ifdef CONFIG_ENABLE_LINUX_REG
8708 status = wlan_hdd_init_channels(pHddCtx);
8709 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8710 {
8711 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8712 __func__);
8713 goto err_vosstop;
8714 }
8715#endif
8716
Jeff Johnson295189b2012-06-20 16:38:30 -07008717 status = hdd_post_voss_start_config( pHddCtx );
8718 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8719 {
8720 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8721 __func__);
8722 goto err_vosstop;
8723 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008724
8725#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308726 wlan_hdd_cfg80211_update_reg_info( wiphy );
8727
8728 /* registration of wiphy dev with cfg80211 */
8729 if (0 > wlan_hdd_cfg80211_register(wiphy))
8730 {
8731 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8732 goto err_vosstop;
8733 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008735
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308736#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308737 /* registration of wiphy dev with cfg80211 */
8738 if (0 > wlan_hdd_cfg80211_register(wiphy))
8739 {
8740 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8741 goto err_vosstop;
8742 }
8743
8744 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8745 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8746 {
8747 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8748 __func__);
8749 goto err_unregister_wiphy;
8750 }
8751#endif
8752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8754 {
8755 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8756 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8757 }
8758 else
8759 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8761 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8762 if (pAdapter != NULL)
8763 {
kaidde69982014-06-18 13:23:21 +08008764 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308766 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8767 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8768 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008769
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308770 /* Generate the P2P Device Address. This consists of the device's
8771 * primary MAC address with the locally administered bit set.
8772 */
8773 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008774 }
8775 else
8776 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308777 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8778 if (p2p_dev_addr != NULL)
8779 {
8780 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8781 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8782 }
8783 else
8784 {
8785 hddLog(VOS_TRACE_LEVEL_FATAL,
8786 "%s: Failed to allocate mac_address for p2p_device",
8787 __func__);
8788 goto err_close_adapter;
8789 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008791
8792 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8793 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8794 if ( NULL == pP2pAdapter )
8795 {
8796 hddLog(VOS_TRACE_LEVEL_FATAL,
8797 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008798 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008799 goto err_close_adapter;
8800 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008803
8804 if( pAdapter == NULL )
8805 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8807 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008809
Arif Hussain66559122013-11-21 10:11:40 -08008810 if (country_code)
8811 {
8812 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008813 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008814 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8815#ifndef CONFIG_ENABLE_LINUX_REG
8816 hdd_checkandupdate_phymode(pAdapter, country_code);
8817#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008818 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8819 (void *)(tSmeChangeCountryCallback)
8820 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008821 country_code,
8822 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308823 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008824 if (eHAL_STATUS_SUCCESS == ret)
8825 {
Arif Hussaincb607082013-12-20 11:57:42 -08008826 ret = wait_for_completion_interruptible_timeout(
8827 &pAdapter->change_country_code,
8828 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8829
8830 if (0 >= ret)
8831 {
8832 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8833 "%s: SME while setting country code timed out", __func__);
8834 }
Arif Hussain66559122013-11-21 10:11:40 -08008835 }
8836 else
8837 {
Arif Hussaincb607082013-12-20 11:57:42 -08008838 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8839 "%s: SME Change Country code from module param fail ret=%d",
8840 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008841 }
8842 }
8843
Jeff Johnson295189b2012-06-20 16:38:30 -07008844#ifdef WLAN_BTAMP_FEATURE
8845 vStatus = WLANBAP_Open(pVosContext);
8846 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8847 {
8848 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8849 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008850 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 }
8852
8853 vStatus = BSL_Init(pVosContext);
8854 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8855 {
8856 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8857 "%s: Failed to Init BSL",__func__);
8858 goto err_bap_close;
8859 }
8860 vStatus = WLANBAP_Start(pVosContext);
8861 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8862 {
8863 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8864 "%s: Failed to start TL",__func__);
8865 goto err_bap_close;
8866 }
8867
8868 pConfig = pHddCtx->cfg_ini;
8869 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8870 status = WLANBAP_SetConfig(&btAmpConfig);
8871
8872#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008873
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008874#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8875 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8876 {
8877 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8878 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8879 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8880 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8881 }
8882#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008883#ifdef FEATURE_WLAN_SCAN_PNO
8884 /*SME must send channel update configuration to RIVA*/
8885 sme_UpdateChannelConfig(pHddCtx->hHal);
8886#endif
8887
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308888 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 /* Register with platform driver as client for Suspend/Resume */
8891 status = hddRegisterPmOps(pHddCtx);
8892 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8893 {
8894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8895#ifdef WLAN_BTAMP_FEATURE
8896 goto err_bap_stop;
8897#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008898 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008899#endif //WLAN_BTAMP_FEATURE
8900 }
8901
Yue Ma0d4891e2013-08-06 17:01:45 -07008902 /* Open debugfs interface */
8903 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8904 {
8905 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8906 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008907 }
8908
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 /* Register TM level change handler function to the platform */
8910 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8911 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8912 {
8913 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8914 goto err_unregister_pmops;
8915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008916
8917 /* register for riva power on lock to platform driver */
8918 if (req_riva_power_on_lock("wlan"))
8919 {
8920 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8921 __func__);
8922 goto err_unregister_pmops;
8923 }
8924
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 // register net device notifier for device change notification
8926 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8927
8928 if(ret < 0)
8929 {
8930 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8931 goto err_free_power_on_lock;
8932 }
8933
8934 //Initialize the nlink service
8935 if(nl_srv_init() != 0)
8936 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308937 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 goto err_reg_netdev;
8939 }
8940
Leo Chang4ce1cc52013-10-21 18:27:15 -07008941#ifdef WLAN_KD_READY_NOTIFIER
8942 pHddCtx->kd_nl_init = 1;
8943#endif /* WLAN_KD_READY_NOTIFIER */
8944
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 //Initialize the BTC service
8946 if(btc_activate_service(pHddCtx) != 0)
8947 {
8948 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8949 goto err_nl_srv;
8950 }
8951
8952#ifdef PTT_SOCK_SVC_ENABLE
8953 //Initialize the PTT service
8954 if(ptt_sock_activate_svc(pHddCtx) != 0)
8955 {
8956 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8957 goto err_nl_srv;
8958 }
8959#endif
8960
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308961#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8962 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8963 {
8964 if(wlan_logging_sock_activate_svc(
8965 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8966 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8967 {
8968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8969 " failed", __func__);
8970 goto err_nl_srv;
8971 }
8972 }
8973#endif
8974
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008978 /* Action frame registered in one adapter which will
8979 * applicable to all interfaces
8980 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308981 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008983
8984 mutex_init(&pHddCtx->sap_lock);
8985
Mihir Shete18156292014-03-11 15:38:30 +05308986 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008988#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008989#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8990 /* Initialize the wake lcok */
8991 wake_lock_init(&pHddCtx->rx_wake_lock,
8992 WAKE_LOCK_SUSPEND,
8993 "qcom_rx_wakelock");
8994#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008995 /* Initialize the wake lcok */
8996 wake_lock_init(&pHddCtx->sap_wake_lock,
8997 WAKE_LOCK_SUSPEND,
8998 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008999#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009000
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009001 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9002 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009003
9004 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9005 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05309006#ifndef CONFIG_ENABLE_LINUX_REG
9007 /*updating wiphy so that regulatory user hints can be processed*/
9008 if (wiphy)
9009 {
9010 regulatory_hint(wiphy, "00");
9011 }
9012#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009013 // Initialize the restart logic
9014 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309015
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009016 //Register the traffic monitor timer now
9017 if ( pHddCtx->cfg_ini->dynSplitscan)
9018 {
9019 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9020 VOS_TIMER_TYPE_SW,
9021 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9022 (void *)pHddCtx);
9023 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309024#ifdef WLAN_FEATURE_EXTSCAN
9025 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9026 wlan_hdd_cfg80211_extscan_callback,
9027 pHddCtx);
9028#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009029 goto success;
9030
9031err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009032#ifdef WLAN_KD_READY_NOTIFIER
9033 nl_srv_exit(pHddCtx->ptt_pid);
9034#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009036#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009037err_reg_netdev:
9038 unregister_netdevice_notifier(&hdd_netdev_notifier);
9039
9040err_free_power_on_lock:
9041 free_riva_power_on_lock("wlan");
9042
9043err_unregister_pmops:
9044 hddDevTmUnregisterNotifyCallback(pHddCtx);
9045 hddDeregisterPmOps(pHddCtx);
9046
Yue Ma0d4891e2013-08-06 17:01:45 -07009047 hdd_debugfs_exit(pHddCtx);
9048
Jeff Johnson295189b2012-06-20 16:38:30 -07009049#ifdef WLAN_BTAMP_FEATURE
9050err_bap_stop:
9051 WLANBAP_Stop(pVosContext);
9052#endif
9053
9054#ifdef WLAN_BTAMP_FEATURE
9055err_bap_close:
9056 WLANBAP_Close(pVosContext);
9057#endif
9058
Jeff Johnson295189b2012-06-20 16:38:30 -07009059err_close_adapter:
9060 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309061err_unregister_wiphy:
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309062 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009063err_vosstop:
9064 vos_stop(pVosContext);
9065
Amar Singhala49cbc52013-10-08 18:37:44 -07009066err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009067 status = vos_sched_close( pVosContext );
9068 if (!VOS_IS_STATUS_SUCCESS(status)) {
9069 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9070 "%s: Failed to close VOSS Scheduler", __func__);
9071 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9072 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009073 vos_close(pVosContext );
9074
Amar Singhal0a402232013-10-11 20:57:16 -07009075err_vos_nv_close:
9076
c_hpothue6a36282014-03-19 12:27:38 +05309077#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009078 vos_nv_close();
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309081#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009082 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009083
9084err_wdclose:
9085 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9086 vos_watchdog_close(pVosContext);
9087
Jeff Johnson295189b2012-06-20 16:38:30 -07009088err_config:
9089 kfree(pHddCtx->cfg_ini);
9090 pHddCtx->cfg_ini= NULL;
9091
9092err_free_hdd_context:
9093 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009094 wiphy_free(wiphy) ;
9095 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 VOS_BUG(1);
9097
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009098 if (hdd_is_ssr_required())
9099 {
9100 /* WDI timeout had happened during load, so SSR is needed here */
9101 subsystem_restart("wcnss");
9102 msleep(5000);
9103 }
9104 hdd_set_ssr_required (VOS_FALSE);
9105
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009106 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009107
9108success:
9109 EXIT();
9110 return 0;
9111}
9112
9113/**---------------------------------------------------------------------------
9114
Jeff Johnson32d95a32012-09-10 13:15:23 -07009115 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009116
Jeff Johnson32d95a32012-09-10 13:15:23 -07009117 This is the driver entry point - called in different timeline depending
9118 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009119
9120 \param - None
9121
9122 \return - 0 for success, non zero for failure
9123
9124 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009125static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009126{
9127 VOS_STATUS status;
9128 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 struct device *dev = NULL;
9130 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009131#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9132 int max_retries = 0;
9133#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009134
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309135#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9136 wlan_logging_sock_init_svc();
9137#endif
9138
Jeff Johnson295189b2012-06-20 16:38:30 -07009139 ENTER();
9140
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009141#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009143#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009144
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309145 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9147 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9148
9149 //Power Up Libra WLAN card first if not already powered up
9150 status = vos_chipPowerUp(NULL,NULL,NULL);
9151 if (!VOS_IS_STATUS_SUCCESS(status))
9152 {
9153 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9154 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309155#ifdef WLAN_OPEN_SOURCE
9156 wake_lock_destroy(&wlan_wake_lock);
9157#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309158
9159#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9160 wlan_logging_sock_deinit_svc();
9161#endif
9162
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009163 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 }
9165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166#ifdef ANI_BUS_TYPE_PCI
9167
9168 dev = wcnss_wlan_get_device();
9169
9170#endif // ANI_BUS_TYPE_PCI
9171
9172#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009173
9174#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9175 /* wait until WCNSS driver downloads NV */
9176 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9177 msleep(1000);
9178 }
9179 if (max_retries >= 5) {
9180 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309181#ifdef WLAN_OPEN_SOURCE
9182 wake_lock_destroy(&wlan_wake_lock);
9183#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309184
9185#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9186 wlan_logging_sock_deinit_svc();
9187#endif
9188
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009189 return -ENODEV;
9190 }
9191#endif
9192
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 dev = wcnss_wlan_get_device();
9194#endif // ANI_BUS_TYPE_PLATFORM
9195
9196
9197 do {
9198 if (NULL == dev) {
9199 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9200 ret_status = -1;
9201 break;
9202 }
9203
Jeff Johnson295189b2012-06-20 16:38:30 -07009204#ifdef TIMER_MANAGER
9205 vos_timer_manager_init();
9206#endif
9207
9208 /* Preopen VOSS so that it is ready to start at least SAL */
9209 status = vos_preOpen(&pVosContext);
9210
9211 if (!VOS_IS_STATUS_SUCCESS(status))
9212 {
9213 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9214 ret_status = -1;
9215 break;
9216 }
9217
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009218#ifndef MODULE
9219 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9220 */
9221 hdd_set_conparam((v_UINT_t)con_mode);
9222#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009223
9224 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009225 if (hdd_wlan_startup(dev))
9226 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009228 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 vos_preClose( &pVosContext );
9230 ret_status = -1;
9231 break;
9232 }
9233
9234 /* Cancel the vote for XO Core ON
9235 * This is done here for safety purposes in case we re-initialize without turning
9236 * it OFF in any error scenario.
9237 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009238 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009240 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9242 {
9243 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009244 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 }
9246 } while (0);
9247
9248 if (0 != ret_status)
9249 {
9250 //Assert Deep sleep signal now to put Libra HW in lowest power state
9251 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9252 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9253
9254 //Vote off any PMIC voltage supplies
9255 vos_chipPowerDown(NULL, NULL, NULL);
9256#ifdef TIMER_MANAGER
9257 vos_timer_exit();
9258#endif
9259#ifdef MEMORY_DEBUG
9260 vos_mem_exit();
9261#endif
9262
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009263#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009265#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309266
9267#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9268 wlan_logging_sock_deinit_svc();
9269#endif
9270
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9272 }
9273 else
9274 {
9275 //Send WLAN UP indication to Nlink Service
9276 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9277
9278 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 }
9280
9281 EXIT();
9282
9283 return ret_status;
9284}
9285
Jeff Johnson32d95a32012-09-10 13:15:23 -07009286/**---------------------------------------------------------------------------
9287
9288 \brief hdd_module_init() - Init Function
9289
9290 This is the driver entry point (invoked when module is loaded using insmod)
9291
9292 \param - None
9293
9294 \return - 0 for success, non zero for failure
9295
9296 --------------------------------------------------------------------------*/
9297#ifdef MODULE
9298static int __init hdd_module_init ( void)
9299{
9300 return hdd_driver_init();
9301}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009302#else /* #ifdef MODULE */
9303static int __init hdd_module_init ( void)
9304{
9305 /* Driver initialization is delayed to fwpath_changed_handler */
9306 return 0;
9307}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009308#endif /* #ifdef MODULE */
9309
Jeff Johnson295189b2012-06-20 16:38:30 -07009310
9311/**---------------------------------------------------------------------------
9312
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009313 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009315 This is the driver exit point (invoked when module is unloaded using rmmod
9316 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009317
9318 \param - None
9319
9320 \return - None
9321
9322 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009323static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009324{
9325 hdd_context_t *pHddCtx = NULL;
9326 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309327 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309328 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009329
9330 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9331
9332 //Get the global vos context
9333 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9334
9335 if(!pVosContext)
9336 {
9337 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9338 goto done;
9339 }
9340
9341 //Get the HDD context.
9342 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9343
9344 if(!pHddCtx)
9345 {
9346 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9347 }
9348 else
9349 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309350 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9351
9352 if (pHddCtx->isLogpInProgress)
9353 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309355 "%s:SSR in Progress; block rmmod !!!", __func__);
9356 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9357 msecs_to_jiffies(30000));
9358 if(!rc)
9359 {
9360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9361 "%s:SSR timedout, fatal error", __func__);
9362 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009363 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009365
Mihir Shete18156292014-03-11 15:38:30 +05309366 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9368
Agarwal Ashish5e414792014-06-08 15:25:23 +05309369 if (eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
9370 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority )
9371 {
9372 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9373 }
9374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 //Do all the cleanup before deregistering the driver
9376 hdd_wlan_exit(pHddCtx);
9377 }
9378
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 vos_preClose( &pVosContext );
9380
9381#ifdef TIMER_MANAGER
9382 vos_timer_exit();
9383#endif
9384#ifdef MEMORY_DEBUG
9385 vos_mem_exit();
9386#endif
9387
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309388#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9389 wlan_logging_sock_deinit_svc();
9390#endif
9391
Jeff Johnson295189b2012-06-20 16:38:30 -07009392done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009393#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009395#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309396
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9398}
9399
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009400/**---------------------------------------------------------------------------
9401
9402 \brief hdd_module_exit() - Exit function
9403
9404 This is the driver exit point (invoked when module is unloaded using rmmod)
9405
9406 \param - None
9407
9408 \return - None
9409
9410 --------------------------------------------------------------------------*/
9411static void __exit hdd_module_exit(void)
9412{
9413 hdd_driver_exit();
9414}
9415
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009416#ifdef MODULE
9417static int fwpath_changed_handler(const char *kmessage,
9418 struct kernel_param *kp)
9419{
Jeff Johnson76052702013-04-16 13:55:05 -07009420 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009421}
9422
9423static int con_mode_handler(const char *kmessage,
9424 struct kernel_param *kp)
9425{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009426 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009427}
9428#else /* #ifdef MODULE */
9429/**---------------------------------------------------------------------------
9430
Jeff Johnson76052702013-04-16 13:55:05 -07009431 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009432
Jeff Johnson76052702013-04-16 13:55:05 -07009433 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009434 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009435 - invoked when module parameter fwpath is modified from userspace to signal
9436 initializing the WLAN driver or when con_mode is modified from userspace
9437 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009438
9439 \return - 0 for success, non zero for failure
9440
9441 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009442static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009443{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009444 int ret_status;
9445
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009446 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009447 ret_status = hdd_driver_init();
9448 wlan_hdd_inited = ret_status ? 0 : 1;
9449 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009450 }
9451
9452 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009453
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009454 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009455
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009456 ret_status = hdd_driver_init();
9457 wlan_hdd_inited = ret_status ? 0 : 1;
9458 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009459}
9460
Jeff Johnson295189b2012-06-20 16:38:30 -07009461/**---------------------------------------------------------------------------
9462
Jeff Johnson76052702013-04-16 13:55:05 -07009463 \brief fwpath_changed_handler() - Handler Function
9464
9465 Handle changes to the fwpath parameter
9466
9467 \return - 0 for success, non zero for failure
9468
9469 --------------------------------------------------------------------------*/
9470static int fwpath_changed_handler(const char *kmessage,
9471 struct kernel_param *kp)
9472{
9473 int ret;
9474
9475 ret = param_set_copystring(kmessage, kp);
9476 if (0 == ret)
9477 ret = kickstart_driver();
9478 return ret;
9479}
9480
9481/**---------------------------------------------------------------------------
9482
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009483 \brief con_mode_handler() -
9484
9485 Handler function for module param con_mode when it is changed by userspace
9486 Dynamically linked - do nothing
9487 Statically linked - exit and init driver, as in rmmod and insmod
9488
Jeff Johnson76052702013-04-16 13:55:05 -07009489 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009490
Jeff Johnson76052702013-04-16 13:55:05 -07009491 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009492
9493 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009494static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009495{
Jeff Johnson76052702013-04-16 13:55:05 -07009496 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009497
Jeff Johnson76052702013-04-16 13:55:05 -07009498 ret = param_set_int(kmessage, kp);
9499 if (0 == ret)
9500 ret = kickstart_driver();
9501 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009502}
9503#endif /* #ifdef MODULE */
9504
9505/**---------------------------------------------------------------------------
9506
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 \brief hdd_get_conparam() -
9508
9509 This is the driver exit point (invoked when module is unloaded using rmmod)
9510
9511 \param - None
9512
9513 \return - tVOS_CON_MODE
9514
9515 --------------------------------------------------------------------------*/
9516tVOS_CON_MODE hdd_get_conparam ( void )
9517{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009518#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009520#else
9521 return (tVOS_CON_MODE)curr_con_mode;
9522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009523}
9524void hdd_set_conparam ( v_UINT_t newParam )
9525{
9526 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009527#ifndef MODULE
9528 curr_con_mode = con_mode;
9529#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009530}
9531/**---------------------------------------------------------------------------
9532
9533 \brief hdd_softap_sta_deauth() - function
9534
9535 This to take counter measure to handle deauth req from HDD
9536
9537 \param - pAdapter - Pointer to the HDD
9538
9539 \param - enable - boolean value
9540
9541 \return - None
9542
9543 --------------------------------------------------------------------------*/
9544
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009545VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009546{
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009548 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009549
9550 ENTER();
9551
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009552 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9553 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009554
9555 //Ignore request to deauth bcmc station
9556 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009557 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009559 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009560
9561 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009562 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009563}
9564
9565/**---------------------------------------------------------------------------
9566
9567 \brief hdd_softap_sta_disassoc() - function
9568
9569 This to take counter measure to handle deauth req from HDD
9570
9571 \param - pAdapter - Pointer to the HDD
9572
9573 \param - enable - boolean value
9574
9575 \return - None
9576
9577 --------------------------------------------------------------------------*/
9578
9579void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9580{
9581 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9582
9583 ENTER();
9584
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309585 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009586
9587 //Ignore request to disassoc bcmc station
9588 if( pDestMacAddress[0] & 0x1 )
9589 return;
9590
9591 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9592}
9593
9594void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9595{
9596 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9597
9598 ENTER();
9599
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309600 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009601
9602 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9603}
9604
Jeff Johnson295189b2012-06-20 16:38:30 -07009605/**---------------------------------------------------------------------------
9606 *
9607 * \brief hdd_get__concurrency_mode() -
9608 *
9609 *
9610 * \param - None
9611 *
9612 * \return - CONCURRENCY MODE
9613 *
9614 * --------------------------------------------------------------------------*/
9615tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9616{
9617 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9618 hdd_context_t *pHddCtx;
9619
9620 if (NULL != pVosContext)
9621 {
9622 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9623 if (NULL != pHddCtx)
9624 {
9625 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9626 }
9627 }
9628
9629 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009630 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 return VOS_STA;
9632}
9633
9634/* Decide whether to allow/not the apps power collapse.
9635 * Allow apps power collapse if we are in connected state.
9636 * if not, allow only if we are in IMPS */
9637v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9638{
9639 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009640 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009641 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9643 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9644 hdd_adapter_t *pAdapter = NULL;
9645 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009646 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009647
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9649 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009650
Yathish9f22e662012-12-10 14:21:35 -08009651 concurrent_state = hdd_get_concurrency_mode();
9652
9653#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9654 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9655 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9656 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9657 return TRUE;
9658#endif
9659
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 /*loop through all adapters. TBD fix for Concurrency */
9661 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9662 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9663 {
9664 pAdapter = pAdapterNode->pAdapter;
9665 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9666 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9667 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009668 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309669 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009670 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009671 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9672 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009674 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009675 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9676 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 return FALSE;
9678 }
9679 }
9680 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9681 pAdapterNode = pNext;
9682 }
9683 return TRUE;
9684}
9685
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009686/* Decides whether to send suspend notification to Riva
9687 * if any adapter is in BMPS; then it is required */
9688v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9689{
9690 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9691 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9692
9693 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9694 {
9695 return TRUE;
9696 }
9697 return FALSE;
9698}
9699
Jeff Johnson295189b2012-06-20 16:38:30 -07009700void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9701{
9702 switch(mode)
9703 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009704 case VOS_STA_MODE:
9705 case VOS_P2P_CLIENT_MODE:
9706 case VOS_P2P_GO_MODE:
9707 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009708 pHddCtx->concurrency_mode |= (1 << mode);
9709 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 break;
9711 default:
9712 break;
9713
9714 }
9715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9716 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9717}
9718
9719
9720void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9721{
9722 switch(mode)
9723 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009724 case VOS_STA_MODE:
9725 case VOS_P2P_CLIENT_MODE:
9726 case VOS_P2P_GO_MODE:
9727 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 pHddCtx->no_of_sessions[mode]--;
9729 if (!(pHddCtx->no_of_sessions[mode]))
9730 pHddCtx->concurrency_mode &= (~(1 << mode));
9731 break;
9732 default:
9733 break;
9734 }
9735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9736 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9737}
9738
Jeff Johnsone7245742012-09-05 17:12:55 -07009739/**---------------------------------------------------------------------------
9740 *
9741 * \brief wlan_hdd_restart_init
9742 *
9743 * This function initalizes restart timer/flag. An internal function.
9744 *
9745 * \param - pHddCtx
9746 *
9747 * \return - None
9748 *
9749 * --------------------------------------------------------------------------*/
9750
9751static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9752{
9753 /* Initialize */
9754 pHddCtx->hdd_restart_retries = 0;
9755 atomic_set(&pHddCtx->isRestartInProgress, 0);
9756 vos_timer_init(&pHddCtx->hdd_restart_timer,
9757 VOS_TIMER_TYPE_SW,
9758 wlan_hdd_restart_timer_cb,
9759 pHddCtx);
9760}
9761/**---------------------------------------------------------------------------
9762 *
9763 * \brief wlan_hdd_restart_deinit
9764 *
9765 * This function cleans up the resources used. An internal function.
9766 *
9767 * \param - pHddCtx
9768 *
9769 * \return - None
9770 *
9771 * --------------------------------------------------------------------------*/
9772
9773static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9774{
9775
9776 VOS_STATUS vos_status;
9777 /* Block any further calls */
9778 atomic_set(&pHddCtx->isRestartInProgress, 1);
9779 /* Cleanup */
9780 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9781 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309782 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009783 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9784 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309785 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009786
9787}
9788
9789/**---------------------------------------------------------------------------
9790 *
9791 * \brief wlan_hdd_framework_restart
9792 *
9793 * This function uses a cfg80211 API to start a framework initiated WLAN
9794 * driver module unload/load.
9795 *
9796 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9797 *
9798 *
9799 * \param - pHddCtx
9800 *
9801 * \return - VOS_STATUS_SUCCESS: Success
9802 * VOS_STATUS_E_EMPTY: Adapter is Empty
9803 * VOS_STATUS_E_NOMEM: No memory
9804
9805 * --------------------------------------------------------------------------*/
9806
9807static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9808{
9809 VOS_STATUS status = VOS_STATUS_SUCCESS;
9810 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009811 int len = (sizeof (struct ieee80211_mgmt));
9812 struct ieee80211_mgmt *mgmt = NULL;
9813
9814 /* Prepare the DEAUTH managment frame with reason code */
9815 mgmt = kzalloc(len, GFP_KERNEL);
9816 if(mgmt == NULL)
9817 {
9818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9819 "%s: memory allocation failed (%d bytes)", __func__, len);
9820 return VOS_STATUS_E_NOMEM;
9821 }
9822 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009823
9824 /* Iterate over all adapters/devices */
9825 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9826 do
9827 {
9828 if( (status == VOS_STATUS_SUCCESS) &&
9829 pAdapterNode &&
9830 pAdapterNode->pAdapter)
9831 {
9832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9833 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9834 pAdapterNode->pAdapter->dev->name,
9835 pAdapterNode->pAdapter->device_mode,
9836 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009837 /*
9838 * CFG80211 event to restart the driver
9839 *
9840 * 'cfg80211_send_unprot_deauth' sends a
9841 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9842 * of SME(Linux Kernel) state machine.
9843 *
9844 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9845 * the driver.
9846 *
9847 */
9848
9849 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009850 }
9851 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9852 pAdapterNode = pNext;
9853 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9854
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009855
9856 /* Free the allocated management frame */
9857 kfree(mgmt);
9858
Jeff Johnsone7245742012-09-05 17:12:55 -07009859 /* Retry until we unload or reach max count */
9860 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9861 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9862
9863 return status;
9864
9865}
9866/**---------------------------------------------------------------------------
9867 *
9868 * \brief wlan_hdd_restart_timer_cb
9869 *
9870 * Restart timer callback. An internal function.
9871 *
9872 * \param - User data:
9873 *
9874 * \return - None
9875 *
9876 * --------------------------------------------------------------------------*/
9877
9878void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9879{
9880 hdd_context_t *pHddCtx = usrDataForCallback;
9881 wlan_hdd_framework_restart(pHddCtx);
9882 return;
9883
9884}
9885
9886
9887/**---------------------------------------------------------------------------
9888 *
9889 * \brief wlan_hdd_restart_driver
9890 *
9891 * This function sends an event to supplicant to restart the WLAN driver.
9892 *
9893 * This function is called from vos_wlanRestart.
9894 *
9895 * \param - pHddCtx
9896 *
9897 * \return - VOS_STATUS_SUCCESS: Success
9898 * VOS_STATUS_E_EMPTY: Adapter is Empty
9899 * VOS_STATUS_E_ALREADY: Request already in progress
9900
9901 * --------------------------------------------------------------------------*/
9902VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9903{
9904 VOS_STATUS status = VOS_STATUS_SUCCESS;
9905
9906 /* A tight check to make sure reentrancy */
9907 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9908 {
9909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9910 "%s: WLAN restart is already in progress", __func__);
9911
9912 return VOS_STATUS_E_ALREADY;
9913 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009914 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009915#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009916 wcnss_reset_intr();
9917#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009918
Jeff Johnsone7245742012-09-05 17:12:55 -07009919 return status;
9920}
9921
Mihir Shetee1093ba2014-01-21 20:13:32 +05309922/**---------------------------------------------------------------------------
9923 *
9924 * \brief wlan_hdd_init_channels
9925 *
9926 * This function is used to initialize the channel list in CSR
9927 *
9928 * This function is called from hdd_wlan_startup
9929 *
9930 * \param - pHddCtx: HDD context
9931 *
9932 * \return - VOS_STATUS_SUCCESS: Success
9933 * VOS_STATUS_E_FAULT: Failure reported by SME
9934
9935 * --------------------------------------------------------------------------*/
9936static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9937{
9938 eHalStatus status;
9939
9940 status = sme_InitChannels(pHddCtx->hHal);
9941 if (HAL_STATUS_SUCCESS(status))
9942 {
9943 return VOS_STATUS_SUCCESS;
9944 }
9945 else
9946 {
9947 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9948 __func__, status);
9949 return VOS_STATUS_E_FAULT;
9950 }
9951}
9952
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309953static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
9954{
9955 eHalStatus status;
9956
9957 status = sme_InitChannelsForCC(pHddCtx->hHal);
9958 if (HAL_STATUS_SUCCESS(status))
9959 {
9960 return VOS_STATUS_SUCCESS;
9961 }
9962 else
9963 {
9964 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
9965 __func__, status);
9966 return VOS_STATUS_E_FAULT;
9967 }
9968}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009969/*
9970 * API to find if there is any STA or P2P-Client is connected
9971 */
9972VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9973{
9974 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9975}
Jeff Johnsone7245742012-09-05 17:12:55 -07009976
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309977int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
9978{
9979 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9980 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +05309981 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309982
9983 pScanInfo = &pHddCtx->scan_info;
9984 if (pScanInfo->mScanPending)
9985 {
9986 INIT_COMPLETION(pScanInfo->abortscan_event_var);
9987 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9988 eCSR_SCAN_ABORT_DEFAULT);
9989
9990 status = wait_for_completion_interruptible_timeout(
9991 &pScanInfo->abortscan_event_var,
9992 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +05309993 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309994 {
9995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +05309996 "%s: Timeout or Interrupt occurred while waiting for abort"
9997 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309998 return -ETIMEDOUT;
9999 }
10000 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010001 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010002}
10003
Jeff Johnson295189b2012-06-20 16:38:30 -070010004//Register the module init/exit functions
10005module_init(hdd_module_init);
10006module_exit(hdd_module_exit);
10007
10008MODULE_LICENSE("Dual BSD/GPL");
10009MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10010MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10011
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010012module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10013 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010014
Jeff Johnson76052702013-04-16 13:55:05 -070010015module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010016 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010017
10018module_param(enable_dfs_chan_scan, int,
10019 S_IRUSR | S_IRGRP | S_IROTH);
10020
10021module_param(enable_11d, int,
10022 S_IRUSR | S_IRGRP | S_IROTH);
10023
10024module_param(country_code, charp,
10025 S_IRUSR | S_IRGRP | S_IROTH);