blob: 621b5b1555d768ae788901dff3ea8a0bcdf0c057 [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 {
3630 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303631 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303632 if ('1' == *dhcpPhase)
3633 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303635 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303636
3637 pHddCtx->btCoexModeSet = TRUE;
3638
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303639 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303640 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303641 }
3642 else if ('2' == *dhcpPhase)
3643 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303645 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303646
3647 pHddCtx->btCoexModeSet = FALSE;
3648
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303649 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303650 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303651 }
3652 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003653 else if (strncmp(command, "SCAN-ACTIVE", 11) == 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 ACTIVE"));
3657 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003658 }
3659 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3660 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3662 FL("making default scan to PASSIVE"));
3663 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003664 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303665 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3666 {
3667 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3668 char extra[32];
3669 tANI_U8 len = 0;
3670
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303671 memset(extra, 0, sizeof(extra));
3672 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3673 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303674 {
3675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3676 "%s: failed to copy data to user buffer", __func__);
3677 ret = -EFAULT;
3678 goto exit;
3679 }
3680 ret = len;
3681 }
3682 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3683 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303684 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303685 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003686 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3687 {
3688 tANI_U8 filterType = 0;
3689 tANI_U8 *value;
3690 value = command + 9;
3691
3692 /* Convert the value from ascii to integer */
3693 ret = kstrtou8(value, 10, &filterType);
3694 if (ret < 0)
3695 {
3696 /* If the input value is greater than max value of datatype,
3697 * then also kstrtou8 fails
3698 */
3699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3700 "%s: kstrtou8 failed range ", __func__);
3701 ret = -EINVAL;
3702 goto exit;
3703 }
3704 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3705 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3706 {
3707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3708 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3709 " 2-Sink ", __func__);
3710 ret = -EINVAL;
3711 goto exit;
3712 }
3713 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3714 pHddCtx->drvr_miracast = filterType;
3715 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3716 }
Leo Chang614d2072013-08-22 14:59:44 -07003717 else if (strncmp(command, "SETMCRATE", 9) == 0)
3718 {
Leo Chang614d2072013-08-22 14:59:44 -07003719 tANI_U8 *value = command;
3720 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003721 tSirRateUpdateInd *rateUpdate;
3722 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003723
3724 /* Only valid for SAP mode */
3725 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3726 {
3727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3728 "%s: SAP mode is not running", __func__);
3729 ret = -EFAULT;
3730 goto exit;
3731 }
3732
3733 /* Move pointer to ahead of SETMCRATE<delimiter> */
3734 /* input value is in units of hundred kbps */
3735 value = value + 10;
3736 /* Convert the value from ascii to integer, decimal base */
3737 ret = kstrtouint(value, 10, &targetRate);
3738
Leo Chang1f98cbd2013-10-17 15:03:52 -07003739 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3740 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003741 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003742 hddLog(VOS_TRACE_LEVEL_ERROR,
3743 "%s: SETMCRATE indication alloc fail", __func__);
3744 ret = -EFAULT;
3745 goto exit;
3746 }
3747 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3748
3749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3750 "MC Target rate %d", targetRate);
3751 /* Ignore unicast */
3752 rateUpdate->ucastDataRate = -1;
3753 rateUpdate->mcastDataRate24GHz = targetRate;
3754 rateUpdate->mcastDataRate5GHz = targetRate;
3755 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3756 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3757 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3758 if (eHAL_STATUS_SUCCESS != status)
3759 {
3760 hddLog(VOS_TRACE_LEVEL_ERROR,
3761 "%s: SET_MC_RATE failed", __func__);
3762 vos_mem_free(rateUpdate);
3763 ret = -EFAULT;
3764 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003765 }
3766 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303767#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003768 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303769 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003770 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303771 }
3772#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003773#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003774 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3775 {
3776 tANI_U8 *value = command;
3777 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3778 tANI_U8 numChannels = 0;
3779 eHalStatus status = eHAL_STATUS_SUCCESS;
3780
3781 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3782 if (eHAL_STATUS_SUCCESS != status)
3783 {
3784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3785 "%s: Failed to parse channel list information", __func__);
3786 ret = -EINVAL;
3787 goto exit;
3788 }
3789
3790 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3791 {
3792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3793 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3794 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3795 ret = -EINVAL;
3796 goto exit;
3797 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003798 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003799 ChannelList,
3800 numChannels);
3801 if (eHAL_STATUS_SUCCESS != status)
3802 {
3803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3804 "%s: Failed to update channel list information", __func__);
3805 ret = -EINVAL;
3806 goto exit;
3807 }
3808 }
3809 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3810 {
3811 tANI_U8 *value = command;
3812 char extra[128] = {0};
3813 int len = 0;
3814 tANI_U8 tid = 0;
3815 hdd_station_ctx_t *pHddStaCtx = NULL;
3816 tAniTrafStrmMetrics tsmMetrics;
3817 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3818
3819 /* if not associated, return error */
3820 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3821 {
3822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3823 ret = -EINVAL;
3824 goto exit;
3825 }
3826
3827 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3828 value = value + 12;
3829 /* Convert the value from ascii to integer */
3830 ret = kstrtou8(value, 10, &tid);
3831 if (ret < 0)
3832 {
3833 /* If the input value is greater than max value of datatype, then also
3834 kstrtou8 fails */
3835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3836 "%s: kstrtou8 failed range [%d - %d]", __func__,
3837 TID_MIN_VALUE,
3838 TID_MAX_VALUE);
3839 ret = -EINVAL;
3840 goto exit;
3841 }
3842
3843 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3844 {
3845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3846 "tid value %d is out of range"
3847 " (Min: %d Max: %d)", tid,
3848 TID_MIN_VALUE,
3849 TID_MAX_VALUE);
3850 ret = -EINVAL;
3851 goto exit;
3852 }
3853
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3855 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3856
3857 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3858 {
3859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3860 "%s: failed to get tsm stats", __func__);
3861 ret = -EFAULT;
3862 goto exit;
3863 }
3864
3865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3866 "UplinkPktQueueDly(%d)\n"
3867 "UplinkPktQueueDlyHist[0](%d)\n"
3868 "UplinkPktQueueDlyHist[1](%d)\n"
3869 "UplinkPktQueueDlyHist[2](%d)\n"
3870 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303871 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003872 "UplinkPktLoss(%d)\n"
3873 "UplinkPktCount(%d)\n"
3874 "RoamingCount(%d)\n"
3875 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3876 tsmMetrics.UplinkPktQueueDlyHist[0],
3877 tsmMetrics.UplinkPktQueueDlyHist[1],
3878 tsmMetrics.UplinkPktQueueDlyHist[2],
3879 tsmMetrics.UplinkPktQueueDlyHist[3],
3880 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3881 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3882
3883 /* Output TSM stats is of the format
3884 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3885 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003886 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003887 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3888 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3889 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3890 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3891 tsmMetrics.RoamingDly);
3892
3893 if (copy_to_user(priv_data.buf, &extra, len + 1))
3894 {
3895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3896 "%s: failed to copy data to user buffer", __func__);
3897 ret = -EFAULT;
3898 goto exit;
3899 }
3900 }
3901 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3902 {
3903 tANI_U8 *value = command;
3904 tANI_U8 *cckmIe = NULL;
3905 tANI_U8 cckmIeLen = 0;
3906 eHalStatus status = eHAL_STATUS_SUCCESS;
3907
3908 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3909 if (eHAL_STATUS_SUCCESS != status)
3910 {
3911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3912 "%s: Failed to parse cckm ie data", __func__);
3913 ret = -EINVAL;
3914 goto exit;
3915 }
3916
3917 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3918 {
3919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3920 "%s: CCKM Ie input length is more than max[%d]", __func__,
3921 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003922 vos_mem_free(cckmIe);
3923 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003924 ret = -EINVAL;
3925 goto exit;
3926 }
3927 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003928 vos_mem_free(cckmIe);
3929 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003930 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003931 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3932 {
3933 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003934 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003935 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003936
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003937 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003938 if (eHAL_STATUS_SUCCESS != status)
3939 {
3940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003941 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003942 ret = -EINVAL;
3943 goto exit;
3944 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003945 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3947 hdd_indicateEseBcnReportNoResults (pAdapter,
3948 eseBcnReq.bcnReq[0].measurementToken,
3949 0x02, //BIT(1) set for measurement done
3950 0); // no BSS
3951 goto exit;
3952 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003953
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003954 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3955 if (eHAL_STATUS_SUCCESS != status)
3956 {
3957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3958 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3959 ret = -EINVAL;
3960 goto exit;
3961 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003962 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003963#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303964 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3965 {
3966 eHalStatus status;
3967 char buf[32], len;
3968 long waitRet;
3969 bcnMissRateContext_t getBcnMissRateCtx;
3970
3971 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3972
3973 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3974 {
3975 hddLog(VOS_TRACE_LEVEL_WARN,
3976 FL("GETBCNMISSRATE: STA is not in connected state"));
3977 ret = -1;
3978 goto exit;
3979 }
3980
3981 init_completion(&(getBcnMissRateCtx.completion));
3982 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
3983
3984 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
3985 pAdapter->sessionId,
3986 (void *)getBcnMissRateCB,
3987 (void *)(&getBcnMissRateCtx));
3988 if( eHAL_STATUS_SUCCESS != status)
3989 {
3990 hddLog(VOS_TRACE_LEVEL_INFO,
3991 FL("GETBCNMISSRATE: fail to post WDA cmd"));
3992 ret = -EINVAL;
3993 goto exit;
3994 }
3995
3996 waitRet = wait_for_completion_interruptible_timeout
3997 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
3998 if(waitRet <= 0)
3999 {
4000 hddLog(VOS_TRACE_LEVEL_ERROR,
4001 FL("failed to wait on bcnMissRateComp %d"), ret);
4002
4003 //Make magic number to zero so that callback is not called.
4004 spin_lock(&hdd_context_lock);
4005 getBcnMissRateCtx.magic = 0x0;
4006 spin_unlock(&hdd_context_lock);
4007 ret = -EINVAL;
4008 goto exit;
4009 }
4010
4011 hddLog(VOS_TRACE_LEVEL_INFO,
4012 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4013
4014 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4015 if (copy_to_user(priv_data.buf, &buf, len + 1))
4016 {
4017 hddLog(VOS_TRACE_LEVEL_ERROR,
4018 "%s: failed to copy data to user buffer", __func__);
4019 ret = -EFAULT;
4020 goto exit;
4021 }
4022 ret = len;
4023 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004024 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304025 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4026 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4027 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004028 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4029 __func__, command);
4030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004031 }
4032exit:
4033 if (command)
4034 {
4035 kfree(command);
4036 }
4037 return ret;
4038}
4039
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004040#ifdef CONFIG_COMPAT
4041static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4042{
4043 struct {
4044 compat_uptr_t buf;
4045 int used_len;
4046 int total_len;
4047 } compat_priv_data;
4048 hdd_priv_data_t priv_data;
4049 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004050
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004051 /*
4052 * Note that pAdapter and ifr have already been verified by caller,
4053 * and HDD context has also been validated
4054 */
4055 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4056 sizeof(compat_priv_data))) {
4057 ret = -EFAULT;
4058 goto exit;
4059 }
4060 priv_data.buf = compat_ptr(compat_priv_data.buf);
4061 priv_data.used_len = compat_priv_data.used_len;
4062 priv_data.total_len = compat_priv_data.total_len;
4063 ret = hdd_driver_command(pAdapter, &priv_data);
4064 exit:
4065 return ret;
4066}
4067#else /* CONFIG_COMPAT */
4068static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4069{
4070 /* will never be invoked */
4071 return 0;
4072}
4073#endif /* CONFIG_COMPAT */
4074
4075static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4076{
4077 hdd_priv_data_t priv_data;
4078 int ret = 0;
4079
4080 /*
4081 * Note that pAdapter and ifr have already been verified by caller,
4082 * and HDD context has also been validated
4083 */
4084 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4085 ret = -EFAULT;
4086 } else {
4087 ret = hdd_driver_command(pAdapter, &priv_data);
4088 }
4089 return ret;
4090}
4091
4092int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4093{
4094 hdd_adapter_t *pAdapter;
4095 hdd_context_t *pHddCtx;
4096 int ret;
4097
4098 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4099 if (NULL == pAdapter) {
4100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4101 "%s: HDD adapter context is Null", __func__);
4102 ret = -ENODEV;
4103 goto exit;
4104 }
4105 if (dev != pAdapter->dev) {
4106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4107 "%s: HDD adapter/dev inconsistency", __func__);
4108 ret = -ENODEV;
4109 goto exit;
4110 }
4111
4112 if ((!ifr) || (!ifr->ifr_data)) {
4113 ret = -EINVAL;
4114 goto exit;
4115 }
4116
4117 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4118 ret = wlan_hdd_validate_context(pHddCtx);
4119 if (ret) {
4120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4121 "%s: invalid context", __func__);
4122 ret = -EBUSY;
4123 goto exit;
4124 }
4125
4126 switch (cmd) {
4127 case (SIOCDEVPRIVATE + 1):
4128 if (is_compat_task())
4129 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4130 else
4131 ret = hdd_driver_ioctl(pAdapter, ifr);
4132 break;
4133 default:
4134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4135 __func__, cmd);
4136 ret = -EINVAL;
4137 break;
4138 }
4139 exit:
4140 return ret;
4141}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004142
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004143#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004144/**---------------------------------------------------------------------------
4145
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004146 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004147
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004148 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004149 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4150 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4151 <space>Scan Mode N<space>Meas Duration N
4152 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4153 then take N.
4154 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4155 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4156 This function does not take care of removing duplicate channels from the list
4157
4158 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004159 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004160
4161 \return - 0 for success non-zero for failure
4162
4163 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004164static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4165 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004166{
4167 tANI_U8 *inPtr = pValue;
4168 int tempInt = 0;
4169 int j = 0, i = 0, v = 0;
4170 char buf[32];
4171
4172 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4173 /*no argument after the command*/
4174 if (NULL == inPtr)
4175 {
4176 return -EINVAL;
4177 }
4178 /*no space after the command*/
4179 else if (SPACE_ASCII_VALUE != *inPtr)
4180 {
4181 return -EINVAL;
4182 }
4183
4184 /*removing empty spaces*/
4185 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4186
4187 /*no argument followed by spaces*/
4188 if ('\0' == *inPtr) return -EINVAL;
4189
4190 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004191 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004192 if (1 != v) return -EINVAL;
4193
4194 v = kstrtos32(buf, 10, &tempInt);
4195 if ( v < 0) return -EINVAL;
4196
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004197 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004198
4199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004200 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004201
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004202 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004203 {
4204 for (i = 0; i < 4; i++)
4205 {
4206 /*inPtr pointing to the beginning of first space after number of ie fields*/
4207 inPtr = strpbrk( inPtr, " " );
4208 /*no ie data after the number of ie fields argument*/
4209 if (NULL == inPtr) return -EINVAL;
4210
4211 /*removing empty space*/
4212 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4213
4214 /*no ie data after the number of ie fields argument and spaces*/
4215 if ( '\0' == *inPtr ) return -EINVAL;
4216
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004217 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004218 if (1 != v) return -EINVAL;
4219
4220 v = kstrtos32(buf, 10, &tempInt);
4221 if (v < 0) return -EINVAL;
4222
4223 switch (i)
4224 {
4225 case 0: /* Measurement token */
4226 if (tempInt <= 0)
4227 {
4228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4229 "Invalid Measurement Token(%d)", tempInt);
4230 return -EINVAL;
4231 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004232 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004233 break;
4234
4235 case 1: /* Channel number */
4236 if ((tempInt <= 0) ||
4237 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4238 {
4239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4240 "Invalid Channel Number(%d)", tempInt);
4241 return -EINVAL;
4242 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004243 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004244 break;
4245
4246 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004247 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004248 {
4249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4250 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4251 return -EINVAL;
4252 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004253 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004254 break;
4255
4256 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004257 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4258 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004259 {
4260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4261 "Invalid Measurement Duration(%d)", tempInt);
4262 return -EINVAL;
4263 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004264 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004265 break;
4266 }
4267 }
4268 }
4269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004270 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004271 {
4272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304273 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004274 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004275 pEseBcnReq->bcnReq[j].measurementToken,
4276 pEseBcnReq->bcnReq[j].channel,
4277 pEseBcnReq->bcnReq[j].scanMode,
4278 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004279 }
4280
4281 return VOS_STATUS_SUCCESS;
4282}
4283
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004284static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4285{
4286 struct statsContext *pStatsContext = NULL;
4287 hdd_adapter_t *pAdapter = NULL;
4288
4289 if (NULL == pContext)
4290 {
4291 hddLog(VOS_TRACE_LEVEL_ERROR,
4292 "%s: Bad param, pContext [%p]",
4293 __func__, pContext);
4294 return;
4295 }
4296
Jeff Johnson72a40512013-12-19 10:14:15 -08004297 /* there is a race condition that exists between this callback
4298 function and the caller since the caller could time out either
4299 before or while this code is executing. we use a spinlock to
4300 serialize these actions */
4301 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004302
4303 pStatsContext = pContext;
4304 pAdapter = pStatsContext->pAdapter;
4305 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4306 {
4307 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004308 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004309 hddLog(VOS_TRACE_LEVEL_WARN,
4310 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4311 __func__, pAdapter, pStatsContext->magic);
4312 return;
4313 }
4314
Jeff Johnson72a40512013-12-19 10:14:15 -08004315 /* context is valid so caller is still waiting */
4316
4317 /* paranoia: invalidate the magic */
4318 pStatsContext->magic = 0;
4319
4320 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004321 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4322 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4323 tsmMetrics.UplinkPktQueueDlyHist,
4324 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4325 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4326 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4327 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4328 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4329 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4330 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4331
Jeff Johnson72a40512013-12-19 10:14:15 -08004332 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004333 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004334
4335 /* serialization is complete */
4336 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004337}
4338
4339
4340
4341static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4342 tAniTrafStrmMetrics* pTsmMetrics)
4343{
4344 hdd_station_ctx_t *pHddStaCtx = NULL;
4345 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004346 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004347 long lrc;
4348 struct statsContext context;
4349 hdd_context_t *pHddCtx = NULL;
4350
4351 if (NULL == pAdapter)
4352 {
4353 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4354 return VOS_STATUS_E_FAULT;
4355 }
4356
4357 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4358 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4359
4360 /* we are connected prepare our callback context */
4361 init_completion(&context.completion);
4362 context.pAdapter = pAdapter;
4363 context.magic = STATS_CONTEXT_MAGIC;
4364
4365 /* query tsm stats */
4366 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4367 pHddStaCtx->conn_info.staId[ 0 ],
4368 pHddStaCtx->conn_info.bssId,
4369 &context, pHddCtx->pvosContext, tid);
4370
4371 if (eHAL_STATUS_SUCCESS != hstatus)
4372 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4374 __func__);
4375 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004376 }
4377 else
4378 {
4379 /* request was sent -- wait for the response */
4380 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4381 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004382 if (lrc <= 0)
4383 {
4384 hddLog(VOS_TRACE_LEVEL_ERROR,
4385 "%s: SME %s while retrieving statistics",
4386 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004387 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004388 }
4389 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004390
Jeff Johnson72a40512013-12-19 10:14:15 -08004391 /* either we never sent a request, we sent a request and received a
4392 response or we sent a request and timed out. if we never sent a
4393 request or if we sent a request and got a response, we want to
4394 clear the magic out of paranoia. if we timed out there is a
4395 race condition such that the callback function could be
4396 executing at the same time we are. of primary concern is if the
4397 callback function had already verified the "magic" but had not
4398 yet set the completion variable when a timeout occurred. we
4399 serialize these activities by invalidating the magic while
4400 holding a shared spinlock which will cause us to block if the
4401 callback is currently executing */
4402 spin_lock(&hdd_context_lock);
4403 context.magic = 0;
4404 spin_unlock(&hdd_context_lock);
4405
4406 if (VOS_STATUS_SUCCESS == vstatus)
4407 {
4408 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4409 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4410 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4411 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4412 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4413 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4414 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4415 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4416 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4417 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4418 }
4419 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004420}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004421#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004422
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004423#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004424void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4425{
4426 eCsrBand band = -1;
4427 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4428 switch (band)
4429 {
4430 case eCSR_BAND_ALL:
4431 *pBand = WLAN_HDD_UI_BAND_AUTO;
4432 break;
4433
4434 case eCSR_BAND_24:
4435 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4436 break;
4437
4438 case eCSR_BAND_5G:
4439 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4440 break;
4441
4442 default:
4443 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4444 *pBand = -1;
4445 break;
4446 }
4447}
4448
4449/**---------------------------------------------------------------------------
4450
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004451 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4452
4453 This function parses the send action frame data passed in the format
4454 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4455
Srinivas Girigowda56076852013-08-20 14:00:50 -07004456 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004457 \param - pTargetApBssid Pointer to target Ap bssid
4458 \param - pChannel Pointer to the Target AP channel
4459 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4460 \param - pBuf Pointer to data
4461 \param - pBufLen Pointer to data length
4462
4463 \return - 0 for success non-zero for failure
4464
4465 --------------------------------------------------------------------------*/
4466VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4467 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4468{
4469 tANI_U8 *inPtr = pValue;
4470 tANI_U8 *dataEnd;
4471 int tempInt;
4472 int j = 0;
4473 int i = 0;
4474 int v = 0;
4475 tANI_U8 tempBuf[32];
4476 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004477 /* 12 hexa decimal digits, 5 ':' and '\0' */
4478 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004479
4480 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4481 /*no argument after the command*/
4482 if (NULL == inPtr)
4483 {
4484 return -EINVAL;
4485 }
4486
4487 /*no space after the command*/
4488 else if (SPACE_ASCII_VALUE != *inPtr)
4489 {
4490 return -EINVAL;
4491 }
4492
4493 /*removing empty spaces*/
4494 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4495
4496 /*no argument followed by spaces*/
4497 if ('\0' == *inPtr)
4498 {
4499 return -EINVAL;
4500 }
4501
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004502 v = sscanf(inPtr, "%17s", macAddress);
4503 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004504 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4506 "Invalid MAC address or All hex inputs are not read (%d)", v);
4507 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004508 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004509
4510 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4511 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4512 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4513 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4514 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4515 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004516
4517 /* point to the next argument */
4518 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4519 /*no argument after the command*/
4520 if (NULL == inPtr) return -EINVAL;
4521
4522 /*removing empty spaces*/
4523 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4524
4525 /*no argument followed by spaces*/
4526 if ('\0' == *inPtr)
4527 {
4528 return -EINVAL;
4529 }
4530
4531 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004532 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004533 if (1 != v) return -EINVAL;
4534
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004535 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304536 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304537 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004538
4539 *pChannel = tempInt;
4540
4541 /* point to the next argument */
4542 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4543 /*no argument after the command*/
4544 if (NULL == inPtr) return -EINVAL;
4545 /*removing empty spaces*/
4546 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4547
4548 /*no argument followed by spaces*/
4549 if ('\0' == *inPtr)
4550 {
4551 return -EINVAL;
4552 }
4553
4554 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004555 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004556 if (1 != v) return -EINVAL;
4557
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004558 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004559 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004560
4561 *pDwellTime = tempInt;
4562
4563 /* point to the next argument */
4564 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4565 /*no argument after the command*/
4566 if (NULL == inPtr) return -EINVAL;
4567 /*removing empty spaces*/
4568 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4569
4570 /*no argument followed by spaces*/
4571 if ('\0' == *inPtr)
4572 {
4573 return -EINVAL;
4574 }
4575
4576 /* find the length of data */
4577 dataEnd = inPtr;
4578 while(('\0' != *dataEnd) )
4579 {
4580 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004581 }
Kiet Lambe150c22013-11-21 16:30:32 +05304582 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004583 if ( *pBufLen <= 0) return -EINVAL;
4584
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004585 /* Allocate the number of bytes based on the number of input characters
4586 whether it is even or odd.
4587 if the number of input characters are even, then we need N/2 byte.
4588 if the number of input characters are odd, then we need do (N+1)/2 to
4589 compensate rounding off.
4590 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4591 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4592 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004593 if (NULL == *pBuf)
4594 {
4595 hddLog(VOS_TRACE_LEVEL_FATAL,
4596 "%s: vos_mem_alloc failed ", __func__);
4597 return -EINVAL;
4598 }
4599
4600 /* the buffer received from the upper layer is character buffer,
4601 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4602 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4603 and f0 in 3rd location */
4604 for (i = 0, j = 0; j < *pBufLen; j += 2)
4605 {
Kiet Lambe150c22013-11-21 16:30:32 +05304606 if( j+1 == *pBufLen)
4607 {
4608 tempByte = hdd_parse_hex(inPtr[j]);
4609 }
4610 else
4611 {
4612 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4613 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004614 (*pBuf)[i++] = tempByte;
4615 }
4616 *pBufLen = i;
4617 return VOS_STATUS_SUCCESS;
4618}
4619
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004620/**---------------------------------------------------------------------------
4621
Srinivas Girigowdade697412013-02-14 16:31:48 -08004622 \brief hdd_parse_channellist() - HDD Parse channel list
4623
4624 This function parses the channel list passed in the format
4625 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004626 if the Number of channels (N) does not match with the actual number of channels passed
4627 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4628 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4629 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4630 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004631
4632 \param - pValue Pointer to input channel list
4633 \param - ChannelList Pointer to local output array to record channel list
4634 \param - pNumChannels Pointer to number of roam scan channels
4635
4636 \return - 0 for success non-zero for failure
4637
4638 --------------------------------------------------------------------------*/
4639VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4640{
4641 tANI_U8 *inPtr = pValue;
4642 int tempInt;
4643 int j = 0;
4644 int v = 0;
4645 char buf[32];
4646
4647 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4648 /*no argument after the command*/
4649 if (NULL == inPtr)
4650 {
4651 return -EINVAL;
4652 }
4653
4654 /*no space after the command*/
4655 else if (SPACE_ASCII_VALUE != *inPtr)
4656 {
4657 return -EINVAL;
4658 }
4659
4660 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004661 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004662
4663 /*no argument followed by spaces*/
4664 if ('\0' == *inPtr)
4665 {
4666 return -EINVAL;
4667 }
4668
4669 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004670 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004671 if (1 != v) return -EINVAL;
4672
Srinivas Girigowdade697412013-02-14 16:31:48 -08004673 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004674 if ((v < 0) ||
4675 (tempInt <= 0) ||
4676 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4677 {
4678 return -EINVAL;
4679 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004680
4681 *pNumChannels = tempInt;
4682
4683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4684 "Number of channels are: %d", *pNumChannels);
4685
4686 for (j = 0; j < (*pNumChannels); j++)
4687 {
4688 /*inPtr pointing to the beginning of first space after number of channels*/
4689 inPtr = strpbrk( inPtr, " " );
4690 /*no channel list after the number of channels argument*/
4691 if (NULL == inPtr)
4692 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004693 if (0 != j)
4694 {
4695 *pNumChannels = j;
4696 return VOS_STATUS_SUCCESS;
4697 }
4698 else
4699 {
4700 return -EINVAL;
4701 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004702 }
4703
4704 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004705 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004706
4707 /*no channel list after the number of channels argument and spaces*/
4708 if ( '\0' == *inPtr )
4709 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004710 if (0 != j)
4711 {
4712 *pNumChannels = j;
4713 return VOS_STATUS_SUCCESS;
4714 }
4715 else
4716 {
4717 return -EINVAL;
4718 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004719 }
4720
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004721 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004722 if (1 != v) return -EINVAL;
4723
Srinivas Girigowdade697412013-02-14 16:31:48 -08004724 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004725 if ((v < 0) ||
4726 (tempInt <= 0) ||
4727 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4728 {
4729 return -EINVAL;
4730 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004731 pChannelList[j] = tempInt;
4732
4733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4734 "Channel %d added to preferred channel list",
4735 pChannelList[j] );
4736 }
4737
Srinivas Girigowdade697412013-02-14 16:31:48 -08004738 return VOS_STATUS_SUCCESS;
4739}
4740
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004741
4742/**---------------------------------------------------------------------------
4743
4744 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4745
4746 This function parses the reasoc command data passed in the format
4747 REASSOC<space><bssid><space><channel>
4748
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004749 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004750 \param - pTargetApBssid Pointer to target Ap bssid
4751 \param - pChannel Pointer to the Target AP channel
4752
4753 \return - 0 for success non-zero for failure
4754
4755 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004756VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4757 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004758{
4759 tANI_U8 *inPtr = pValue;
4760 int tempInt;
4761 int v = 0;
4762 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004763 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004764 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004765
4766 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4767 /*no argument after the command*/
4768 if (NULL == inPtr)
4769 {
4770 return -EINVAL;
4771 }
4772
4773 /*no space after the command*/
4774 else if (SPACE_ASCII_VALUE != *inPtr)
4775 {
4776 return -EINVAL;
4777 }
4778
4779 /*removing empty spaces*/
4780 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4781
4782 /*no argument followed by spaces*/
4783 if ('\0' == *inPtr)
4784 {
4785 return -EINVAL;
4786 }
4787
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004788 v = sscanf(inPtr, "%17s", macAddress);
4789 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004790 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4792 "Invalid MAC address or All hex inputs are not read (%d)", v);
4793 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004794 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004795
4796 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4797 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4798 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4799 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4800 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4801 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004802
4803 /* point to the next argument */
4804 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4805 /*no argument after the command*/
4806 if (NULL == inPtr) return -EINVAL;
4807
4808 /*removing empty spaces*/
4809 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4810
4811 /*no argument followed by spaces*/
4812 if ('\0' == *inPtr)
4813 {
4814 return -EINVAL;
4815 }
4816
4817 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004818 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004819 if (1 != v) return -EINVAL;
4820
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004821 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004822 if ((v < 0) ||
4823 (tempInt <= 0) ||
4824 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4825 {
4826 return -EINVAL;
4827 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004828
4829 *pChannel = tempInt;
4830 return VOS_STATUS_SUCCESS;
4831}
4832
4833#endif
4834
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004835#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004836/**---------------------------------------------------------------------------
4837
4838 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4839
4840 This function parses the SETCCKM IE command
4841 SETCCKMIE<space><ie data>
4842
4843 \param - pValue Pointer to input data
4844 \param - pCckmIe Pointer to output cckm Ie
4845 \param - pCckmIeLen Pointer to output cckm ie length
4846
4847 \return - 0 for success non-zero for failure
4848
4849 --------------------------------------------------------------------------*/
4850VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4851 tANI_U8 *pCckmIeLen)
4852{
4853 tANI_U8 *inPtr = pValue;
4854 tANI_U8 *dataEnd;
4855 int j = 0;
4856 int i = 0;
4857 tANI_U8 tempByte = 0;
4858
4859 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4860 /*no argument after the command*/
4861 if (NULL == inPtr)
4862 {
4863 return -EINVAL;
4864 }
4865
4866 /*no space after the command*/
4867 else if (SPACE_ASCII_VALUE != *inPtr)
4868 {
4869 return -EINVAL;
4870 }
4871
4872 /*removing empty spaces*/
4873 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4874
4875 /*no argument followed by spaces*/
4876 if ('\0' == *inPtr)
4877 {
4878 return -EINVAL;
4879 }
4880
4881 /* find the length of data */
4882 dataEnd = inPtr;
4883 while(('\0' != *dataEnd) )
4884 {
4885 dataEnd++;
4886 ++(*pCckmIeLen);
4887 }
4888 if ( *pCckmIeLen <= 0) return -EINVAL;
4889
4890 /* Allocate the number of bytes based on the number of input characters
4891 whether it is even or odd.
4892 if the number of input characters are even, then we need N/2 byte.
4893 if the number of input characters are odd, then we need do (N+1)/2 to
4894 compensate rounding off.
4895 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4896 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4897 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4898 if (NULL == *pCckmIe)
4899 {
4900 hddLog(VOS_TRACE_LEVEL_FATAL,
4901 "%s: vos_mem_alloc failed ", __func__);
4902 return -EINVAL;
4903 }
4904 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4905 /* the buffer received from the upper layer is character buffer,
4906 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4907 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4908 and f0 in 3rd location */
4909 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4910 {
4911 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4912 (*pCckmIe)[i++] = tempByte;
4913 }
4914 *pCckmIeLen = i;
4915
4916 return VOS_STATUS_SUCCESS;
4917}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004918#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004919
Jeff Johnson295189b2012-06-20 16:38:30 -07004920/**---------------------------------------------------------------------------
4921
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004922 \brief hdd_is_valid_mac_address() - Validate MAC address
4923
4924 This function validates whether the given MAC address is valid or not
4925 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4926 where X is the hexa decimal digit character and separated by ':'
4927 This algorithm works even if MAC address is not separated by ':'
4928
4929 This code checks given input string mac contains exactly 12 hexadecimal digits.
4930 and a separator colon : appears in the input string only after
4931 an even number of hex digits.
4932
4933 \param - pMacAddr pointer to the input MAC address
4934 \return - 1 for valid and 0 for invalid
4935
4936 --------------------------------------------------------------------------*/
4937
4938v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4939{
4940 int xdigit = 0;
4941 int separator = 0;
4942 while (*pMacAddr)
4943 {
4944 if (isxdigit(*pMacAddr))
4945 {
4946 xdigit++;
4947 }
4948 else if (':' == *pMacAddr)
4949 {
4950 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4951 break;
4952
4953 ++separator;
4954 }
4955 else
4956 {
4957 separator = -1;
4958 /* Invalid MAC found */
4959 return 0;
4960 }
4961 ++pMacAddr;
4962 }
4963 return (xdigit == 12 && (separator == 5 || separator == 0));
4964}
4965
4966/**---------------------------------------------------------------------------
4967
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 \brief hdd_open() - HDD Open function
4969
4970 This is called in response to ifconfig up
4971
4972 \param - dev Pointer to net_device structure
4973
4974 \return - 0 for success non-zero for failure
4975
4976 --------------------------------------------------------------------------*/
4977int hdd_open (struct net_device *dev)
4978{
4979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4980 hdd_context_t *pHddCtx;
4981 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4982 VOS_STATUS status;
4983 v_BOOL_t in_standby = TRUE;
4984
4985 if (NULL == pAdapter)
4986 {
4987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304988 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 return -ENODEV;
4990 }
4991
4992 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304993 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4994 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 if (NULL == pHddCtx)
4996 {
4997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004998 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004999 return -ENODEV;
5000 }
5001
5002 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5003 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5004 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005005 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5006 {
5007 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305008 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005009 in_standby = FALSE;
5010 break;
5011 }
5012 else
5013 {
5014 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5015 pAdapterNode = pNext;
5016 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 }
5018
5019 if (TRUE == in_standby)
5020 {
5021 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5022 {
5023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5024 "wlan out of power save", __func__);
5025 return -EINVAL;
5026 }
5027 }
5028
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005029 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005030 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5031 {
5032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005033 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005034 /* Enable TX queues only when we are connected */
5035 netif_tx_start_all_queues(dev);
5036 }
5037
5038 return 0;
5039}
5040
5041int hdd_mon_open (struct net_device *dev)
5042{
5043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5044
5045 if(pAdapter == NULL) {
5046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005047 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005048 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 }
5050
5051 netif_start_queue(dev);
5052
5053 return 0;
5054}
5055/**---------------------------------------------------------------------------
5056
5057 \brief hdd_stop() - HDD stop function
5058
5059 This is called in response to ifconfig down
5060
5061 \param - dev Pointer to net_device structure
5062
5063 \return - 0 for success non-zero for failure
5064
5065 --------------------------------------------------------------------------*/
5066
5067int hdd_stop (struct net_device *dev)
5068{
5069 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5070 hdd_context_t *pHddCtx;
5071 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5072 VOS_STATUS status;
5073 v_BOOL_t enter_standby = TRUE;
5074
5075 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 if (NULL == pAdapter)
5077 {
5078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305079 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 return -ENODEV;
5081 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305082 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5083 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5085 if (NULL == pHddCtx)
5086 {
5087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005088 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 return -ENODEV;
5090 }
5091
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005092 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
5094 netif_tx_disable(pAdapter->dev);
5095 netif_carrier_off(pAdapter->dev);
5096
5097
5098 /* SoftAP ifaces should never go in power save mode
5099 making sure same here. */
5100 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5101 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005103 )
5104 {
5105 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5107 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 EXIT();
5109 return 0;
5110 }
5111
5112 /* Find if any iface is up then
5113 if any iface is up then can't put device to sleep/ power save mode. */
5114 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5115 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5116 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005117 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5118 {
5119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305120 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005121 enter_standby = FALSE;
5122 break;
5123 }
5124 else
5125 {
5126 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5127 pAdapterNode = pNext;
5128 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 }
5130
5131 if (TRUE == enter_standby)
5132 {
5133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5134 "entering standby", __func__);
5135 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5136 {
5137 /*log and return success*/
5138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5139 "wlan in power save", __func__);
5140 }
5141 }
5142
5143 EXIT();
5144 return 0;
5145}
5146
5147/**---------------------------------------------------------------------------
5148
5149 \brief hdd_uninit() - HDD uninit function
5150
5151 This is called during the netdev unregister to uninitialize all data
5152associated with the device
5153
5154 \param - dev Pointer to net_device structure
5155
5156 \return - void
5157
5158 --------------------------------------------------------------------------*/
5159static void hdd_uninit (struct net_device *dev)
5160{
5161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5162
5163 ENTER();
5164
5165 do
5166 {
5167 if (NULL == pAdapter)
5168 {
5169 hddLog(VOS_TRACE_LEVEL_FATAL,
5170 "%s: NULL pAdapter", __func__);
5171 break;
5172 }
5173
5174 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5175 {
5176 hddLog(VOS_TRACE_LEVEL_FATAL,
5177 "%s: Invalid magic", __func__);
5178 break;
5179 }
5180
5181 if (NULL == pAdapter->pHddCtx)
5182 {
5183 hddLog(VOS_TRACE_LEVEL_FATAL,
5184 "%s: NULL pHddCtx", __func__);
5185 break;
5186 }
5187
5188 if (dev != pAdapter->dev)
5189 {
5190 hddLog(VOS_TRACE_LEVEL_FATAL,
5191 "%s: Invalid device reference", __func__);
5192 /* we haven't validated all cases so let this go for now */
5193 }
5194
5195 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5196
5197 /* after uninit our adapter structure will no longer be valid */
5198 pAdapter->dev = NULL;
5199 pAdapter->magic = 0;
5200 } while (0);
5201
5202 EXIT();
5203}
5204
5205/**---------------------------------------------------------------------------
5206
5207 \brief hdd_release_firmware() -
5208
5209 This function calls the release firmware API to free the firmware buffer.
5210
5211 \param - pFileName Pointer to the File Name.
5212 pCtx - Pointer to the adapter .
5213
5214
5215 \return - 0 for success, non zero for failure
5216
5217 --------------------------------------------------------------------------*/
5218
5219VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5220{
5221 VOS_STATUS status = VOS_STATUS_SUCCESS;
5222 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5223 ENTER();
5224
5225
5226 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5227
5228 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5229
5230 if(pHddCtx->fw) {
5231 release_firmware(pHddCtx->fw);
5232 pHddCtx->fw = NULL;
5233 }
5234 else
5235 status = VOS_STATUS_E_FAILURE;
5236 }
5237 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5238 if(pHddCtx->nv) {
5239 release_firmware(pHddCtx->nv);
5240 pHddCtx->nv = NULL;
5241 }
5242 else
5243 status = VOS_STATUS_E_FAILURE;
5244
5245 }
5246
5247 EXIT();
5248 return status;
5249}
5250
5251/**---------------------------------------------------------------------------
5252
5253 \brief hdd_request_firmware() -
5254
5255 This function reads the firmware file using the request firmware
5256 API and returns the the firmware data and the firmware file size.
5257
5258 \param - pfileName - Pointer to the file name.
5259 - pCtx - Pointer to the adapter .
5260 - ppfw_data - Pointer to the pointer of the firmware data.
5261 - pSize - Pointer to the file size.
5262
5263 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5264
5265 --------------------------------------------------------------------------*/
5266
5267
5268VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5269{
5270 int status;
5271 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5272 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5273 ENTER();
5274
5275 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5276
5277 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5278
5279 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5280 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5281 __func__, pfileName);
5282 retval = VOS_STATUS_E_FAILURE;
5283 }
5284
5285 else {
5286 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5287 *pSize = pHddCtx->fw->size;
5288 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5289 __func__, *pSize);
5290 }
5291 }
5292 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5293
5294 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5295
5296 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5297 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5298 __func__, pfileName);
5299 retval = VOS_STATUS_E_FAILURE;
5300 }
5301
5302 else {
5303 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5304 *pSize = pHddCtx->nv->size;
5305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5306 __func__, *pSize);
5307 }
5308 }
5309
5310 EXIT();
5311 return retval;
5312}
5313/**---------------------------------------------------------------------------
5314 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5315
5316 This is the function invoked by SME to inform the result of a full power
5317 request issued by HDD
5318
5319 \param - callbackcontext - Pointer to cookie
5320 status - result of request
5321
5322 \return - None
5323
5324--------------------------------------------------------------------------*/
5325void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5326{
5327 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5328
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005329 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005330 if(&pHddCtx->full_pwr_comp_var)
5331 {
5332 complete(&pHddCtx->full_pwr_comp_var);
5333 }
5334}
5335
5336/**---------------------------------------------------------------------------
5337
5338 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5339
5340 This is the function invoked by SME to inform the result of BMPS
5341 request issued by HDD
5342
5343 \param - callbackcontext - Pointer to cookie
5344 status - result of request
5345
5346 \return - None
5347
5348--------------------------------------------------------------------------*/
5349void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5350{
5351
5352 struct completion *completion_var = (struct completion*) callbackContext;
5353
Arif Hussain6d2a3322013-11-17 19:50:10 -08005354 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 if(completion_var != NULL)
5356 {
5357 complete(completion_var);
5358 }
5359}
5360
5361/**---------------------------------------------------------------------------
5362
5363 \brief hdd_get_cfg_file_size() -
5364
5365 This function reads the configuration file using the request firmware
5366 API and returns the configuration file size.
5367
5368 \param - pCtx - Pointer to the adapter .
5369 - pFileName - Pointer to the file name.
5370 - pBufSize - Pointer to the buffer size.
5371
5372 \return - 0 for success, non zero for failure
5373
5374 --------------------------------------------------------------------------*/
5375
5376VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5377{
5378 int status;
5379 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5380
5381 ENTER();
5382
5383 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5384
5385 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5386 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5387 status = VOS_STATUS_E_FAILURE;
5388 }
5389 else {
5390 *pBufSize = pHddCtx->fw->size;
5391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5392 release_firmware(pHddCtx->fw);
5393 pHddCtx->fw = NULL;
5394 }
5395
5396 EXIT();
5397 return VOS_STATUS_SUCCESS;
5398}
5399
5400/**---------------------------------------------------------------------------
5401
5402 \brief hdd_read_cfg_file() -
5403
5404 This function reads the configuration file using the request firmware
5405 API and returns the cfg data and the buffer size of the configuration file.
5406
5407 \param - pCtx - Pointer to the adapter .
5408 - pFileName - Pointer to the file name.
5409 - pBuffer - Pointer to the data buffer.
5410 - pBufSize - Pointer to the buffer size.
5411
5412 \return - 0 for success, non zero for failure
5413
5414 --------------------------------------------------------------------------*/
5415
5416VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5417 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5418{
5419 int status;
5420 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5421
5422 ENTER();
5423
5424 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5425
5426 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5427 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5428 return VOS_STATUS_E_FAILURE;
5429 }
5430 else {
5431 if(*pBufSize != pHddCtx->fw->size) {
5432 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5433 "file size", __func__);
5434 release_firmware(pHddCtx->fw);
5435 pHddCtx->fw = NULL;
5436 return VOS_STATUS_E_FAILURE;
5437 }
5438 else {
5439 if(pBuffer) {
5440 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5441 }
5442 release_firmware(pHddCtx->fw);
5443 pHddCtx->fw = NULL;
5444 }
5445 }
5446
5447 EXIT();
5448
5449 return VOS_STATUS_SUCCESS;
5450}
5451
5452/**---------------------------------------------------------------------------
5453
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 \brief hdd_set_mac_address() -
5455
5456 This function sets the user specified mac address using
5457 the command ifconfig wlanX hw ether <mac adress>.
5458
5459 \param - dev - Pointer to the net device.
5460 - addr - Pointer to the sockaddr.
5461 \return - 0 for success, non zero for failure
5462
5463 --------------------------------------------------------------------------*/
5464
5465static int hdd_set_mac_address(struct net_device *dev, void *addr)
5466{
5467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5468 struct sockaddr *psta_mac_addr = addr;
5469 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5470
5471 ENTER();
5472
5473 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5475
5476 EXIT();
5477 return halStatus;
5478}
5479
5480tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5481{
5482 int i;
5483 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5484 {
Abhishek Singheb183782014-02-06 13:37:21 +05305485 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 break;
5487 }
5488
5489 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5490 return NULL;
5491
5492 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5493 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5494}
5495
5496void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5497{
5498 int i;
5499 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5500 {
5501 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5502 {
5503 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5504 break;
5505 }
5506 }
5507 return;
5508}
5509
5510#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5511 static struct net_device_ops wlan_drv_ops = {
5512 .ndo_open = hdd_open,
5513 .ndo_stop = hdd_stop,
5514 .ndo_uninit = hdd_uninit,
5515 .ndo_start_xmit = hdd_hard_start_xmit,
5516 .ndo_tx_timeout = hdd_tx_timeout,
5517 .ndo_get_stats = hdd_stats,
5518 .ndo_do_ioctl = hdd_ioctl,
5519 .ndo_set_mac_address = hdd_set_mac_address,
5520 .ndo_select_queue = hdd_select_queue,
5521#ifdef WLAN_FEATURE_PACKET_FILTERING
5522#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5523 .ndo_set_rx_mode = hdd_set_multicast_list,
5524#else
5525 .ndo_set_multicast_list = hdd_set_multicast_list,
5526#endif //LINUX_VERSION_CODE
5527#endif
5528 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 static struct net_device_ops wlan_mon_drv_ops = {
5530 .ndo_open = hdd_mon_open,
5531 .ndo_stop = hdd_stop,
5532 .ndo_uninit = hdd_uninit,
5533 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5534 .ndo_tx_timeout = hdd_tx_timeout,
5535 .ndo_get_stats = hdd_stats,
5536 .ndo_do_ioctl = hdd_ioctl,
5537 .ndo_set_mac_address = hdd_set_mac_address,
5538 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005539
5540#endif
5541
5542void hdd_set_station_ops( struct net_device *pWlanDev )
5543{
5544#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 pWlanDev->netdev_ops = &wlan_drv_ops;
5546#else
5547 pWlanDev->open = hdd_open;
5548 pWlanDev->stop = hdd_stop;
5549 pWlanDev->uninit = hdd_uninit;
5550 pWlanDev->hard_start_xmit = NULL;
5551 pWlanDev->tx_timeout = hdd_tx_timeout;
5552 pWlanDev->get_stats = hdd_stats;
5553 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 pWlanDev->set_mac_address = hdd_set_mac_address;
5555#endif
5556}
5557
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005558static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005559{
5560 struct net_device *pWlanDev = NULL;
5561 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 /*
5563 * cfg80211 initialization and registration....
5564 */
5565 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5566
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 if(pWlanDev != NULL)
5568 {
5569
5570 //Save the pointer to the net_device in the HDD adapter
5571 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5572
Jeff Johnson295189b2012-06-20 16:38:30 -07005573 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5574
5575 pAdapter->dev = pWlanDev;
5576 pAdapter->pHddCtx = pHddCtx;
5577 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5578
5579 init_completion(&pAdapter->session_open_comp_var);
5580 init_completion(&pAdapter->session_close_comp_var);
5581 init_completion(&pAdapter->disconnect_comp_var);
5582 init_completion(&pAdapter->linkup_event_var);
5583 init_completion(&pAdapter->cancel_rem_on_chan_var);
5584 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305585 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5587 init_completion(&pAdapter->offchannel_tx_event);
5588#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005590#ifdef FEATURE_WLAN_TDLS
5591 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005592 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005593 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305594 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005595#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005596 init_completion(&pHddCtx->mc_sus_event_var);
5597 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305598 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005599 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005600 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005601
Rajeev79dbe4c2013-10-05 11:03:42 +05305602#ifdef FEATURE_WLAN_BATCH_SCAN
5603 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5604 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5605 pAdapter->pBatchScanRsp = NULL;
5606 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005607 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005608 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305609 mutex_init(&pAdapter->hdd_batch_scan_lock);
5610#endif
5611
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 pAdapter->isLinkUpSvcNeeded = FALSE;
5613 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5614 //Init the net_device structure
5615 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5616
5617 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5618 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5619 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5620 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5621
5622 hdd_set_station_ops( pAdapter->dev );
5623
5624 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5626 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5627 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 /* set pWlanDev's parent to underlying device */
5629 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5630 }
5631
5632 return pAdapter;
5633}
5634
5635VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5636{
5637 struct net_device *pWlanDev = pAdapter->dev;
5638 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5639 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5640 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5641
5642 if( rtnl_lock_held )
5643 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005644 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5646 {
5647 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5648 return VOS_STATUS_E_FAILURE;
5649 }
5650 }
5651 if (register_netdevice(pWlanDev))
5652 {
5653 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5654 return VOS_STATUS_E_FAILURE;
5655 }
5656 }
5657 else
5658 {
5659 if(register_netdev(pWlanDev))
5660 {
5661 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5662 return VOS_STATUS_E_FAILURE;
5663 }
5664 }
5665 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5666
5667 return VOS_STATUS_SUCCESS;
5668}
5669
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005670static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005671{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005672 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005673
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005674 if (NULL == pAdapter)
5675 {
5676 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5677 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005679
5680 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5681 {
5682 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5683 return eHAL_STATUS_NOT_INITIALIZED;
5684 }
5685
5686 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5687
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005688#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005689 /* need to make sure all of our scheduled work has completed.
5690 * This callback is called from MC thread context, so it is safe to
5691 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005692 *
5693 * Even though this is called from MC thread context, if there is a faulty
5694 * work item in the system, that can hang this call forever. So flushing
5695 * this global work queue is not safe; and now we make sure that
5696 * individual work queues are stopped correctly. But the cancel work queue
5697 * is a GPL only API, so the proprietary version of the driver would still
5698 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005699 */
5700 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005701#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005702
5703 /* We can be blocked while waiting for scheduled work to be
5704 * flushed, and the adapter structure can potentially be freed, in
5705 * which case the magic will have been reset. So make sure the
5706 * magic is still good, and hence the adapter structure is still
5707 * valid, before signaling completion */
5708 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5709 {
5710 complete(&pAdapter->session_close_comp_var);
5711 }
5712
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 return eHAL_STATUS_SUCCESS;
5714}
5715
5716VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5717{
5718 struct net_device *pWlanDev = pAdapter->dev;
5719 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5720 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5721 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5722 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305723 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005724
5725 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005726 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 //Open a SME session for future operation
5728 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005729 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5731 {
5732 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005733 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 halStatus, halStatus );
5735 status = VOS_STATUS_E_FAILURE;
5736 goto error_sme_open;
5737 }
5738
5739 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305740 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 &pAdapter->session_open_comp_var,
5742 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305743 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 {
5745 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305746 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005747 status = VOS_STATUS_E_FAILURE;
5748 goto error_sme_open;
5749 }
5750
5751 // Register wireless extensions
5752 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5753 {
5754 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005755 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 halStatus, halStatus );
5757 status = VOS_STATUS_E_FAILURE;
5758 goto error_register_wext;
5759 }
5760 //Safe to register the hard_start_xmit function again
5761#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5762 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5763#else
5764 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5765#endif
5766
5767 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305768 hddLog(VOS_TRACE_LEVEL_INFO,
5769 "%s: Set HDD connState to eConnectionState_NotConnected",
5770 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5772
5773 //Set the default operation channel
5774 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5775
5776 /* Make the default Auth Type as OPEN*/
5777 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5778
5779 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5780 {
5781 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005782 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 status, status );
5784 goto error_init_txrx;
5785 }
5786
5787 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5788
5789 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5790 {
5791 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005792 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 status, status );
5794 goto error_wmm_init;
5795 }
5796
5797 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5798
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005799#ifdef FEATURE_WLAN_TDLS
5800 if(0 != wlan_hdd_tdls_init(pAdapter))
5801 {
5802 status = VOS_STATUS_E_FAILURE;
5803 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5804 goto error_tdls_init;
5805 }
5806 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5807#endif
5808
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 return VOS_STATUS_SUCCESS;
5810
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005811#ifdef FEATURE_WLAN_TDLS
5812error_tdls_init:
5813 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5814 hdd_wmm_adapter_close(pAdapter);
5815#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005816error_wmm_init:
5817 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5818 hdd_deinit_tx_rx(pAdapter);
5819error_init_txrx:
5820 hdd_UnregisterWext(pWlanDev);
5821error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005822 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 {
5824 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005825 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005827 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305829 unsigned long rc;
5830
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305832 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005834 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305835 if (rc <= 0)
5836 hddLog(VOS_TRACE_LEVEL_ERROR,
5837 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 }
5839}
5840error_sme_open:
5841 return status;
5842}
5843
Jeff Johnson295189b2012-06-20 16:38:30 -07005844void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5845{
5846 hdd_cfg80211_state_t *cfgState;
5847
5848 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5849
5850 if( NULL != cfgState->buf )
5851 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305852 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5854 rc = wait_for_completion_interruptible_timeout(
5855 &pAdapter->tx_action_cnf_event,
5856 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305857 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305860 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5861 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 }
5863 }
5864 return;
5865}
Jeff Johnson295189b2012-06-20 16:38:30 -07005866
5867void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5868{
5869 ENTER();
5870 switch ( pAdapter->device_mode )
5871 {
5872 case WLAN_HDD_INFRA_STATION:
5873 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005874 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 {
5876 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5877 {
5878 hdd_deinit_tx_rx( pAdapter );
5879 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5880 }
5881
5882 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5883 {
5884 hdd_wmm_adapter_close( pAdapter );
5885 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5886 }
5887
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005889#ifdef FEATURE_WLAN_TDLS
5890 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5891 {
5892 wlan_hdd_tdls_exit(pAdapter);
5893 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5894 }
5895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005896
5897 break;
5898 }
5899
5900 case WLAN_HDD_SOFTAP:
5901 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305903
5904 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5905 {
5906 hdd_wmm_adapter_close( pAdapter );
5907 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5908 }
5909
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005911
5912 hdd_unregister_hostapd(pAdapter);
5913 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 break;
5916 }
5917
5918 case WLAN_HDD_MONITOR:
5919 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5922 {
5923 hdd_deinit_tx_rx( pAdapter );
5924 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 if(NULL != pAdapterforTx)
5927 {
5928 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 break;
5931 }
5932
5933
5934 default:
5935 break;
5936 }
5937
5938 EXIT();
5939}
5940
5941void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5942{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005943 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305944
5945 ENTER();
5946 if (NULL == pAdapter)
5947 {
5948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5949 "%s: HDD adapter is Null", __func__);
5950 return;
5951 }
5952
5953 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005954
Rajeev79dbe4c2013-10-05 11:03:42 +05305955#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305956 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5957 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005958 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305959 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5960 )
5961 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005962 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305963 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005964 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5965 {
5966 hdd_deinit_batch_scan(pAdapter);
5967 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305968 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005969 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305970#endif
5971
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5973 if( rtnl_held )
5974 {
5975 unregister_netdevice(pWlanDev);
5976 }
5977 else
5978 {
5979 unregister_netdev(pWlanDev);
5980 }
5981 // note that the pAdapter is no longer valid at this point
5982 // since the memory has been reclaimed
5983 }
5984
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305985 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005986}
5987
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005988void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5989{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305990 VOS_STATUS status;
5991 hdd_adapter_t *pAdapter = NULL;
5992 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005993
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305994 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005995
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305996 /*loop through all adapters.*/
5997 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005998 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305999 pAdapter = pAdapterNode->pAdapter;
6000 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6001 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006002
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306003 { // we skip this registration for modes other than STA and P2P client modes.
6004 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6005 pAdapterNode = pNext;
6006 continue;
6007 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006008
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306009 //Apply Dynamic DTIM For P2P
6010 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6011 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6012 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6013 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6014 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6015 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6016 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6017 (eConnectionState_Associated ==
6018 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6019 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6020 {
6021 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006022
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306023 powerRequest.uIgnoreDTIM = 1;
6024 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6025
6026 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6027 {
6028 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6029 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6030 }
6031 else
6032 {
6033 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6034 }
6035
6036 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6037 * specified during Enter/Exit BMPS when LCD off*/
6038 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6039 NULL, eANI_BOOLEAN_FALSE);
6040 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6041 NULL, eANI_BOOLEAN_FALSE);
6042
6043 /* switch to the DTIM specified in cfg.ini */
6044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6045 "Switch to DTIM %d", powerRequest.uListenInterval);
6046 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6047 break;
6048
6049 }
6050
6051 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6052 pAdapterNode = pNext;
6053 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006054}
6055
6056void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6057{
6058 /*Switch back to DTIM 1*/
6059 tSirSetPowerParamsReq powerRequest = { 0 };
6060
6061 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6062 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006063 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006064
6065 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6066 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6067 NULL, eANI_BOOLEAN_FALSE);
6068 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6069 NULL, eANI_BOOLEAN_FALSE);
6070
6071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6072 "Switch to DTIM%d",powerRequest.uListenInterval);
6073 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6074
6075}
6076
Jeff Johnson295189b2012-06-20 16:38:30 -07006077VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6078{
6079 VOS_STATUS status = VOS_STATUS_SUCCESS;
6080
6081 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6082 {
6083 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6084 }
6085
6086 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6087 {
6088 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6089 }
6090
6091 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6092 {
6093 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6094 }
6095
6096 return status;
6097}
6098
6099VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6100{
6101 hdd_adapter_t *pAdapter = NULL;
6102 eHalStatus halStatus;
6103 VOS_STATUS status = VOS_STATUS_E_INVAL;
6104 v_BOOL_t disableBmps = FALSE;
6105 v_BOOL_t disableImps = FALSE;
6106
6107 switch(session_type)
6108 {
6109 case WLAN_HDD_INFRA_STATION:
6110 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006111 case WLAN_HDD_P2P_CLIENT:
6112 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 //Exit BMPS -> Is Sta/P2P Client is already connected
6114 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6115 if((NULL != pAdapter)&&
6116 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6117 {
6118 disableBmps = TRUE;
6119 }
6120
6121 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6122 if((NULL != pAdapter)&&
6123 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6124 {
6125 disableBmps = TRUE;
6126 }
6127
6128 //Exit both Bmps and Imps incase of Go/SAP Mode
6129 if((WLAN_HDD_SOFTAP == session_type) ||
6130 (WLAN_HDD_P2P_GO == session_type))
6131 {
6132 disableBmps = TRUE;
6133 disableImps = TRUE;
6134 }
6135
6136 if(TRUE == disableImps)
6137 {
6138 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6139 {
6140 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6141 }
6142 }
6143
6144 if(TRUE == disableBmps)
6145 {
6146 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6147 {
6148 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6149
6150 if(eHAL_STATUS_SUCCESS != halStatus)
6151 {
6152 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006153 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006154 VOS_ASSERT(0);
6155 return status;
6156 }
6157 }
6158
6159 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6160 {
6161 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6162
6163 if(eHAL_STATUS_SUCCESS != halStatus)
6164 {
6165 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006166 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 VOS_ASSERT(0);
6168 return status;
6169 }
6170 }
6171 }
6172
6173 if((TRUE == disableBmps) ||
6174 (TRUE == disableImps))
6175 {
6176 /* Now, get the chip into Full Power now */
6177 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6178 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6179 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6180
6181 if(halStatus != eHAL_STATUS_SUCCESS)
6182 {
6183 if(halStatus == eHAL_STATUS_PMC_PENDING)
6184 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306185 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306187 ret = wait_for_completion_interruptible_timeout(
6188 &pHddCtx->full_pwr_comp_var,
6189 msecs_to_jiffies(1000));
6190 if (ret <= 0)
6191 {
6192 hddLog(VOS_TRACE_LEVEL_ERROR,
6193 "%s: wait on full_pwr_comp_var failed %ld",
6194 __func__, ret);
6195 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 }
6197 else
6198 {
6199 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006200 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 VOS_ASSERT(0);
6202 return status;
6203 }
6204 }
6205
6206 status = VOS_STATUS_SUCCESS;
6207 }
6208
6209 break;
6210 }
6211 return status;
6212}
6213
6214hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006215 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 tANI_U8 rtnl_held )
6217{
6218 hdd_adapter_t *pAdapter = NULL;
6219 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6220 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6221 VOS_STATUS exitbmpsStatus;
6222
Arif Hussain6d2a3322013-11-17 19:50:10 -08006223 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006224
Nirav Shah436658f2014-02-28 17:05:45 +05306225 if(macAddr == NULL)
6226 {
6227 /* Not received valid macAddr */
6228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6229 "%s:Unable to add virtual intf: Not able to get"
6230 "valid mac address",__func__);
6231 return NULL;
6232 }
6233
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 //Disable BMPS incase of Concurrency
6235 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6236
6237 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6238 {
6239 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306240 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 VOS_ASSERT(0);
6242 return NULL;
6243 }
6244
6245 switch(session_type)
6246 {
6247 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006249 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 {
6251 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6252
6253 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306254 {
6255 hddLog(VOS_TRACE_LEVEL_FATAL,
6256 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306258 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006259
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306260#ifdef FEATURE_WLAN_TDLS
6261 /* A Mutex Lock is introduced while changing/initializing the mode to
6262 * protect the concurrent access for the Adapters by TDLS module.
6263 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306264 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306265#endif
6266
Jeff Johnsone7245742012-09-05 17:12:55 -07006267 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6268 NL80211_IFTYPE_P2P_CLIENT:
6269 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006270
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306272#ifdef FEATURE_WLAN_TDLS
6273 mutex_unlock(&pHddCtx->tdls_lock);
6274#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306275
6276 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 if( VOS_STATUS_SUCCESS != status )
6278 goto err_free_netdev;
6279
6280 status = hdd_register_interface( pAdapter, rtnl_held );
6281 if( VOS_STATUS_SUCCESS != status )
6282 {
6283 hdd_deinit_adapter(pHddCtx, pAdapter);
6284 goto err_free_netdev;
6285 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306286
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306287 // Workqueue which gets scheduled in IPv4 notification callback.
6288 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6289
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306290#ifdef WLAN_NS_OFFLOAD
6291 // Workqueue which gets scheduled in IPv6 notification callback.
6292 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 //Stop the Interface TX queue.
6295 netif_tx_disable(pAdapter->dev);
6296 //netif_tx_disable(pWlanDev);
6297 netif_carrier_off(pAdapter->dev);
6298
6299 break;
6300 }
6301
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 case WLAN_HDD_SOFTAP:
6304 {
6305 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6306 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306307 {
6308 hddLog(VOS_TRACE_LEVEL_FATAL,
6309 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006312
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6314 NL80211_IFTYPE_AP:
6315 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 pAdapter->device_mode = session_type;
6317
6318 status = hdd_init_ap_mode(pAdapter);
6319 if( VOS_STATUS_SUCCESS != status )
6320 goto err_free_netdev;
6321
6322 status = hdd_register_hostapd( pAdapter, rtnl_held );
6323 if( VOS_STATUS_SUCCESS != status )
6324 {
6325 hdd_deinit_adapter(pHddCtx, pAdapter);
6326 goto err_free_netdev;
6327 }
6328
6329 netif_tx_disable(pAdapter->dev);
6330 netif_carrier_off(pAdapter->dev);
6331
6332 hdd_set_conparam( 1 );
6333 break;
6334 }
6335 case WLAN_HDD_MONITOR:
6336 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6338 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306339 {
6340 hddLog(VOS_TRACE_LEVEL_FATAL,
6341 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306343 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006344
6345 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6346 pAdapter->device_mode = session_type;
6347 status = hdd_register_interface( pAdapter, rtnl_held );
6348#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6349 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6350#else
6351 pAdapter->dev->open = hdd_mon_open;
6352 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6353#endif
6354 hdd_init_tx_rx( pAdapter );
6355 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6356 //Set adapter to be used for data tx. It will use either GO or softap.
6357 pAdapter->sessionCtx.monitor.pAdapterForTx =
6358 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6360 {
6361 pAdapter->sessionCtx.monitor.pAdapterForTx =
6362 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 /* This workqueue will be used to transmit management packet over
6365 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006366 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6367 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6368 return NULL;
6369 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006370
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6372 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 }
6374 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 case WLAN_HDD_FTM:
6376 {
6377 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6378
6379 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306380 {
6381 hddLog(VOS_TRACE_LEVEL_FATAL,
6382 FL("failed to allocate adapter for session %d"), session_type);
6383 return NULL;
6384 }
6385
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6387 * message while loading driver in FTM mode. */
6388 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6389 pAdapter->device_mode = session_type;
6390 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306391
6392 hdd_init_tx_rx( pAdapter );
6393
6394 //Stop the Interface TX queue.
6395 netif_tx_disable(pAdapter->dev);
6396 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 }
6398 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 default:
6400 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306401 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6402 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 VOS_ASSERT(0);
6404 return NULL;
6405 }
6406 }
6407
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 if( VOS_STATUS_SUCCESS == status )
6409 {
6410 //Add it to the hdd's session list.
6411 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6412 if( NULL == pHddAdapterNode )
6413 {
6414 status = VOS_STATUS_E_NOMEM;
6415 }
6416 else
6417 {
6418 pHddAdapterNode->pAdapter = pAdapter;
6419 status = hdd_add_adapter_back ( pHddCtx,
6420 pHddAdapterNode );
6421 }
6422 }
6423
6424 if( VOS_STATUS_SUCCESS != status )
6425 {
6426 if( NULL != pAdapter )
6427 {
6428 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6429 pAdapter = NULL;
6430 }
6431 if( NULL != pHddAdapterNode )
6432 {
6433 vos_mem_free( pHddAdapterNode );
6434 }
6435
6436 goto resume_bmps;
6437 }
6438
6439 if(VOS_STATUS_SUCCESS == status)
6440 {
6441 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6442
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006443 //Initialize the WoWL service
6444 if(!hdd_init_wowl(pAdapter))
6445 {
6446 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6447 goto err_free_netdev;
6448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 return pAdapter;
6451
6452err_free_netdev:
6453 free_netdev(pAdapter->dev);
6454 wlan_hdd_release_intf_addr( pHddCtx,
6455 pAdapter->macAddressCurrent.bytes );
6456
6457resume_bmps:
6458 //If bmps disabled enable it
6459 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6460 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306461 if (pHddCtx->hdd_wlan_suspended)
6462 {
6463 hdd_set_pwrparams(pHddCtx);
6464 }
6465 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 }
6467 return NULL;
6468}
6469
6470VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6471 tANI_U8 rtnl_held )
6472{
6473 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6474 VOS_STATUS status;
6475
6476 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6477 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306478 {
6479 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6480 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306482 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006483
6484 while ( pCurrent->pAdapter != pAdapter )
6485 {
6486 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6487 if( VOS_STATUS_SUCCESS != status )
6488 break;
6489
6490 pCurrent = pNext;
6491 }
6492 pAdapterNode = pCurrent;
6493 if( VOS_STATUS_SUCCESS == status )
6494 {
6495 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6496 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306497
6498#ifdef FEATURE_WLAN_TDLS
6499
6500 /* A Mutex Lock is introduced while changing/initializing the mode to
6501 * protect the concurrent access for the Adapters by TDLS module.
6502 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306503 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306504#endif
6505
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 hdd_remove_adapter( pHddCtx, pAdapterNode );
6507 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006508 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006509
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306510#ifdef FEATURE_WLAN_TDLS
6511 mutex_unlock(&pHddCtx->tdls_lock);
6512#endif
6513
Jeff Johnson295189b2012-06-20 16:38:30 -07006514
6515 /* If there is a single session of STA/P2P client, re-enable BMPS */
6516 if ((!vos_concurrent_sessions_running()) &&
6517 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6518 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6519 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306520 if (pHddCtx->hdd_wlan_suspended)
6521 {
6522 hdd_set_pwrparams(pHddCtx);
6523 }
6524 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 }
6526
6527 return VOS_STATUS_SUCCESS;
6528 }
6529
6530 return VOS_STATUS_E_FAILURE;
6531}
6532
6533VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6534{
6535 hdd_adapter_list_node_t *pHddAdapterNode;
6536 VOS_STATUS status;
6537
6538 ENTER();
6539
6540 do
6541 {
6542 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6543 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6544 {
6545 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6546 vos_mem_free( pHddAdapterNode );
6547 }
6548 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6549
6550 EXIT();
6551
6552 return VOS_STATUS_SUCCESS;
6553}
6554
6555void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6556{
6557 v_U8_t addIE[1] = {0};
6558
6559 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6560 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6561 eANI_BOOLEAN_FALSE) )
6562 {
6563 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006564 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 }
6566
6567 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6568 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6569 eANI_BOOLEAN_FALSE) )
6570 {
6571 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006572 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 }
6574
6575 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6576 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6577 eANI_BOOLEAN_FALSE) )
6578 {
6579 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006580 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 }
6582}
6583
6584VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6585{
6586 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6587 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6588 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306589 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306590 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006591
6592 ENTER();
6593
6594 switch(pAdapter->device_mode)
6595 {
6596 case WLAN_HDD_INFRA_STATION:
6597 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006598 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306599 {
6600 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6601 if( hdd_connIsConnected(pstation) ||
6602 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 {
6604 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6605 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6606 pAdapter->sessionId,
6607 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6608 else
6609 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6610 pAdapter->sessionId,
6611 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6612 //success implies disconnect command got queued up successfully
6613 if(halStatus == eHAL_STATUS_SUCCESS)
6614 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306615 ret = wait_for_completion_interruptible_timeout(
6616 &pAdapter->disconnect_comp_var,
6617 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6618 if (ret <= 0)
6619 {
6620 hddLog(VOS_TRACE_LEVEL_ERROR,
6621 "%s: wait on disconnect_comp_var failed %ld",
6622 __func__, ret);
6623 }
6624 }
6625 else
6626 {
6627 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6628 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 }
6630 memset(&wrqu, '\0', sizeof(wrqu));
6631 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6632 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6633 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6634 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306635 else if(pstation->conn_info.connState ==
6636 eConnectionState_Disconnecting)
6637 {
6638 ret = wait_for_completion_interruptible_timeout(
6639 &pAdapter->disconnect_comp_var,
6640 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6641 if (ret <= 0)
6642 {
6643 hddLog(VOS_TRACE_LEVEL_ERROR,
6644 FL("wait on disconnect_comp_var failed %ld"), ret);
6645 }
6646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 else
6648 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306649 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6650 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306652 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6653 {
6654 while (pAdapter->is_roc_inprogress)
6655 {
6656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6657 "%s: ROC in progress for session %d!!!",
6658 __func__, pAdapter->sessionId);
6659 // waiting for ROC to expire
6660 msleep(500);
6661 /* In GO present case , if retry exceeds 3,
6662 it means something went wrong. */
6663 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6664 {
6665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6666 "%s: ROC completion is not received.!!!", __func__);
6667 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6668 pAdapter->sessionId);
6669 wait_for_completion_interruptible_timeout(
6670 &pAdapter->cancel_rem_on_chan_var,
6671 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6672 break;
6673 }
6674 }
6675 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306676#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306677#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306678 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6679#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306680 if (pAdapter->ipv6_notifier_registered)
6681 {
6682 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6683 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6684 pAdapter->ipv6_notifier_registered = false;
6685 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306686#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306687 if (pAdapter->ipv4_notifier_registered)
6688 {
6689 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6690 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6691 pAdapter->ipv4_notifier_registered = false;
6692 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306693#ifdef WLAN_OPEN_SOURCE
6694 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6695#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006696 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6697 {
6698 INIT_COMPLETION(pAdapter->session_close_comp_var);
6699 if (eHAL_STATUS_SUCCESS ==
6700 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6701 hdd_smeCloseSessionCallback, pAdapter))
6702 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306703 unsigned long ret;
6704
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306706 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 &pAdapter->session_close_comp_var,
6708 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306709 if ( 0 >= ret)
6710 {
6711 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6712 __func__, ret);
6713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006714 }
6715 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306716 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006717 break;
6718
6719 case WLAN_HDD_SOFTAP:
6720 case WLAN_HDD_P2P_GO:
6721 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306722 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6723 while (pAdapter->is_roc_inprogress) {
6724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6725 "%s: ROC in progress for session %d!!!",
6726 __func__, pAdapter->sessionId);
6727 msleep(500);
6728 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6730 "%s: ROC completion is not received.!!!", __func__);
6731 WLANSAP_CancelRemainOnChannel(
6732 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6733 wait_for_completion_interruptible_timeout(
6734 &pAdapter->cancel_rem_on_chan_var,
6735 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6736 break;
6737 }
6738 }
6739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 mutex_lock(&pHddCtx->sap_lock);
6741 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6742 {
6743 VOS_STATUS status;
6744 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6745
6746 //Stop Bss.
6747 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6748 if (VOS_IS_STATUS_SUCCESS(status))
6749 {
6750 hdd_hostapd_state_t *pHostapdState =
6751 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6752
6753 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6754
6755 if (!VOS_IS_STATUS_SUCCESS(status))
6756 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306757 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6758 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 }
6760 }
6761 else
6762 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006763 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 }
6765 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6766
6767 if (eHAL_STATUS_FAILURE ==
6768 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6769 0, NULL, eANI_BOOLEAN_FALSE))
6770 {
6771 hddLog(LOGE,
6772 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006773 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 }
6775
6776 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6777 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6778 eANI_BOOLEAN_FALSE) )
6779 {
6780 hddLog(LOGE,
6781 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6782 }
6783
6784 // Reset WNI_CFG_PROBE_RSP Flags
6785 wlan_hdd_reset_prob_rspies(pAdapter);
6786 kfree(pAdapter->sessionCtx.ap.beacon);
6787 pAdapter->sessionCtx.ap.beacon = NULL;
6788 }
6789 mutex_unlock(&pHddCtx->sap_lock);
6790 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006791
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006793#ifdef WLAN_OPEN_SOURCE
6794 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6795#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006797
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 default:
6799 break;
6800 }
6801
6802 EXIT();
6803 return VOS_STATUS_SUCCESS;
6804}
6805
6806VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6807{
6808 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6809 VOS_STATUS status;
6810 hdd_adapter_t *pAdapter;
6811
6812 ENTER();
6813
6814 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6815
6816 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6817 {
6818 pAdapter = pAdapterNode->pAdapter;
6819 netif_tx_disable(pAdapter->dev);
6820 netif_carrier_off(pAdapter->dev);
6821
6822 hdd_stop_adapter( pHddCtx, pAdapter );
6823
6824 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6825 pAdapterNode = pNext;
6826 }
6827
6828 EXIT();
6829
6830 return VOS_STATUS_SUCCESS;
6831}
6832
Rajeev Kumarf999e582014-01-09 17:33:29 -08006833
6834#ifdef FEATURE_WLAN_BATCH_SCAN
6835/**---------------------------------------------------------------------------
6836
6837 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6838 structures
6839
6840 \param - pAdapter Pointer to HDD adapter
6841
6842 \return - None
6843
6844 --------------------------------------------------------------------------*/
6845void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6846{
6847 tHddBatchScanRsp *pNode;
6848 tHddBatchScanRsp *pPrev;
6849
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306850 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006851 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306852 hddLog(VOS_TRACE_LEVEL_ERROR,
6853 "%s: Adapter context is Null", __func__);
6854 return;
6855 }
6856
6857 pNode = pAdapter->pBatchScanRsp;
6858 while (pNode)
6859 {
6860 pPrev = pNode;
6861 pNode = pNode->pNext;
6862 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006863 }
6864
6865 pAdapter->pBatchScanRsp = NULL;
6866 pAdapter->numScanList = 0;
6867 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6868 pAdapter->prev_batch_id = 0;
6869
6870 return;
6871}
6872#endif
6873
6874
Jeff Johnson295189b2012-06-20 16:38:30 -07006875VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6876{
6877 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6878 VOS_STATUS status;
6879 hdd_adapter_t *pAdapter;
6880
6881 ENTER();
6882
6883 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6884
6885 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6886 {
6887 pAdapter = pAdapterNode->pAdapter;
6888 netif_tx_disable(pAdapter->dev);
6889 netif_carrier_off(pAdapter->dev);
6890
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006891 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6892
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306894 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6895 {
6896 hdd_wmm_adapter_close( pAdapter );
6897 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6898 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006899
Rajeev Kumarf999e582014-01-09 17:33:29 -08006900#ifdef FEATURE_WLAN_BATCH_SCAN
6901 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6902 {
6903 hdd_deinit_batch_scan(pAdapter);
6904 }
6905#endif
6906
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6908 pAdapterNode = pNext;
6909 }
6910
6911 EXIT();
6912
6913 return VOS_STATUS_SUCCESS;
6914}
6915
6916VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6917{
6918 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6919 VOS_STATUS status;
6920 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306921 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006922
6923 ENTER();
6924
6925 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6926
6927 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6928 {
6929 pAdapter = pAdapterNode->pAdapter;
6930
6931 switch(pAdapter->device_mode)
6932 {
6933 case WLAN_HDD_INFRA_STATION:
6934 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006935 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306936
6937 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6938
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 hdd_init_station_mode(pAdapter);
6940 /* Open the gates for HDD to receive Wext commands */
6941 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006942 pHddCtx->scan_info.mScanPending = FALSE;
6943 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006944
6945 //Trigger the initial scan
6946 hdd_wlan_initial_scan(pAdapter);
6947
6948 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306949 if (eConnectionState_Associated == connState ||
6950 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 {
6952 union iwreq_data wrqu;
6953 memset(&wrqu, '\0', sizeof(wrqu));
6954 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6955 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6956 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006957 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006958
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 /* indicate disconnected event to nl80211 */
6960 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6961 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006962 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306963 else if (eConnectionState_Connecting == connState)
6964 {
6965 /*
6966 * Indicate connect failure to supplicant if we were in the
6967 * process of connecting
6968 */
6969 cfg80211_connect_result(pAdapter->dev, NULL,
6970 NULL, 0, NULL, 0,
6971 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6972 GFP_KERNEL);
6973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 break;
6975
6976 case WLAN_HDD_SOFTAP:
6977 /* softAP can handle SSR */
6978 break;
6979
6980 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006983 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 break;
6985
6986 case WLAN_HDD_MONITOR:
6987 /* monitor interface start */
6988 break;
6989 default:
6990 break;
6991 }
6992
6993 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6994 pAdapterNode = pNext;
6995 }
6996
6997 EXIT();
6998
6999 return VOS_STATUS_SUCCESS;
7000}
7001
7002VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7003{
7004 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7005 hdd_adapter_t *pAdapter;
7006 VOS_STATUS status;
7007 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307008 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007009
7010 ENTER();
7011
7012 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7013
7014 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7015 {
7016 pAdapter = pAdapterNode->pAdapter;
7017
7018 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7019 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7020 {
7021 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7022 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7023
Abhishek Singhf4669da2014-05-26 15:07:49 +05307024 hddLog(VOS_TRACE_LEVEL_INFO,
7025 "%s: Set HDD connState to eConnectionState_NotConnected",
7026 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7028 init_completion(&pAdapter->disconnect_comp_var);
7029 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7030 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7031
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307032 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 &pAdapter->disconnect_comp_var,
7034 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307035 if (0 >= ret)
7036 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7037 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007038
7039 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7040 pHddCtx->isAmpAllowed = VOS_FALSE;
7041 sme_RoamConnect(pHddCtx->hHal,
7042 pAdapter->sessionId, &(pWextState->roamProfile),
7043 &roamId);
7044 }
7045
7046 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7047 pAdapterNode = pNext;
7048 }
7049
7050 EXIT();
7051
7052 return VOS_STATUS_SUCCESS;
7053}
7054
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007055void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7056{
7057 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7058 VOS_STATUS status;
7059 hdd_adapter_t *pAdapter;
7060 hdd_station_ctx_t *pHddStaCtx;
7061 hdd_ap_ctx_t *pHddApCtx;
7062 hdd_hostapd_state_t * pHostapdState;
7063 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7064 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7065 const char *p2pMode = "DEV";
7066 const char *ccMode = "Standalone";
7067 int n;
7068
7069 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7070 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7071 {
7072 pAdapter = pAdapterNode->pAdapter;
7073 switch (pAdapter->device_mode) {
7074 case WLAN_HDD_INFRA_STATION:
7075 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7076 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7077 staChannel = pHddStaCtx->conn_info.operationChannel;
7078 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7079 }
7080 break;
7081 case WLAN_HDD_P2P_CLIENT:
7082 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7083 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7084 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7085 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7086 p2pMode = "CLI";
7087 }
7088 break;
7089 case WLAN_HDD_P2P_GO:
7090 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7091 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7092 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7093 p2pChannel = pHddApCtx->operatingChannel;
7094 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7095 }
7096 p2pMode = "GO";
7097 break;
7098 case WLAN_HDD_SOFTAP:
7099 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7100 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7101 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7102 apChannel = pHddApCtx->operatingChannel;
7103 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7104 }
7105 break;
7106 default:
7107 break;
7108 }
7109 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7110 pAdapterNode = pNext;
7111 }
7112 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7113 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7114 }
7115 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7116 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7117 if (p2pChannel > 0) {
7118 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7119 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7120 }
7121 if (apChannel > 0) {
7122 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7123 apChannel, MAC_ADDR_ARRAY(apBssid));
7124 }
7125
7126 if (p2pChannel > 0 && apChannel > 0) {
7127 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7128 }
7129}
7130
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007131bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007132{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007133 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007134}
7135
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007136/* Once SSR is disabled then it cannot be set. */
7137void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007138{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007139 if (HDD_SSR_DISABLED == isSsrRequired)
7140 return;
7141
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 isSsrRequired = value;
7143}
7144
7145VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7146 hdd_adapter_list_node_t** ppAdapterNode)
7147{
7148 VOS_STATUS status;
7149 spin_lock(&pHddCtx->hddAdapters.lock);
7150 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7151 (hdd_list_node_t**) ppAdapterNode );
7152 spin_unlock(&pHddCtx->hddAdapters.lock);
7153 return status;
7154}
7155
7156VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7157 hdd_adapter_list_node_t* pAdapterNode,
7158 hdd_adapter_list_node_t** pNextAdapterNode)
7159{
7160 VOS_STATUS status;
7161 spin_lock(&pHddCtx->hddAdapters.lock);
7162 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7163 (hdd_list_node_t*) pAdapterNode,
7164 (hdd_list_node_t**)pNextAdapterNode );
7165
7166 spin_unlock(&pHddCtx->hddAdapters.lock);
7167 return status;
7168}
7169
7170VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7171 hdd_adapter_list_node_t* pAdapterNode)
7172{
7173 VOS_STATUS status;
7174 spin_lock(&pHddCtx->hddAdapters.lock);
7175 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7176 &pAdapterNode->node );
7177 spin_unlock(&pHddCtx->hddAdapters.lock);
7178 return status;
7179}
7180
7181VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7182 hdd_adapter_list_node_t** ppAdapterNode)
7183{
7184 VOS_STATUS status;
7185 spin_lock(&pHddCtx->hddAdapters.lock);
7186 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7187 (hdd_list_node_t**) ppAdapterNode );
7188 spin_unlock(&pHddCtx->hddAdapters.lock);
7189 return status;
7190}
7191
7192VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7193 hdd_adapter_list_node_t* pAdapterNode)
7194{
7195 VOS_STATUS status;
7196 spin_lock(&pHddCtx->hddAdapters.lock);
7197 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7198 (hdd_list_node_t*) pAdapterNode );
7199 spin_unlock(&pHddCtx->hddAdapters.lock);
7200 return status;
7201}
7202
7203VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7204 hdd_adapter_list_node_t* pAdapterNode)
7205{
7206 VOS_STATUS status;
7207 spin_lock(&pHddCtx->hddAdapters.lock);
7208 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7209 (hdd_list_node_t*) pAdapterNode );
7210 spin_unlock(&pHddCtx->hddAdapters.lock);
7211 return status;
7212}
7213
7214hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7215 tSirMacAddr macAddr )
7216{
7217 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7218 hdd_adapter_t *pAdapter;
7219 VOS_STATUS status;
7220
7221 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7222
7223 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7224 {
7225 pAdapter = pAdapterNode->pAdapter;
7226
7227 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7228 macAddr, sizeof(tSirMacAddr) ) )
7229 {
7230 return pAdapter;
7231 }
7232 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7233 pAdapterNode = pNext;
7234 }
7235
7236 return NULL;
7237
7238}
7239
7240hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7241{
7242 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7243 hdd_adapter_t *pAdapter;
7244 VOS_STATUS status;
7245
7246 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7247
7248 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7249 {
7250 pAdapter = pAdapterNode->pAdapter;
7251
7252 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7253 IFNAMSIZ ) )
7254 {
7255 return pAdapter;
7256 }
7257 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7258 pAdapterNode = pNext;
7259 }
7260
7261 return NULL;
7262
7263}
7264
7265hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7266{
7267 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7268 hdd_adapter_t *pAdapter;
7269 VOS_STATUS status;
7270
7271 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7272
7273 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7274 {
7275 pAdapter = pAdapterNode->pAdapter;
7276
7277 if( pAdapter && (mode == pAdapter->device_mode) )
7278 {
7279 return pAdapter;
7280 }
7281 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7282 pAdapterNode = pNext;
7283 }
7284
7285 return NULL;
7286
7287}
7288
7289//Remove this function later
7290hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7291{
7292 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7293 hdd_adapter_t *pAdapter;
7294 VOS_STATUS status;
7295
7296 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7297
7298 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7299 {
7300 pAdapter = pAdapterNode->pAdapter;
7301
7302 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7303 {
7304 return pAdapter;
7305 }
7306
7307 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7308 pAdapterNode = pNext;
7309 }
7310
7311 return NULL;
7312
7313}
7314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315/**---------------------------------------------------------------------------
7316
7317 \brief hdd_set_monitor_tx_adapter() -
7318
7319 This API initializes the adapter to be used while transmitting on monitor
7320 adapter.
7321
7322 \param - pHddCtx - Pointer to the HDD context.
7323 pAdapter - Adapter that will used for TX. This can be NULL.
7324 \return - None.
7325 --------------------------------------------------------------------------*/
7326void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7327{
7328 hdd_adapter_t *pMonAdapter;
7329
7330 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7331
7332 if( NULL != pMonAdapter )
7333 {
7334 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7335 }
7336}
Jeff Johnson295189b2012-06-20 16:38:30 -07007337/**---------------------------------------------------------------------------
7338
7339 \brief hdd_select_queue() -
7340
7341 This API returns the operating channel of the requested device mode
7342
7343 \param - pHddCtx - Pointer to the HDD context.
7344 - mode - Device mode for which operating channel is required
7345 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7346 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7347 \return - channel number. "0" id the requested device is not found OR it is not connected.
7348 --------------------------------------------------------------------------*/
7349v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7350{
7351 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7352 VOS_STATUS status;
7353 hdd_adapter_t *pAdapter;
7354 v_U8_t operatingChannel = 0;
7355
7356 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7357
7358 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7359 {
7360 pAdapter = pAdapterNode->pAdapter;
7361
7362 if( mode == pAdapter->device_mode )
7363 {
7364 switch(pAdapter->device_mode)
7365 {
7366 case WLAN_HDD_INFRA_STATION:
7367 case WLAN_HDD_P2P_CLIENT:
7368 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7369 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7370 break;
7371 case WLAN_HDD_SOFTAP:
7372 case WLAN_HDD_P2P_GO:
7373 /*softap connection info */
7374 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7375 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7376 break;
7377 default:
7378 break;
7379 }
7380
7381 break; //Found the device of interest. break the loop
7382 }
7383
7384 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7385 pAdapterNode = pNext;
7386 }
7387 return operatingChannel;
7388}
7389
7390#ifdef WLAN_FEATURE_PACKET_FILTERING
7391/**---------------------------------------------------------------------------
7392
7393 \brief hdd_set_multicast_list() -
7394
7395 This used to set the multicast address list.
7396
7397 \param - dev - Pointer to the WLAN device.
7398 - skb - Pointer to OS packet (sk_buff).
7399 \return - success/fail
7400
7401 --------------------------------------------------------------------------*/
7402static void hdd_set_multicast_list(struct net_device *dev)
7403{
7404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007405 int mc_count;
7406 int i = 0;
7407 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307408
7409 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 {
7411 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307412 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 return;
7414 }
7415
7416 if (dev->flags & IFF_ALLMULTI)
7417 {
7418 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007419 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307420 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 }
7422 else
7423 {
7424 mc_count = netdev_mc_count(dev);
7425 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007426 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7428 {
7429 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007430 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307431 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 return;
7433 }
7434
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307435 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007436
7437 netdev_for_each_mc_addr(ha, dev) {
7438 if (i == mc_count)
7439 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307440 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7441 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007442 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307444 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 i++;
7446 }
7447 }
7448 return;
7449}
7450#endif
7451
7452/**---------------------------------------------------------------------------
7453
7454 \brief hdd_select_queue() -
7455
7456 This function is registered with the Linux OS for network
7457 core to decide which queue to use first.
7458
7459 \param - dev - Pointer to the WLAN device.
7460 - skb - Pointer to OS packet (sk_buff).
7461 \return - ac, Queue Index/access category corresponding to UP in IP header
7462
7463 --------------------------------------------------------------------------*/
7464v_U16_t hdd_select_queue(struct net_device *dev,
7465 struct sk_buff *skb)
7466{
7467 return hdd_wmm_select_queue(dev, skb);
7468}
7469
7470
7471/**---------------------------------------------------------------------------
7472
7473 \brief hdd_wlan_initial_scan() -
7474
7475 This function triggers the initial scan
7476
7477 \param - pAdapter - Pointer to the HDD adapter.
7478
7479 --------------------------------------------------------------------------*/
7480void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7481{
7482 tCsrScanRequest scanReq;
7483 tCsrChannelInfo channelInfo;
7484 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007485 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7487
7488 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7489 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7490 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7491
7492 if(sme_Is11dSupported(pHddCtx->hHal))
7493 {
7494 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7495 if ( HAL_STATUS_SUCCESS( halStatus ) )
7496 {
7497 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7498 if( !scanReq.ChannelInfo.ChannelList )
7499 {
7500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7501 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007502 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 return;
7504 }
7505 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7506 channelInfo.numOfChannels);
7507 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7508 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007509 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007510 }
7511
7512 scanReq.scanType = eSIR_PASSIVE_SCAN;
7513 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7514 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7515 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7516 }
7517 else
7518 {
7519 scanReq.scanType = eSIR_ACTIVE_SCAN;
7520 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7521 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7522 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7523 }
7524
7525 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7526 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7527 {
7528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7529 __func__, halStatus );
7530 }
7531
7532 if(sme_Is11dSupported(pHddCtx->hHal))
7533 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7534}
7535
Jeff Johnson295189b2012-06-20 16:38:30 -07007536/**---------------------------------------------------------------------------
7537
7538 \brief hdd_full_power_callback() - HDD full power callback function
7539
7540 This is the function invoked by SME to inform the result of a full power
7541 request issued by HDD
7542
7543 \param - callbackcontext - Pointer to cookie
7544 \param - status - result of request
7545
7546 \return - None
7547
7548 --------------------------------------------------------------------------*/
7549static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7550{
Jeff Johnson72a40512013-12-19 10:14:15 -08007551 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007552
7553 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307554 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007555
7556 if (NULL == callbackContext)
7557 {
7558 hddLog(VOS_TRACE_LEVEL_ERROR,
7559 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007560 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 return;
7562 }
7563
Jeff Johnson72a40512013-12-19 10:14:15 -08007564 /* there is a race condition that exists between this callback
7565 function and the caller since the caller could time out either
7566 before or while this code is executing. we use a spinlock to
7567 serialize these actions */
7568 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007569
7570 if (POWER_CONTEXT_MAGIC != pContext->magic)
7571 {
7572 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007573 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007574 hddLog(VOS_TRACE_LEVEL_WARN,
7575 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007576 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007577 return;
7578 }
7579
Jeff Johnson72a40512013-12-19 10:14:15 -08007580 /* context is valid so caller is still waiting */
7581
7582 /* paranoia: invalidate the magic */
7583 pContext->magic = 0;
7584
7585 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007587
7588 /* serialization is complete */
7589 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007590}
7591
7592/**---------------------------------------------------------------------------
7593
7594 \brief hdd_wlan_exit() - HDD WLAN exit function
7595
7596 This is the driver exit point (invoked during rmmod)
7597
7598 \param - pHddCtx - Pointer to the HDD Context
7599
7600 \return - None
7601
7602 --------------------------------------------------------------------------*/
7603void hdd_wlan_exit(hdd_context_t *pHddCtx)
7604{
7605 eHalStatus halStatus;
7606 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7607 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307608 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007609 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007610 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 long lrc;
7612
7613 ENTER();
7614
Jeff Johnson88ba7742013-02-27 14:36:02 -08007615 if (VOS_FTM_MODE != hdd_get_conparam())
7616 {
7617 // Unloading, restart logic is no more required.
7618 wlan_hdd_restart_deinit(pHddCtx);
7619 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007620
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007623 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 {
7625 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7626 WLAN_HDD_INFRA_STATION);
7627 if (pAdapter == NULL)
7628 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7629
7630 if (pAdapter != NULL)
7631 {
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307632 wlan_hdd_cfg80211_deregister_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 hdd_UnregisterWext(pAdapter->dev);
7634 }
7635 }
7636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007637
Jeff Johnson295189b2012-06-20 16:38:30 -07007638 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007639 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307640 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007641 wlan_hdd_ftm_close(pHddCtx);
7642 goto free_hdd_ctx;
7643 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 //Stop the Interface TX queue.
7645 //netif_tx_disable(pWlanDev);
7646 //netif_carrier_off(pWlanDev);
7647
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7649 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307650 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 pAdapter = hdd_get_adapter(pHddCtx,
7652 WLAN_HDD_SOFTAP);
7653 }
7654 else
7655 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307658 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 pAdapter = hdd_get_adapter(pHddCtx,
7660 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007661 if (pAdapter == NULL)
7662 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307665
7666 if(NULL == pAdapter)
7667 {
7668 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7669 goto free_hdd_ctx;
7670 }
7671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 /* DeRegister with platform driver as client for Suspend/Resume */
7673 vosStatus = hddDeregisterPmOps(pHddCtx);
7674 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7675 {
7676 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7677 VOS_ASSERT(0);
7678 }
7679
7680 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7681 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7682 {
7683 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007685
7686 // Cancel any outstanding scan requests. We are about to close all
7687 // of our adapters, but an adapter structure is what SME passes back
7688 // to our callback function. Hence if there are any outstanding scan
7689 // requests then there is a race condition between when the adapter
7690 // is closed and when the callback is invoked. We try to resolve that
7691 // race condition here by canceling any outstanding scans before we
7692 // close the adapters.
7693 // Note that the scans may be cancelled in an asynchronous manner, so
7694 // ideally there needs to be some kind of synchronization. Rather than
7695 // introduce a new synchronization here, we will utilize the fact that
7696 // we are about to Request Full Power, and since that is synchronized,
7697 // the expectation is that by the time Request Full Power has completed,
7698 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007699 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307700 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007701 else
7702 hddLog(VOS_TRACE_LEVEL_ERROR,
7703 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007704
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007705 //Stop the traffic monitor timer
7706 if ( VOS_TIMER_STATE_RUNNING ==
7707 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7708 {
7709 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7710 }
7711
7712 // Destroy the traffic monitor timer
7713 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7714 &pHddCtx->tx_rx_trafficTmr)))
7715 {
7716 hddLog(VOS_TRACE_LEVEL_ERROR,
7717 "%s: Cannot deallocate Traffic monitor timer", __func__);
7718 }
7719
Jeff Johnson295189b2012-06-20 16:38:30 -07007720 //Disable IMPS/BMPS as we do not want the device to enter any power
7721 //save mode during shutdown
7722 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7723 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7724 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7725
7726 //Ensure that device is in full power as we will touch H/W during vos_Stop
7727 init_completion(&powerContext.completion);
7728 powerContext.magic = POWER_CONTEXT_MAGIC;
7729
7730 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7731 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7732
7733 if (eHAL_STATUS_SUCCESS != halStatus)
7734 {
7735 if (eHAL_STATUS_PMC_PENDING == halStatus)
7736 {
7737 /* request was sent -- wait for the response */
7738 lrc = wait_for_completion_interruptible_timeout(
7739 &powerContext.completion,
7740 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 if (lrc <= 0)
7742 {
7743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007744 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 }
7746 }
7747 else
7748 {
7749 hddLog(VOS_TRACE_LEVEL_ERROR,
7750 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007751 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007752 /* continue -- need to clean up as much as possible */
7753 }
7754 }
7755
Jeff Johnson72a40512013-12-19 10:14:15 -08007756 /* either we never sent a request, we sent a request and received a
7757 response or we sent a request and timed out. if we never sent a
7758 request or if we sent a request and got a response, we want to
7759 clear the magic out of paranoia. if we timed out there is a
7760 race condition such that the callback function could be
7761 executing at the same time we are. of primary concern is if the
7762 callback function had already verified the "magic" but had not
7763 yet set the completion variable when a timeout occurred. we
7764 serialize these activities by invalidating the magic while
7765 holding a shared spinlock which will cause us to block if the
7766 callback is currently executing */
7767 spin_lock(&hdd_context_lock);
7768 powerContext.magic = 0;
7769 spin_unlock(&hdd_context_lock);
7770
Yue Ma0d4891e2013-08-06 17:01:45 -07007771 hdd_debugfs_exit(pHddCtx);
7772
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 // Unregister the Net Device Notifier
7774 unregister_netdevice_notifier(&hdd_netdev_notifier);
7775
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 hdd_stop_all_adapters( pHddCtx );
7777
Jeff Johnson295189b2012-06-20 16:38:30 -07007778#ifdef WLAN_BTAMP_FEATURE
7779 vosStatus = WLANBAP_Stop(pVosContext);
7780 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7781 {
7782 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7783 "%s: Failed to stop BAP",__func__);
7784 }
7785#endif //WLAN_BTAMP_FEATURE
7786
7787 //Stop all the modules
7788 vosStatus = vos_stop( pVosContext );
7789 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7790 {
7791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7792 "%s: Failed to stop VOSS",__func__);
7793 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7794 }
7795
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 //Assert Deep sleep signal now to put Libra HW in lowest power state
7797 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7798 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7799
7800 //Vote off any PMIC voltage supplies
7801 vos_chipPowerDown(NULL, NULL, NULL);
7802
7803 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7804
Leo Chang59cdc7e2013-07-10 10:08:21 -07007805
Jeff Johnson295189b2012-06-20 16:38:30 -07007806 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007808
7809 //Close the scheduler before calling vos_close to make sure no thread is
7810 // scheduled after the each module close is called i.e after all the data
7811 // structures are freed.
7812 vosStatus = vos_sched_close( pVosContext );
7813 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7814 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7815 "%s: Failed to close VOSS Scheduler",__func__);
7816 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7817 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007818#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007819#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7820 /* Destroy the wake lock */
7821 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7822#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007823 /* Destroy the wake lock */
7824 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007825#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007826
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307827#ifdef CONFIG_ENABLE_LINUX_REG
7828 vosStatus = vos_nv_close();
7829 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7830 {
7831 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7832 "%s: Failed to close NV", __func__);
7833 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7834 }
7835#endif
7836
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 //Close VOSS
7838 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7839 vos_close(pVosContext);
7840
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 //Close Watchdog
7842 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7843 vos_watchdog_close(pVosContext);
7844
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307845 //Clean up HDD Nlink Service
7846 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007847#ifdef WLAN_KD_READY_NOTIFIER
7848 nl_srv_exit(pHddCtx->ptt_pid);
7849#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307850 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007851#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307852
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307853#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307854 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307855 {
7856 wlan_logging_sock_deactivate_svc();
7857 }
7858#endif
7859
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 /* Cancel the vote for XO Core ON.
7861 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7862 * exited at this point
7863 */
7864 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007865 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7867 {
7868 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7869 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007870 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 }
7872
7873 hdd_close_all_adapters( pHddCtx );
7874
Jeff Johnson295189b2012-06-20 16:38:30 -07007875 /* free the power on lock from platform driver */
7876 if (free_riva_power_on_lock("wlan"))
7877 {
7878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7879 __func__);
7880 }
7881
Jeff Johnson88ba7742013-02-27 14:36:02 -08007882free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307883
7884 //Free up dynamically allocated members inside HDD Adapter
7885 if (pHddCtx->cfg_ini)
7886 {
7887 kfree(pHddCtx->cfg_ini);
7888 pHddCtx->cfg_ini= NULL;
7889 }
7890
Leo Changf04ddad2013-09-18 13:46:38 -07007891 /* FTM mode, WIPHY did not registered
7892 If un-register here, system crash will happen */
7893 if (VOS_FTM_MODE != hdd_get_conparam())
7894 {
7895 wiphy_unregister(wiphy) ;
7896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 if (hdd_is_ssr_required())
7899 {
7900 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007901 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 msleep(5000);
7903 }
7904 hdd_set_ssr_required (VOS_FALSE);
7905}
7906
7907
7908/**---------------------------------------------------------------------------
7909
7910 \brief hdd_update_config_from_nv() - Function to update the contents of
7911 the running configuration with parameters taken from NV storage
7912
7913 \param - pHddCtx - Pointer to the HDD global context
7914
7915 \return - VOS_STATUS_SUCCESS if successful
7916
7917 --------------------------------------------------------------------------*/
7918static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7919{
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 v_BOOL_t itemIsValid = VOS_FALSE;
7921 VOS_STATUS status;
7922 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7923 v_U8_t macLoop;
7924
7925 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7926 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7927 if(status != VOS_STATUS_SUCCESS)
7928 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007929 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007930 return VOS_STATUS_E_FAILURE;
7931 }
7932
7933 if (itemIsValid == VOS_TRUE)
7934 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007935 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7937 VOS_MAX_CONCURRENCY_PERSONA);
7938 if(status != VOS_STATUS_SUCCESS)
7939 {
7940 /* Get MAC from NV fail, not update CFG info
7941 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007942 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 return VOS_STATUS_E_FAILURE;
7944 }
7945
7946 /* If first MAC is not valid, treat all others are not valid
7947 * Then all MACs will be got from ini file */
7948 if(vos_is_macaddr_zero(&macFromNV[0]))
7949 {
7950 /* MAC address in NV file is not configured yet */
7951 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7952 return VOS_STATUS_E_INVAL;
7953 }
7954
7955 /* Get MAC address from NV, update CFG info */
7956 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7957 {
7958 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7959 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307960 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 /* This MAC is not valid, skip it
7962 * This MAC will be got from ini file */
7963 }
7964 else
7965 {
7966 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7967 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7968 VOS_MAC_ADDR_SIZE);
7969 }
7970 }
7971 }
7972 else
7973 {
7974 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7975 return VOS_STATUS_E_FAILURE;
7976 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007977
Jeff Johnson295189b2012-06-20 16:38:30 -07007978
7979 return VOS_STATUS_SUCCESS;
7980}
7981
7982/**---------------------------------------------------------------------------
7983
7984 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7985
7986 \param - pAdapter - Pointer to the HDD
7987
7988 \return - None
7989
7990 --------------------------------------------------------------------------*/
7991VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7992{
7993 eHalStatus halStatus;
7994 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307995 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007996
Jeff Johnson295189b2012-06-20 16:38:30 -07007997
7998 // Send ready indication to the HDD. This will kick off the MAC
7999 // into a 'running' state and should kick off an initial scan.
8000 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8001 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8002 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308003 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 "code %08d [x%08x]",__func__, halStatus, halStatus );
8005 return VOS_STATUS_E_FAILURE;
8006 }
8007
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308008 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8010 // And RIVA will crash
8011 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8012 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308013 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8014 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8015
8016
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 return VOS_STATUS_SUCCESS;
8018}
8019
Jeff Johnson295189b2012-06-20 16:38:30 -07008020/* wake lock APIs for HDD */
8021void hdd_prevent_suspend(void)
8022{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008023#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008025#else
8026 wcnss_prevent_suspend();
8027#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008028}
8029
8030void hdd_allow_suspend(void)
8031{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008032#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008033 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008034#else
8035 wcnss_allow_suspend();
8036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008037}
8038
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308039void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008040{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008041#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008042 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008043#else
8044 /* Do nothing as there is no API in wcnss for timeout*/
8045#endif
8046}
8047
Jeff Johnson295189b2012-06-20 16:38:30 -07008048/**---------------------------------------------------------------------------
8049
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008050 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8051 information between Host and Riva
8052
8053 This function gets reported version of FW
8054 It also finds the version of Riva headers used to compile the host
8055 It compares the above two and prints a warning if they are different
8056 It gets the SW and HW version string
8057 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8058 indicating the features they support through a bitmap
8059
8060 \param - pHddCtx - Pointer to HDD context
8061
8062 \return - void
8063
8064 --------------------------------------------------------------------------*/
8065
8066void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8067{
8068
8069 tSirVersionType versionCompiled;
8070 tSirVersionType versionReported;
8071 tSirVersionString versionString;
8072 tANI_U8 fwFeatCapsMsgSupported = 0;
8073 VOS_STATUS vstatus;
8074
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008075 memset(&versionCompiled, 0, sizeof(versionCompiled));
8076 memset(&versionReported, 0, sizeof(versionReported));
8077
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008078 /* retrieve and display WCNSS version information */
8079 do {
8080
8081 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8082 &versionCompiled);
8083 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8084 {
8085 hddLog(VOS_TRACE_LEVEL_FATAL,
8086 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008087 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008088 break;
8089 }
8090
8091 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8092 &versionReported);
8093 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8094 {
8095 hddLog(VOS_TRACE_LEVEL_FATAL,
8096 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008097 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008098 break;
8099 }
8100
8101 if ((versionCompiled.major != versionReported.major) ||
8102 (versionCompiled.minor != versionReported.minor) ||
8103 (versionCompiled.version != versionReported.version) ||
8104 (versionCompiled.revision != versionReported.revision))
8105 {
8106 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8107 "Host expected %u.%u.%u.%u\n",
8108 WLAN_MODULE_NAME,
8109 (int)versionReported.major,
8110 (int)versionReported.minor,
8111 (int)versionReported.version,
8112 (int)versionReported.revision,
8113 (int)versionCompiled.major,
8114 (int)versionCompiled.minor,
8115 (int)versionCompiled.version,
8116 (int)versionCompiled.revision);
8117 }
8118 else
8119 {
8120 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8121 WLAN_MODULE_NAME,
8122 (int)versionReported.major,
8123 (int)versionReported.minor,
8124 (int)versionReported.version,
8125 (int)versionReported.revision);
8126 }
8127
8128 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8129 versionString,
8130 sizeof(versionString));
8131 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8132 {
8133 hddLog(VOS_TRACE_LEVEL_FATAL,
8134 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008135 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008136 break;
8137 }
8138
8139 pr_info("%s: WCNSS software version %s\n",
8140 WLAN_MODULE_NAME, versionString);
8141
8142 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8143 versionString,
8144 sizeof(versionString));
8145 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8146 {
8147 hddLog(VOS_TRACE_LEVEL_FATAL,
8148 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008149 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008150 break;
8151 }
8152
8153 pr_info("%s: WCNSS hardware version %s\n",
8154 WLAN_MODULE_NAME, versionString);
8155
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008156 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8157 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008158 send the message only if it the riva is 1.1
8159 minor numbers for different riva branches:
8160 0 -> (1.0)Mainline Build
8161 1 -> (1.1)Mainline Build
8162 2->(1.04) Stability Build
8163 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008164 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008165 ((versionReported.minor>=1) && (versionReported.version>=1)))
8166 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8167 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008168
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008169 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008170 {
8171#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8172 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8173 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8174#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008175 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8176 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8177 {
8178 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8179 }
8180
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008181 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008182 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008183
8184 } while (0);
8185
8186}
8187
8188/**---------------------------------------------------------------------------
8189
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308190 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8191
8192 \param - pHddCtx - Pointer to the hdd context
8193
8194 \return - true if hardware supports 5GHz
8195
8196 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308197boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308198{
8199 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8200 * then hardware support 5Ghz.
8201 */
8202 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8203 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308205 return true;
8206 }
8207 else
8208 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308210 __func__);
8211 return false;
8212 }
8213}
8214
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308215/**---------------------------------------------------------------------------
8216
8217 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8218 generate function
8219
8220 This is generate the random mac address for WLAN interface
8221
8222 \param - pHddCtx - Pointer to HDD context
8223 idx - Start interface index to get auto
8224 generated mac addr.
8225 mac_addr - Mac address
8226
8227 \return - 0 for success, < 0 for failure
8228
8229 --------------------------------------------------------------------------*/
8230
8231static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8232 int idx, v_MACADDR_t mac_addr)
8233{
8234 int i;
8235 unsigned int serialno;
8236 serialno = wcnss_get_serial_number();
8237
8238 if (0 != serialno)
8239 {
8240 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8241 bytes of the serial number that can be used to generate
8242 the other 3 bytes of the MAC address. Mask off all but
8243 the lower 3 bytes (this will also make sure we don't
8244 overflow in the next step) */
8245 serialno &= 0x00FFFFFF;
8246
8247 /* we need a unique address for each session */
8248 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8249
8250 /* autogen other Mac addresses */
8251 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8252 {
8253 /* start with the entire default address */
8254 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8255 /* then replace the lower 3 bytes */
8256 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8257 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8258 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8259
8260 serialno++;
8261 hddLog(VOS_TRACE_LEVEL_ERROR,
8262 "%s: Derived Mac Addr: "
8263 MAC_ADDRESS_STR, __func__,
8264 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8265 }
8266
8267 }
8268 else
8269 {
8270 hddLog(LOGE, FL("Failed to Get Serial NO"));
8271 return -1;
8272 }
8273 return 0;
8274}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308275
8276/**---------------------------------------------------------------------------
8277
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308278 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8279 completed to flush out the scan results
8280
8281 11d scan is done during driver load and is a passive scan on all
8282 channels supported by the device, 11d scans may find some APs on
8283 frequencies which are forbidden to be used in the regulatory domain
8284 the device is operating in. If these APs are notified to the supplicant
8285 it may try to connect to these APs, thus flush out all the scan results
8286 which are present in SME after 11d scan is done.
8287
8288 \return - eHalStatus
8289
8290 --------------------------------------------------------------------------*/
8291static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8292 tANI_U32 scanId, eCsrScanStatus status)
8293{
8294 ENTER();
8295
8296 sme_ScanFlushResult(halHandle, 0);
8297
8298 EXIT();
8299
8300 return eHAL_STATUS_SUCCESS;
8301}
8302
8303/**---------------------------------------------------------------------------
8304
Jeff Johnson295189b2012-06-20 16:38:30 -07008305 \brief hdd_wlan_startup() - HDD init function
8306
8307 This is the driver startup code executed once a WLAN device has been detected
8308
8309 \param - dev - Pointer to the underlying device
8310
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008311 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008312
8313 --------------------------------------------------------------------------*/
8314
8315int hdd_wlan_startup(struct device *dev )
8316{
8317 VOS_STATUS status;
8318 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008319 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008320 hdd_context_t *pHddCtx = NULL;
8321 v_CONTEXT_t pVosContext= NULL;
8322#ifdef WLAN_BTAMP_FEATURE
8323 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8324 WLANBAP_ConfigType btAmpConfig;
8325 hdd_config_t *pConfig;
8326#endif
8327 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308329 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008330
8331 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008332 /*
8333 * cfg80211: wiphy allocation
8334 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308335 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008336
8337 if(wiphy == NULL)
8338 {
8339 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008340 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 }
8342
8343 pHddCtx = wiphy_priv(wiphy);
8344
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 //Initialize the adapter context to zeros.
8346 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8347
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308350 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008351
8352 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8353
8354 /*Get vos context here bcoz vos_open requires it*/
8355 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8356
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008357 if(pVosContext == NULL)
8358 {
8359 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8360 goto err_free_hdd_context;
8361 }
8362
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 //Save the Global VOSS context in adapter context for future.
8364 pHddCtx->pvosContext = pVosContext;
8365
8366 //Save the adapter context in global context for future.
8367 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8368
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 pHddCtx->parent_dev = dev;
8370
8371 init_completion(&pHddCtx->full_pwr_comp_var);
8372 init_completion(&pHddCtx->standby_comp_var);
8373 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008374 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008375 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308376 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308377 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008378
8379#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008380 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008381#else
8382 init_completion(&pHddCtx->driver_crda_req);
8383#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008384
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308385 spin_lock_init(&pHddCtx->schedScan_lock);
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8388
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308389#ifdef FEATURE_WLAN_TDLS
8390 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8391 * invoked by other instances also) to protect the concurrent
8392 * access for the Adapters by TDLS module.
8393 */
8394 mutex_init(&pHddCtx->tdls_lock);
8395#endif
8396
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308397 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 // Load all config first as TL config is needed during vos_open
8399 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8400 if(pHddCtx->cfg_ini == NULL)
8401 {
8402 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8403 goto err_free_hdd_context;
8404 }
8405
8406 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8407
8408 // Read and parse the qcom_cfg.ini file
8409 status = hdd_parse_config_ini( pHddCtx );
8410 if ( VOS_STATUS_SUCCESS != status )
8411 {
8412 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8413 __func__, WLAN_INI_FILE);
8414 goto err_config;
8415 }
Arif Hussaind5218912013-12-05 01:10:55 -08008416#ifdef MEMORY_DEBUG
8417 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8418 vos_mem_init();
8419
8420 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8421 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8422#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008423
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308424 /* INI has been read, initialise the configuredMcastBcastFilter with
8425 * INI value as this will serve as the default value
8426 */
8427 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8428 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8429 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308430
8431 if (false == hdd_is_5g_supported(pHddCtx))
8432 {
8433 //5Ghz is not supported.
8434 if (1 != pHddCtx->cfg_ini->nBandCapability)
8435 {
8436 hddLog(VOS_TRACE_LEVEL_INFO,
8437 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8438 pHddCtx->cfg_ini->nBandCapability = 1;
8439 }
8440 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308441
8442 /* If SNR Monitoring is enabled, FW has to parse all beacons
8443 * for calcaluting and storing the average SNR, so set Nth beacon
8444 * filter to 1 to enable FW to parse all the beaocons
8445 */
8446 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8447 {
8448 /* The log level is deliberately set to WARN as overriding
8449 * nthBeaconFilter to 1 will increase power cosumption and this
8450 * might just prove helpful to detect the power issue.
8451 */
8452 hddLog(VOS_TRACE_LEVEL_WARN,
8453 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8454 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308457 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008459 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008461 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8462 {
8463 hddLog(VOS_TRACE_LEVEL_FATAL,
8464 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8465 goto err_config;
8466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008468
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008469 // Update VOS trace levels based upon the cfg.ini
8470 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8471 pHddCtx->cfg_ini->vosTraceEnableBAP);
8472 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8473 pHddCtx->cfg_ini->vosTraceEnableTL);
8474 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8475 pHddCtx->cfg_ini->vosTraceEnableWDI);
8476 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8477 pHddCtx->cfg_ini->vosTraceEnableHDD);
8478 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8479 pHddCtx->cfg_ini->vosTraceEnableSME);
8480 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8481 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308482 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8483 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008484 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8485 pHddCtx->cfg_ini->vosTraceEnableWDA);
8486 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8487 pHddCtx->cfg_ini->vosTraceEnableSYS);
8488 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8489 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008490 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8491 pHddCtx->cfg_ini->vosTraceEnableSAP);
8492 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8493 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008494
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 // Update WDI trace levels based upon the cfg.ini
8496 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8497 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8498 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8499 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8500 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8501 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8502 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8503 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008504
Jeff Johnson88ba7742013-02-27 14:36:02 -08008505 if (VOS_FTM_MODE == hdd_get_conparam())
8506 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8508 {
8509 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8510 goto err_free_hdd_context;
8511 }
8512 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308513
8514 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008517
Jeff Johnson88ba7742013-02-27 14:36:02 -08008518 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008519 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8520 {
8521 status = vos_watchdog_open(pVosContext,
8522 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8523
8524 if(!VOS_IS_STATUS_SUCCESS( status ))
8525 {
8526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308527 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 }
8529 }
8530
8531 pHddCtx->isLogpInProgress = FALSE;
8532 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8533
Jeff Johnson295189b2012-06-20 16:38:30 -07008534 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8535 if(!VOS_IS_STATUS_SUCCESS(status))
8536 {
8537 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008539 }
8540
Amar Singhala49cbc52013-10-08 18:37:44 -07008541#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008542 /* initialize the NV module. This is required so that
8543 we can initialize the channel information in wiphy
8544 from the NV.bin data. The channel information in
8545 wiphy needs to be initialized before wiphy registration */
8546
8547 status = vos_nv_open();
8548 if (!VOS_IS_STATUS_SUCCESS(status))
8549 {
8550 /* NV module cannot be initialized */
8551 hddLog( VOS_TRACE_LEVEL_FATAL,
8552 "%s: vos_nv_open failed", __func__);
8553 goto err_clkvote;
8554 }
8555
8556 status = vos_init_wiphy_from_nv_bin();
8557 if (!VOS_IS_STATUS_SUCCESS(status))
8558 {
8559 /* NV module cannot be initialized */
8560 hddLog( VOS_TRACE_LEVEL_FATAL,
8561 "%s: vos_init_wiphy failed", __func__);
8562 goto err_vos_nv_close;
8563 }
8564
Amar Singhala49cbc52013-10-08 18:37:44 -07008565#endif
8566
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308567 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 if ( !VOS_IS_STATUS_SUCCESS( status ))
8569 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008570 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308571 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 }
8573
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8575
8576 if ( NULL == pHddCtx->hHal )
8577 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008578 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 goto err_vosclose;
8580 }
8581
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008582 status = vos_preStart( pHddCtx->pvosContext );
8583 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8584 {
8585 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308586 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008587 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008588
Arif Hussaineaf68602013-12-30 23:10:44 -08008589 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8590 {
8591 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8592 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8593 __func__, enable_dfs_chan_scan);
8594 }
8595 if (0 == enable_11d || 1 == enable_11d)
8596 {
8597 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8598 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8599 __func__, enable_11d);
8600 }
8601
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008602 /* Note that the vos_preStart() sequence triggers the cfg download.
8603 The cfg download must occur before we update the SME config
8604 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008605 status = hdd_set_sme_config( pHddCtx );
8606
8607 if ( VOS_STATUS_SUCCESS != status )
8608 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008609 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308610 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008612
8613 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008614 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8615 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 if (!VOS_IS_STATUS_SUCCESS(status))
8617 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008618 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308619 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008620 }
8621
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 /* In the integrated architecture we update the configuration from
8623 the INI file and from NV before vOSS has been started so that
8624 the final contents are available to send down to the cCPU */
8625
8626 // Apply the cfg.ini to cfg.dat
8627 if (FALSE == hdd_update_config_dat(pHddCtx))
8628 {
8629 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308630 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008631 }
8632
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308633 // Get mac addr from platform driver
8634 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8635
8636 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308638 /* Store the mac addr for first interface */
8639 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8640
8641 hddLog(VOS_TRACE_LEVEL_ERROR,
8642 "%s: WLAN Mac Addr: "
8643 MAC_ADDRESS_STR, __func__,
8644 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8645
8646 /* Here, passing Arg2 as 1 because we do not want to change the
8647 last 3 bytes (means non OUI bytes) of first interface mac
8648 addr.
8649 */
8650 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8651 {
8652 hddLog(VOS_TRACE_LEVEL_ERROR,
8653 "%s: Failed to generate wlan interface mac addr "
8654 "using MAC from ini file ", __func__);
8655 }
8656 }
8657 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8658 {
8659 // Apply the NV to cfg.dat
8660 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008661#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8662 /* There was not a valid set of MAC Addresses in NV. See if the
8663 default addresses were modified by the cfg.ini settings. If so,
8664 we'll use them, but if not, we'll autogenerate a set of MAC
8665 addresses based upon the device serial number */
8666
8667 static const v_MACADDR_t default_address =
8668 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008669
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308670 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8671 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008672 {
8673 /* cfg.ini has the default address, invoke autogen logic */
8674
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308675 /* Here, passing Arg2 as 0 because we want to change the
8676 last 3 bytes (means non OUI bytes) of all the interfaces
8677 mac addr.
8678 */
8679 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8680 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308682 hddLog(VOS_TRACE_LEVEL_ERROR,
8683 "%s: Failed to generate wlan interface mac addr "
8684 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8685 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 }
8688 else
8689#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8690 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008691 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 "%s: Invalid MAC address in NV, using MAC from ini file "
8693 MAC_ADDRESS_STR, __func__,
8694 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8695 }
8696 }
8697 {
8698 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308699
8700 /* Set the MAC Address Currently this is used by HAL to
8701 * add self sta. Remove this once self sta is added as
8702 * part of session open.
8703 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8705 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8706 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308707
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 if (!HAL_STATUS_SUCCESS( halStatus ))
8709 {
8710 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8711 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308712 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 }
8714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008715
8716 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8717 Note: Firmware image will be read and downloaded inside vos_start API */
8718 status = vos_start( pHddCtx->pvosContext );
8719 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8720 {
8721 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308722 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 }
8724
Leo Chang6cec3e22014-01-21 15:33:49 -08008725#ifdef FEATURE_WLAN_CH_AVOID
8726 /* Plug in avoid channel notification callback
8727 * This should happen before ADD_SELF_STA
8728 * FW will send first IND with ADD_SELF_STA REQ from host */
8729 sme_AddChAvoidCallback(pHddCtx->hHal,
8730 hdd_hostapd_ch_avoid_cb);
8731#endif /* FEATURE_WLAN_CH_AVOID */
8732
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008733 /* Exchange capability info between Host and FW and also get versioning info from FW */
8734 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008735
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308736#ifdef CONFIG_ENABLE_LINUX_REG
8737 status = wlan_hdd_init_channels(pHddCtx);
8738 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8739 {
8740 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8741 __func__);
8742 goto err_vosstop;
8743 }
8744#endif
8745
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 status = hdd_post_voss_start_config( pHddCtx );
8747 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8748 {
8749 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8750 __func__);
8751 goto err_vosstop;
8752 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008753
8754#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308755 wlan_hdd_cfg80211_update_reg_info( wiphy );
8756
8757 /* registration of wiphy dev with cfg80211 */
8758 if (0 > wlan_hdd_cfg80211_register(wiphy))
8759 {
8760 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8761 goto err_vosstop;
8762 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008764
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308765#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308766 /* registration of wiphy dev with cfg80211 */
8767 if (0 > wlan_hdd_cfg80211_register(wiphy))
8768 {
8769 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8770 goto err_vosstop;
8771 }
8772
8773 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8774 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8775 {
8776 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8777 __func__);
8778 goto err_unregister_wiphy;
8779 }
8780#endif
8781
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8783 {
8784 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8785 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8786 }
8787 else
8788 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8790 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8791 if (pAdapter != NULL)
8792 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308793 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008794 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308795 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8796 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8797 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008798
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308799 /* Generate the P2P Device Address. This consists of the device's
8800 * primary MAC address with the locally administered bit set.
8801 */
8802 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008803 }
8804 else
8805 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308806 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8807 if (p2p_dev_addr != NULL)
8808 {
8809 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8810 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8811 }
8812 else
8813 {
8814 hddLog(VOS_TRACE_LEVEL_FATAL,
8815 "%s: Failed to allocate mac_address for p2p_device",
8816 __func__);
8817 goto err_close_adapter;
8818 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008820
8821 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8822 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8823 if ( NULL == pP2pAdapter )
8824 {
8825 hddLog(VOS_TRACE_LEVEL_FATAL,
8826 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008827 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008828 goto err_close_adapter;
8829 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008832
8833 if( pAdapter == NULL )
8834 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8836 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008838
Arif Hussain66559122013-11-21 10:11:40 -08008839 if (country_code)
8840 {
8841 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008842 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008843 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8844#ifndef CONFIG_ENABLE_LINUX_REG
8845 hdd_checkandupdate_phymode(pAdapter, country_code);
8846#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008847 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8848 (void *)(tSmeChangeCountryCallback)
8849 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008850 country_code,
8851 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308852 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008853 if (eHAL_STATUS_SUCCESS == ret)
8854 {
Arif Hussaincb607082013-12-20 11:57:42 -08008855 ret = wait_for_completion_interruptible_timeout(
8856 &pAdapter->change_country_code,
8857 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8858
8859 if (0 >= ret)
8860 {
8861 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8862 "%s: SME while setting country code timed out", __func__);
8863 }
Arif Hussain66559122013-11-21 10:11:40 -08008864 }
8865 else
8866 {
Arif Hussaincb607082013-12-20 11:57:42 -08008867 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8868 "%s: SME Change Country code from module param fail ret=%d",
8869 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008870 }
8871 }
8872
Jeff Johnson295189b2012-06-20 16:38:30 -07008873#ifdef WLAN_BTAMP_FEATURE
8874 vStatus = WLANBAP_Open(pVosContext);
8875 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8876 {
8877 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8878 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008879 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 }
8881
8882 vStatus = BSL_Init(pVosContext);
8883 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8884 {
8885 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8886 "%s: Failed to Init BSL",__func__);
8887 goto err_bap_close;
8888 }
8889 vStatus = WLANBAP_Start(pVosContext);
8890 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8891 {
8892 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8893 "%s: Failed to start TL",__func__);
8894 goto err_bap_close;
8895 }
8896
8897 pConfig = pHddCtx->cfg_ini;
8898 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8899 status = WLANBAP_SetConfig(&btAmpConfig);
8900
8901#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008902
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008903#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8904 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8905 {
8906 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8907 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8908 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8909 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8910 }
8911#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008912#ifdef FEATURE_WLAN_SCAN_PNO
8913 /*SME must send channel update configuration to RIVA*/
8914 sme_UpdateChannelConfig(pHddCtx->hHal);
8915#endif
8916
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308917 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8918
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 /* Register with platform driver as client for Suspend/Resume */
8920 status = hddRegisterPmOps(pHddCtx);
8921 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8922 {
8923 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8924#ifdef WLAN_BTAMP_FEATURE
8925 goto err_bap_stop;
8926#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008927 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008928#endif //WLAN_BTAMP_FEATURE
8929 }
8930
Yue Ma0d4891e2013-08-06 17:01:45 -07008931 /* Open debugfs interface */
8932 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8933 {
8934 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8935 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008936 }
8937
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 /* Register TM level change handler function to the platform */
8939 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8940 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8941 {
8942 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8943 goto err_unregister_pmops;
8944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008945
8946 /* register for riva power on lock to platform driver */
8947 if (req_riva_power_on_lock("wlan"))
8948 {
8949 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8950 __func__);
8951 goto err_unregister_pmops;
8952 }
8953
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 // register net device notifier for device change notification
8955 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8956
8957 if(ret < 0)
8958 {
8959 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8960 goto err_free_power_on_lock;
8961 }
8962
8963 //Initialize the nlink service
8964 if(nl_srv_init() != 0)
8965 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308966 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 goto err_reg_netdev;
8968 }
8969
Leo Chang4ce1cc52013-10-21 18:27:15 -07008970#ifdef WLAN_KD_READY_NOTIFIER
8971 pHddCtx->kd_nl_init = 1;
8972#endif /* WLAN_KD_READY_NOTIFIER */
8973
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 //Initialize the BTC service
8975 if(btc_activate_service(pHddCtx) != 0)
8976 {
8977 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8978 goto err_nl_srv;
8979 }
8980
8981#ifdef PTT_SOCK_SVC_ENABLE
8982 //Initialize the PTT service
8983 if(ptt_sock_activate_svc(pHddCtx) != 0)
8984 {
8985 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8986 goto err_nl_srv;
8987 }
8988#endif
8989
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308990#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8991 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8992 {
8993 if(wlan_logging_sock_activate_svc(
8994 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8995 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8996 {
8997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8998 " failed", __func__);
8999 goto err_nl_srv;
9000 }
9001 }
9002#endif
9003
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009007 /* Action frame registered in one adapter which will
9008 * applicable to all interfaces
9009 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309010 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009012
9013 mutex_init(&pHddCtx->sap_lock);
9014
Mihir Shete18156292014-03-11 15:38:30 +05309015 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009016
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009017#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009018#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9019 /* Initialize the wake lcok */
9020 wake_lock_init(&pHddCtx->rx_wake_lock,
9021 WAKE_LOCK_SUSPEND,
9022 "qcom_rx_wakelock");
9023#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009024 /* Initialize the wake lcok */
9025 wake_lock_init(&pHddCtx->sap_wake_lock,
9026 WAKE_LOCK_SUSPEND,
9027 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009028#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009029
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009030 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9031 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009032
9033 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9034 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05309035#ifndef CONFIG_ENABLE_LINUX_REG
9036 /*updating wiphy so that regulatory user hints can be processed*/
9037 if (wiphy)
9038 {
9039 regulatory_hint(wiphy, "00");
9040 }
9041#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009042 // Initialize the restart logic
9043 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309044
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009045 //Register the traffic monitor timer now
9046 if ( pHddCtx->cfg_ini->dynSplitscan)
9047 {
9048 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9049 VOS_TIMER_TYPE_SW,
9050 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9051 (void *)pHddCtx);
9052 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 goto success;
9054
9055err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009056#ifdef WLAN_KD_READY_NOTIFIER
9057 nl_srv_exit(pHddCtx->ptt_pid);
9058#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009060#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009061err_reg_netdev:
9062 unregister_netdevice_notifier(&hdd_netdev_notifier);
9063
9064err_free_power_on_lock:
9065 free_riva_power_on_lock("wlan");
9066
9067err_unregister_pmops:
9068 hddDevTmUnregisterNotifyCallback(pHddCtx);
9069 hddDeregisterPmOps(pHddCtx);
9070
Yue Ma0d4891e2013-08-06 17:01:45 -07009071 hdd_debugfs_exit(pHddCtx);
9072
Jeff Johnson295189b2012-06-20 16:38:30 -07009073#ifdef WLAN_BTAMP_FEATURE
9074err_bap_stop:
9075 WLANBAP_Stop(pVosContext);
9076#endif
9077
9078#ifdef WLAN_BTAMP_FEATURE
9079err_bap_close:
9080 WLANBAP_Close(pVosContext);
9081#endif
9082
Jeff Johnson295189b2012-06-20 16:38:30 -07009083err_close_adapter:
9084 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309085err_unregister_wiphy:
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309086 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009087err_vosstop:
9088 vos_stop(pVosContext);
9089
Amar Singhala49cbc52013-10-08 18:37:44 -07009090err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 status = vos_sched_close( pVosContext );
9092 if (!VOS_IS_STATUS_SUCCESS(status)) {
9093 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9094 "%s: Failed to close VOSS Scheduler", __func__);
9095 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9096 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009097 vos_close(pVosContext );
9098
Amar Singhal0a402232013-10-11 20:57:16 -07009099err_vos_nv_close:
9100
c_hpothue6a36282014-03-19 12:27:38 +05309101#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009102 vos_nv_close();
9103
Jeff Johnson295189b2012-06-20 16:38:30 -07009104err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309105#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009106 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009107
9108err_wdclose:
9109 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9110 vos_watchdog_close(pVosContext);
9111
Jeff Johnson295189b2012-06-20 16:38:30 -07009112err_config:
9113 kfree(pHddCtx->cfg_ini);
9114 pHddCtx->cfg_ini= NULL;
9115
9116err_free_hdd_context:
9117 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 wiphy_free(wiphy) ;
9119 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 VOS_BUG(1);
9121
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009122 if (hdd_is_ssr_required())
9123 {
9124 /* WDI timeout had happened during load, so SSR is needed here */
9125 subsystem_restart("wcnss");
9126 msleep(5000);
9127 }
9128 hdd_set_ssr_required (VOS_FALSE);
9129
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009130 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009131
9132success:
9133 EXIT();
9134 return 0;
9135}
9136
9137/**---------------------------------------------------------------------------
9138
Jeff Johnson32d95a32012-09-10 13:15:23 -07009139 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009140
Jeff Johnson32d95a32012-09-10 13:15:23 -07009141 This is the driver entry point - called in different timeline depending
9142 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009143
9144 \param - None
9145
9146 \return - 0 for success, non zero for failure
9147
9148 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009149static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009150{
9151 VOS_STATUS status;
9152 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 struct device *dev = NULL;
9154 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009155#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9156 int max_retries = 0;
9157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009158
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309159#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9160 wlan_logging_sock_init_svc();
9161#endif
9162
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 ENTER();
9164
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009165#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009167#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009168
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309169 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9171 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9172
9173 //Power Up Libra WLAN card first if not already powered up
9174 status = vos_chipPowerUp(NULL,NULL,NULL);
9175 if (!VOS_IS_STATUS_SUCCESS(status))
9176 {
9177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9178 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309179#ifdef WLAN_OPEN_SOURCE
9180 wake_lock_destroy(&wlan_wake_lock);
9181#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309182
9183#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9184 wlan_logging_sock_deinit_svc();
9185#endif
9186
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009187 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009188 }
9189
Jeff Johnson295189b2012-06-20 16:38:30 -07009190#ifdef ANI_BUS_TYPE_PCI
9191
9192 dev = wcnss_wlan_get_device();
9193
9194#endif // ANI_BUS_TYPE_PCI
9195
9196#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009197
9198#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9199 /* wait until WCNSS driver downloads NV */
9200 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9201 msleep(1000);
9202 }
9203 if (max_retries >= 5) {
9204 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309205#ifdef WLAN_OPEN_SOURCE
9206 wake_lock_destroy(&wlan_wake_lock);
9207#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309208
9209#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9210 wlan_logging_sock_deinit_svc();
9211#endif
9212
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009213 return -ENODEV;
9214 }
9215#endif
9216
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 dev = wcnss_wlan_get_device();
9218#endif // ANI_BUS_TYPE_PLATFORM
9219
9220
9221 do {
9222 if (NULL == dev) {
9223 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9224 ret_status = -1;
9225 break;
9226 }
9227
Jeff Johnson295189b2012-06-20 16:38:30 -07009228#ifdef TIMER_MANAGER
9229 vos_timer_manager_init();
9230#endif
9231
9232 /* Preopen VOSS so that it is ready to start at least SAL */
9233 status = vos_preOpen(&pVosContext);
9234
9235 if (!VOS_IS_STATUS_SUCCESS(status))
9236 {
9237 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9238 ret_status = -1;
9239 break;
9240 }
9241
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009242#ifndef MODULE
9243 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9244 */
9245 hdd_set_conparam((v_UINT_t)con_mode);
9246#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009247
9248 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009249 if (hdd_wlan_startup(dev))
9250 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009252 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 vos_preClose( &pVosContext );
9254 ret_status = -1;
9255 break;
9256 }
9257
9258 /* Cancel the vote for XO Core ON
9259 * This is done here for safety purposes in case we re-initialize without turning
9260 * it OFF in any error scenario.
9261 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009262 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009264 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9266 {
9267 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009268 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 }
9270 } while (0);
9271
9272 if (0 != ret_status)
9273 {
9274 //Assert Deep sleep signal now to put Libra HW in lowest power state
9275 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9276 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9277
9278 //Vote off any PMIC voltage supplies
9279 vos_chipPowerDown(NULL, NULL, NULL);
9280#ifdef TIMER_MANAGER
9281 vos_timer_exit();
9282#endif
9283#ifdef MEMORY_DEBUG
9284 vos_mem_exit();
9285#endif
9286
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009287#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009289#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309290
9291#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9292 wlan_logging_sock_deinit_svc();
9293#endif
9294
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9296 }
9297 else
9298 {
9299 //Send WLAN UP indication to Nlink Service
9300 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9301
9302 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 }
9304
9305 EXIT();
9306
9307 return ret_status;
9308}
9309
Jeff Johnson32d95a32012-09-10 13:15:23 -07009310/**---------------------------------------------------------------------------
9311
9312 \brief hdd_module_init() - Init Function
9313
9314 This is the driver entry point (invoked when module is loaded using insmod)
9315
9316 \param - None
9317
9318 \return - 0 for success, non zero for failure
9319
9320 --------------------------------------------------------------------------*/
9321#ifdef MODULE
9322static int __init hdd_module_init ( void)
9323{
9324 return hdd_driver_init();
9325}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009326#else /* #ifdef MODULE */
9327static int __init hdd_module_init ( void)
9328{
9329 /* Driver initialization is delayed to fwpath_changed_handler */
9330 return 0;
9331}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009332#endif /* #ifdef MODULE */
9333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334
9335/**---------------------------------------------------------------------------
9336
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009337 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009338
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009339 This is the driver exit point (invoked when module is unloaded using rmmod
9340 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009341
9342 \param - None
9343
9344 \return - None
9345
9346 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009347static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009348{
9349 hdd_context_t *pHddCtx = NULL;
9350 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309351 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309352 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009353
9354 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9355
9356 //Get the global vos context
9357 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9358
9359 if(!pVosContext)
9360 {
9361 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9362 goto done;
9363 }
9364
9365 //Get the HDD context.
9366 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9367
9368 if(!pHddCtx)
9369 {
9370 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9371 }
9372 else
9373 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309374 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9375
9376 if (pHddCtx->isLogpInProgress)
9377 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309379 "%s:SSR in Progress; block rmmod !!!", __func__);
9380 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9381 msecs_to_jiffies(30000));
9382 if(!rc)
9383 {
9384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9385 "%s:SSR timedout, fatal error", __func__);
9386 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009387 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309388 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009389
Mihir Shete18156292014-03-11 15:38:30 +05309390 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9392
Agarwal Ashish5e414792014-06-08 15:25:23 +05309393 if (eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
9394 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority )
9395 {
9396 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9397 }
9398
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 //Do all the cleanup before deregistering the driver
9400 hdd_wlan_exit(pHddCtx);
9401 }
9402
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 vos_preClose( &pVosContext );
9404
9405#ifdef TIMER_MANAGER
9406 vos_timer_exit();
9407#endif
9408#ifdef MEMORY_DEBUG
9409 vos_mem_exit();
9410#endif
9411
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309412#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9413 wlan_logging_sock_deinit_svc();
9414#endif
9415
Jeff Johnson295189b2012-06-20 16:38:30 -07009416done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009417#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009419#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309420
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9422}
9423
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009424/**---------------------------------------------------------------------------
9425
9426 \brief hdd_module_exit() - Exit function
9427
9428 This is the driver exit point (invoked when module is unloaded using rmmod)
9429
9430 \param - None
9431
9432 \return - None
9433
9434 --------------------------------------------------------------------------*/
9435static void __exit hdd_module_exit(void)
9436{
9437 hdd_driver_exit();
9438}
9439
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009440#ifdef MODULE
9441static int fwpath_changed_handler(const char *kmessage,
9442 struct kernel_param *kp)
9443{
Jeff Johnson76052702013-04-16 13:55:05 -07009444 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009445}
9446
9447static int con_mode_handler(const char *kmessage,
9448 struct kernel_param *kp)
9449{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009450 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009451}
9452#else /* #ifdef MODULE */
9453/**---------------------------------------------------------------------------
9454
Jeff Johnson76052702013-04-16 13:55:05 -07009455 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009456
Jeff Johnson76052702013-04-16 13:55:05 -07009457 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009458 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009459 - invoked when module parameter fwpath is modified from userspace to signal
9460 initializing the WLAN driver or when con_mode is modified from userspace
9461 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009462
9463 \return - 0 for success, non zero for failure
9464
9465 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009466static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009467{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009468 int ret_status;
9469
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009470 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009471 ret_status = hdd_driver_init();
9472 wlan_hdd_inited = ret_status ? 0 : 1;
9473 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009474 }
9475
9476 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009477
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009478 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009479
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009480 ret_status = hdd_driver_init();
9481 wlan_hdd_inited = ret_status ? 0 : 1;
9482 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009483}
9484
Jeff Johnson295189b2012-06-20 16:38:30 -07009485/**---------------------------------------------------------------------------
9486
Jeff Johnson76052702013-04-16 13:55:05 -07009487 \brief fwpath_changed_handler() - Handler Function
9488
9489 Handle changes to the fwpath parameter
9490
9491 \return - 0 for success, non zero for failure
9492
9493 --------------------------------------------------------------------------*/
9494static int fwpath_changed_handler(const char *kmessage,
9495 struct kernel_param *kp)
9496{
9497 int ret;
9498
9499 ret = param_set_copystring(kmessage, kp);
9500 if (0 == ret)
9501 ret = kickstart_driver();
9502 return ret;
9503}
9504
9505/**---------------------------------------------------------------------------
9506
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009507 \brief con_mode_handler() -
9508
9509 Handler function for module param con_mode when it is changed by userspace
9510 Dynamically linked - do nothing
9511 Statically linked - exit and init driver, as in rmmod and insmod
9512
Jeff Johnson76052702013-04-16 13:55:05 -07009513 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009514
Jeff Johnson76052702013-04-16 13:55:05 -07009515 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009516
9517 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009518static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009519{
Jeff Johnson76052702013-04-16 13:55:05 -07009520 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009521
Jeff Johnson76052702013-04-16 13:55:05 -07009522 ret = param_set_int(kmessage, kp);
9523 if (0 == ret)
9524 ret = kickstart_driver();
9525 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009526}
9527#endif /* #ifdef MODULE */
9528
9529/**---------------------------------------------------------------------------
9530
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 \brief hdd_get_conparam() -
9532
9533 This is the driver exit point (invoked when module is unloaded using rmmod)
9534
9535 \param - None
9536
9537 \return - tVOS_CON_MODE
9538
9539 --------------------------------------------------------------------------*/
9540tVOS_CON_MODE hdd_get_conparam ( void )
9541{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009542#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009544#else
9545 return (tVOS_CON_MODE)curr_con_mode;
9546#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009547}
9548void hdd_set_conparam ( v_UINT_t newParam )
9549{
9550 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009551#ifndef MODULE
9552 curr_con_mode = con_mode;
9553#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009554}
9555/**---------------------------------------------------------------------------
9556
9557 \brief hdd_softap_sta_deauth() - function
9558
9559 This to take counter measure to handle deauth req from HDD
9560
9561 \param - pAdapter - Pointer to the HDD
9562
9563 \param - enable - boolean value
9564
9565 \return - None
9566
9567 --------------------------------------------------------------------------*/
9568
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009569VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009570{
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009572 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009573
9574 ENTER();
9575
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009576 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9577 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009578
9579 //Ignore request to deauth bcmc station
9580 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009581 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009582
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009583 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009584
9585 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009586 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009587}
9588
9589/**---------------------------------------------------------------------------
9590
9591 \brief hdd_softap_sta_disassoc() - function
9592
9593 This to take counter measure to handle deauth req from HDD
9594
9595 \param - pAdapter - Pointer to the HDD
9596
9597 \param - enable - boolean value
9598
9599 \return - None
9600
9601 --------------------------------------------------------------------------*/
9602
9603void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9604{
9605 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9606
9607 ENTER();
9608
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309609 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009610
9611 //Ignore request to disassoc bcmc station
9612 if( pDestMacAddress[0] & 0x1 )
9613 return;
9614
9615 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9616}
9617
9618void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9619{
9620 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9621
9622 ENTER();
9623
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309624 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009625
9626 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9627}
9628
Jeff Johnson295189b2012-06-20 16:38:30 -07009629/**---------------------------------------------------------------------------
9630 *
9631 * \brief hdd_get__concurrency_mode() -
9632 *
9633 *
9634 * \param - None
9635 *
9636 * \return - CONCURRENCY MODE
9637 *
9638 * --------------------------------------------------------------------------*/
9639tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9640{
9641 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9642 hdd_context_t *pHddCtx;
9643
9644 if (NULL != pVosContext)
9645 {
9646 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9647 if (NULL != pHddCtx)
9648 {
9649 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9650 }
9651 }
9652
9653 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009654 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 return VOS_STA;
9656}
9657
9658/* Decide whether to allow/not the apps power collapse.
9659 * Allow apps power collapse if we are in connected state.
9660 * if not, allow only if we are in IMPS */
9661v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9662{
9663 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009664 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009665 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9667 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9668 hdd_adapter_t *pAdapter = NULL;
9669 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009670 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9673 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009674
Yathish9f22e662012-12-10 14:21:35 -08009675 concurrent_state = hdd_get_concurrency_mode();
9676
9677#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9678 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9679 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9680 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9681 return TRUE;
9682#endif
9683
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 /*loop through all adapters. TBD fix for Concurrency */
9685 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9686 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9687 {
9688 pAdapter = pAdapterNode->pAdapter;
9689 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9690 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9691 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009692 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309693 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009694 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009695 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9696 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009698 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009699 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9700 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 return FALSE;
9702 }
9703 }
9704 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9705 pAdapterNode = pNext;
9706 }
9707 return TRUE;
9708}
9709
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009710/* Decides whether to send suspend notification to Riva
9711 * if any adapter is in BMPS; then it is required */
9712v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9713{
9714 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9715 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9716
9717 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9718 {
9719 return TRUE;
9720 }
9721 return FALSE;
9722}
9723
Jeff Johnson295189b2012-06-20 16:38:30 -07009724void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9725{
9726 switch(mode)
9727 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009728 case VOS_STA_MODE:
9729 case VOS_P2P_CLIENT_MODE:
9730 case VOS_P2P_GO_MODE:
9731 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009732 pHddCtx->concurrency_mode |= (1 << mode);
9733 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 break;
9735 default:
9736 break;
9737
9738 }
9739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9740 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9741}
9742
9743
9744void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9745{
9746 switch(mode)
9747 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009748 case VOS_STA_MODE:
9749 case VOS_P2P_CLIENT_MODE:
9750 case VOS_P2P_GO_MODE:
9751 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 pHddCtx->no_of_sessions[mode]--;
9753 if (!(pHddCtx->no_of_sessions[mode]))
9754 pHddCtx->concurrency_mode &= (~(1 << mode));
9755 break;
9756 default:
9757 break;
9758 }
9759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9760 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9761}
9762
Jeff Johnsone7245742012-09-05 17:12:55 -07009763/**---------------------------------------------------------------------------
9764 *
9765 * \brief wlan_hdd_restart_init
9766 *
9767 * This function initalizes restart timer/flag. An internal function.
9768 *
9769 * \param - pHddCtx
9770 *
9771 * \return - None
9772 *
9773 * --------------------------------------------------------------------------*/
9774
9775static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9776{
9777 /* Initialize */
9778 pHddCtx->hdd_restart_retries = 0;
9779 atomic_set(&pHddCtx->isRestartInProgress, 0);
9780 vos_timer_init(&pHddCtx->hdd_restart_timer,
9781 VOS_TIMER_TYPE_SW,
9782 wlan_hdd_restart_timer_cb,
9783 pHddCtx);
9784}
9785/**---------------------------------------------------------------------------
9786 *
9787 * \brief wlan_hdd_restart_deinit
9788 *
9789 * This function cleans up the resources used. An internal function.
9790 *
9791 * \param - pHddCtx
9792 *
9793 * \return - None
9794 *
9795 * --------------------------------------------------------------------------*/
9796
9797static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9798{
9799
9800 VOS_STATUS vos_status;
9801 /* Block any further calls */
9802 atomic_set(&pHddCtx->isRestartInProgress, 1);
9803 /* Cleanup */
9804 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9805 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309806 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009807 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9808 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309809 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009810
9811}
9812
9813/**---------------------------------------------------------------------------
9814 *
9815 * \brief wlan_hdd_framework_restart
9816 *
9817 * This function uses a cfg80211 API to start a framework initiated WLAN
9818 * driver module unload/load.
9819 *
9820 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9821 *
9822 *
9823 * \param - pHddCtx
9824 *
9825 * \return - VOS_STATUS_SUCCESS: Success
9826 * VOS_STATUS_E_EMPTY: Adapter is Empty
9827 * VOS_STATUS_E_NOMEM: No memory
9828
9829 * --------------------------------------------------------------------------*/
9830
9831static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9832{
9833 VOS_STATUS status = VOS_STATUS_SUCCESS;
9834 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009835 int len = (sizeof (struct ieee80211_mgmt));
9836 struct ieee80211_mgmt *mgmt = NULL;
9837
9838 /* Prepare the DEAUTH managment frame with reason code */
9839 mgmt = kzalloc(len, GFP_KERNEL);
9840 if(mgmt == NULL)
9841 {
9842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9843 "%s: memory allocation failed (%d bytes)", __func__, len);
9844 return VOS_STATUS_E_NOMEM;
9845 }
9846 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009847
9848 /* Iterate over all adapters/devices */
9849 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9850 do
9851 {
9852 if( (status == VOS_STATUS_SUCCESS) &&
9853 pAdapterNode &&
9854 pAdapterNode->pAdapter)
9855 {
9856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9857 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9858 pAdapterNode->pAdapter->dev->name,
9859 pAdapterNode->pAdapter->device_mode,
9860 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009861 /*
9862 * CFG80211 event to restart the driver
9863 *
9864 * 'cfg80211_send_unprot_deauth' sends a
9865 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9866 * of SME(Linux Kernel) state machine.
9867 *
9868 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9869 * the driver.
9870 *
9871 */
9872
9873 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009874 }
9875 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9876 pAdapterNode = pNext;
9877 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9878
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009879
9880 /* Free the allocated management frame */
9881 kfree(mgmt);
9882
Jeff Johnsone7245742012-09-05 17:12:55 -07009883 /* Retry until we unload or reach max count */
9884 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9885 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9886
9887 return status;
9888
9889}
9890/**---------------------------------------------------------------------------
9891 *
9892 * \brief wlan_hdd_restart_timer_cb
9893 *
9894 * Restart timer callback. An internal function.
9895 *
9896 * \param - User data:
9897 *
9898 * \return - None
9899 *
9900 * --------------------------------------------------------------------------*/
9901
9902void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9903{
9904 hdd_context_t *pHddCtx = usrDataForCallback;
9905 wlan_hdd_framework_restart(pHddCtx);
9906 return;
9907
9908}
9909
9910
9911/**---------------------------------------------------------------------------
9912 *
9913 * \brief wlan_hdd_restart_driver
9914 *
9915 * This function sends an event to supplicant to restart the WLAN driver.
9916 *
9917 * This function is called from vos_wlanRestart.
9918 *
9919 * \param - pHddCtx
9920 *
9921 * \return - VOS_STATUS_SUCCESS: Success
9922 * VOS_STATUS_E_EMPTY: Adapter is Empty
9923 * VOS_STATUS_E_ALREADY: Request already in progress
9924
9925 * --------------------------------------------------------------------------*/
9926VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9927{
9928 VOS_STATUS status = VOS_STATUS_SUCCESS;
9929
9930 /* A tight check to make sure reentrancy */
9931 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9932 {
9933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9934 "%s: WLAN restart is already in progress", __func__);
9935
9936 return VOS_STATUS_E_ALREADY;
9937 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009938 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009939#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009940 wcnss_reset_intr();
9941#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009942
Jeff Johnsone7245742012-09-05 17:12:55 -07009943 return status;
9944}
9945
Mihir Shetee1093ba2014-01-21 20:13:32 +05309946/**---------------------------------------------------------------------------
9947 *
9948 * \brief wlan_hdd_init_channels
9949 *
9950 * This function is used to initialize the channel list in CSR
9951 *
9952 * This function is called from hdd_wlan_startup
9953 *
9954 * \param - pHddCtx: HDD context
9955 *
9956 * \return - VOS_STATUS_SUCCESS: Success
9957 * VOS_STATUS_E_FAULT: Failure reported by SME
9958
9959 * --------------------------------------------------------------------------*/
9960static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9961{
9962 eHalStatus status;
9963
9964 status = sme_InitChannels(pHddCtx->hHal);
9965 if (HAL_STATUS_SUCCESS(status))
9966 {
9967 return VOS_STATUS_SUCCESS;
9968 }
9969 else
9970 {
9971 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9972 __func__, status);
9973 return VOS_STATUS_E_FAULT;
9974 }
9975}
9976
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309977static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
9978{
9979 eHalStatus status;
9980
9981 status = sme_InitChannelsForCC(pHddCtx->hHal);
9982 if (HAL_STATUS_SUCCESS(status))
9983 {
9984 return VOS_STATUS_SUCCESS;
9985 }
9986 else
9987 {
9988 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
9989 __func__, status);
9990 return VOS_STATUS_E_FAULT;
9991 }
9992}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009993/*
9994 * API to find if there is any STA or P2P-Client is connected
9995 */
9996VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9997{
9998 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9999}
Jeff Johnsone7245742012-09-05 17:12:55 -070010000
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010001int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10002{
10003 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10004 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010005 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010006
10007 pScanInfo = &pHddCtx->scan_info;
10008 if (pScanInfo->mScanPending)
10009 {
10010 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10011 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10012 eCSR_SCAN_ABORT_DEFAULT);
10013
10014 status = wait_for_completion_interruptible_timeout(
10015 &pScanInfo->abortscan_event_var,
10016 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010017 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010018 {
10019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010020 "%s: Timeout or Interrupt occurred while waiting for abort"
10021 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010022 return -ETIMEDOUT;
10023 }
10024 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010025 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010026}
10027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028//Register the module init/exit functions
10029module_init(hdd_module_init);
10030module_exit(hdd_module_exit);
10031
10032MODULE_LICENSE("Dual BSD/GPL");
10033MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10034MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10035
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010036module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10037 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010038
Jeff Johnson76052702013-04-16 13:55:05 -070010039module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010040 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010041
10042module_param(enable_dfs_chan_scan, int,
10043 S_IRUSR | S_IRGRP | S_IROTH);
10044
10045module_param(enable_11d, int,
10046 S_IRUSR | S_IRGRP | S_IROTH);
10047
10048module_param(country_code, charp,
10049 S_IRUSR | S_IRGRP | S_IROTH);