blob: 98e5be254c18aa009f67406b757c91acafce71b3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
37 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
38
39 Qualcomm Confidential and Proprietary.
40
41 ========================================================================*/
42
43/**=========================================================================
44
45 EDIT HISTORY FOR FILE
46
47
48 This section contains comments describing changes made to the module.
49 Notice that changes are listed in reverse chronological order.
50
51
52 $Header:$ $DateTime: $ $Author: $
53
54
55 when who what, where, why
56 -------- --- --------------------------------------------------------
57 04/5/09 Shailender Created module.
58 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
59 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
60 ==========================================================================*/
61
62/*--------------------------------------------------------------------------
63 Include Files
64 ------------------------------------------------------------------------*/
65//#include <wlan_qct_driver.h>
66#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <vos_api.h>
68#include <vos_sched.h>
69#include <vos_power.h>
70#include <linux/etherdevice.h>
71#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070072#ifdef ANI_BUS_TYPE_PLATFORM
73#include <linux/wcnss_wlan.h>
74#endif //ANI_BUS_TYPE_PLATFORM
75#ifdef ANI_BUS_TYPE_PCI
76#include "wcnss_wlan.h"
77#endif /* ANI_BUS_TYPE_PCI */
78#include <wlan_hdd_tx_rx.h>
79#include <palTimer.h>
80#include <wniApi.h>
81#include <wlan_nlink_srv.h>
82#include <wlan_btc_svc.h>
83#include <wlan_hdd_cfg.h>
84#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053085#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070086#include <wlan_hdd_wowl.h>
87#include <wlan_hdd_misc.h>
88#include <wlan_hdd_wext.h>
89#ifdef WLAN_BTAMP_FEATURE
90#include <bap_hdd_main.h>
91#include <bapInternal.h>
92#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053093#include "wlan_hdd_trace.h"
94#include "vos_types.h"
95#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include <linux/wireless.h>
97#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053098#include <linux/inetdevice.h>
99#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "wlan_hdd_cfg80211.h"
101#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700103int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include "sapApi.h"
105#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700106#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
108#include <soc/qcom/subsystem_restart.h>
109#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530111#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include <wlan_hdd_hostapd.h>
113#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_hdd_dev_pwr.h"
116#ifdef WLAN_BTAMP_FEATURE
117#include "bap_hdd_misc.h"
118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700120#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800121#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530122#ifdef FEATURE_WLAN_TDLS
123#include "wlan_hdd_tdls.h"
124#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700125#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700126
127#ifdef MODULE
128#define WLAN_MODULE_NAME module_name(THIS_MODULE)
129#else
130#define WLAN_MODULE_NAME "wlan"
131#endif
132
133#ifdef TIMER_MANAGER
134#define TIMER_MANAGER_STR " +TIMER_MANAGER"
135#else
136#define TIMER_MANAGER_STR ""
137#endif
138
139#ifdef MEMORY_DEBUG
140#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
141#else
142#define MEMORY_DEBUG_STR ""
143#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530144#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700145/* the Android framework expects this param even though we don't use it */
146#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700147static char fwpath_buffer[BUF_LEN];
148static struct kparam_string fwpath = {
149 .string = fwpath_buffer,
150 .maxlen = BUF_LEN,
151};
Arif Hussain66559122013-11-21 10:11:40 -0800152
153static char *country_code;
154static int enable_11d = -1;
155static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530156static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800157
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700159static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161
Jeff Johnsone7245742012-09-05 17:12:55 -0700162/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800163 * spinlock for synchronizing asynchronous request/response
164 * (full description of use in wlan_hdd_main.h)
165 */
166DEFINE_SPINLOCK(hdd_context_lock);
167
168/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700169 * The rate at which the driver sends RESTART event to supplicant
170 * once the function 'vos_wlanRestart()' is called
171 *
172 */
173#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
174#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700175
176/*
177 * Size of Driver command strings from upper layer
178 */
179#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
180#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
181
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800182#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700183#define TID_MIN_VALUE 0
184#define TID_MAX_VALUE 15
185static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
186 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800187static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
188 tCsrEseBeaconReq *pEseBcnReq);
189#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530191static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530192/*
193 * Maximum buffer size used for returning the data back to user space
194 */
195#define WLAN_MAX_BUF_SIZE 1024
196#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700197/*
198 * Driver miracast parameters 0-Disabled
199 * 1-Source, 2-Sink
200 */
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
202#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
203
c_hpothu92367912014-05-01 15:18:17 +0530204//wait time for beacon miss rate.
205#define BCN_MISS_RATE_TIME 500
206
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800207#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700208static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700211static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700212
213//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700214static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
215static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
216static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
217void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800218void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220v_U16_t hdd_select_queue(struct net_device *dev,
221 struct sk_buff *skb);
222
223#ifdef WLAN_FEATURE_PACKET_FILTERING
224static void hdd_set_multicast_list(struct net_device *dev);
225#endif
226
227void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
228
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800230void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
231static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700232static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
233 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
234 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700235static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
236 tANI_U8 *pTargetApBssid,
237 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800238#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800239#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700240VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800241#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700242
Mihir Shetee1093ba2014-01-21 20:13:32 +0530243static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530244const char * hdd_device_modetoString(v_U8_t device_mode)
245{
246 switch(device_mode)
247 {
248 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
249 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
250 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
251 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
252 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
253 CASE_RETURN_STRING( WLAN_HDD_FTM );
254 CASE_RETURN_STRING( WLAN_HDD_IBSS );
255 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
256 default:
257 return "device_mode Unknown";
258 }
259}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530260
Jeff Johnson295189b2012-06-20 16:38:30 -0700261static int hdd_netdev_notifier_call(struct notifier_block * nb,
262 unsigned long state,
263 void *ndev)
264{
265 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700267 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700268#ifdef WLAN_BTAMP_FEATURE
269 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530271 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700274 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700275 (strncmp(dev->name, "p2p", 3)))
276 return NOTIFY_DONE;
277
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700279 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
Jeff Johnson27cee452013-03-27 11:10:24 -0700281 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 VOS_ASSERT(0);
285 return NOTIFY_DONE;
286 }
287
Jeff Johnson27cee452013-03-27 11:10:24 -0700288 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
289 if (NULL == pHddCtx)
290 {
291 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
292 VOS_ASSERT(0);
293 return NOTIFY_DONE;
294 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800295 if (pHddCtx->isLogpInProgress)
296 return NOTIFY_DONE;
297
Jeff Johnson27cee452013-03-27 11:10:24 -0700298
299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
300 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700301
302 switch (state) {
303 case NETDEV_REGISTER:
304 break;
305
306 case NETDEV_UNREGISTER:
307 break;
308
309 case NETDEV_UP:
310 break;
311
312 case NETDEV_DOWN:
313 break;
314
315 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700316 if(TRUE == pAdapter->isLinkUpSvcNeeded)
317 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 break;
319
320 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530322 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
325 "%s: Timeout occurred while waiting for abortscan %ld",
326 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 }
328 else
329 {
330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530331 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700332 }
333#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 status = WLANBAP_StopAmp();
336 if(VOS_STATUS_SUCCESS != status )
337 {
338 pHddCtx->isAmpAllowed = VOS_TRUE;
339 hddLog(VOS_TRACE_LEVEL_FATAL,
340 "%s: Failed to stop AMP", __func__);
341 }
342 else
343 {
344 //a state m/c implementation in PAL is TBD to avoid this delay
345 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700346 if ( pHddCtx->isAmpAllowed )
347 {
348 WLANBAP_DeregisterFromHCI();
349 pHddCtx->isAmpAllowed = VOS_FALSE;
350 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 }
352#endif //WLAN_BTAMP_FEATURE
353 break;
354
355 default:
356 break;
357 }
358
359 return NOTIFY_DONE;
360}
361
362struct notifier_block hdd_netdev_notifier = {
363 .notifier_call = hdd_netdev_notifier_call,
364};
365
366/*---------------------------------------------------------------------------
367 * Function definitions
368 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700369void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
370void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700371//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700372static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700373#ifndef MODULE
374/* current con_mode - used only for statically linked driver
375 * con_mode is changed by userspace to indicate a mode change which will
376 * result in calling the module exit and init functions. The module
377 * exit function will clean up based on the value of con_mode prior to it
378 * being changed by userspace. So curr_con_mode records the current con_mode
379 * for exit when con_mode becomes the next mode for init
380 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700381static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700382#endif
383
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800384/**---------------------------------------------------------------------------
385
386 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
387
388 Called immediately after the cfg.ini is read in order to configure
389 the desired trace levels.
390
391 \param - moduleId - module whose trace level is being configured
392 \param - bitmask - bitmask of log levels to be enabled
393
394 \return - void
395
396 --------------------------------------------------------------------------*/
397static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
398{
399 wpt_tracelevel level;
400
401 /* if the bitmask is the default value, then a bitmask was not
402 specified in cfg.ini, so leave the logging level alone (it
403 will remain at the "compiled in" default value) */
404 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
405 {
406 return;
407 }
408
409 /* a mask was specified. start by disabling all logging */
410 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
411
412 /* now cycle through the bitmask until all "set" bits are serviced */
413 level = VOS_TRACE_LEVEL_FATAL;
414 while (0 != bitmask)
415 {
416 if (bitmask & 1)
417 {
418 vos_trace_setValue(moduleId, level, 1);
419 }
420 level++;
421 bitmask >>= 1;
422 }
423}
424
425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426/**---------------------------------------------------------------------------
427
428 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
429
430 Called immediately after the cfg.ini is read in order to configure
431 the desired trace levels in the WDI.
432
433 \param - moduleId - module whose trace level is being configured
434 \param - bitmask - bitmask of log levels to be enabled
435
436 \return - void
437
438 --------------------------------------------------------------------------*/
439static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
440{
441 wpt_tracelevel level;
442
443 /* if the bitmask is the default value, then a bitmask was not
444 specified in cfg.ini, so leave the logging level alone (it
445 will remain at the "compiled in" default value) */
446 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
447 {
448 return;
449 }
450
451 /* a mask was specified. start by disabling all logging */
452 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
453
454 /* now cycle through the bitmask until all "set" bits are serviced */
455 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
456 while (0 != bitmask)
457 {
458 if (bitmask & 1)
459 {
460 wpalTraceSetLevel(moduleId, level, 1);
461 }
462 level++;
463 bitmask >>= 1;
464 }
465}
Jeff Johnson295189b2012-06-20 16:38:30 -0700466
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530467/*
468 * FUNCTION: wlan_hdd_validate_context
469 * This function is used to check the HDD context
470 */
471int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
472{
473 ENTER();
474
475 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
476 {
477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
478 "%s: HDD context is Null", __func__);
479 return -ENODEV;
480 }
481
482 if (pHddCtx->isLogpInProgress)
483 {
484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
485 "%s: LOGP in Progress. Ignore!!!", __func__);
486 return -EAGAIN;
487 }
488
Mihir Shete18156292014-03-11 15:38:30 +0530489 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530490 {
491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
492 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
493 return -EAGAIN;
494 }
495 return 0;
496}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700497#ifdef CONFIG_ENABLE_LINUX_REG
498void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
499{
500 hdd_adapter_t *pAdapter = NULL;
501 hdd_station_ctx_t *pHddStaCtx = NULL;
502 eCsrPhyMode phyMode;
503 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530504
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700505 if (NULL == pHddCtx)
506 {
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
508 "HDD Context is null !!");
509 return ;
510 }
511
512 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
513 if (NULL == pAdapter)
514 {
515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
516 "pAdapter is null !!");
517 return ;
518 }
519
520 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
521 if (NULL == pHddStaCtx)
522 {
523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
524 "pHddStaCtx is null !!");
525 return ;
526 }
527
528 cfg_param = pHddCtx->cfg_ini;
529 if (NULL == cfg_param)
530 {
531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
532 "cfg_params not available !!");
533 return ;
534 }
535
536 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
537
538 if (!pHddCtx->isVHT80Allowed)
539 {
540 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
541 (eCSR_DOT11_MODE_11ac == phyMode) ||
542 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
543 {
544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
545 "Setting phymode to 11n!!");
546 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
547 }
548 }
549 else
550 {
551 /*New country Supports 11ac as well resetting value back from .ini*/
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
553 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
554 return ;
555 }
556
557 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
558 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
559 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
560 {
561 VOS_STATUS vosStatus;
562
563 // need to issue a disconnect to CSR.
564 INIT_COMPLETION(pAdapter->disconnect_comp_var);
565 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
566 pAdapter->sessionId,
567 eCSR_DISCONNECT_REASON_UNSPECIFIED );
568
569 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530570 {
571 long ret;
572
573 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700574 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530575 if (0 >= ret)
576 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
577 ret);
578 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700579
580 }
581}
582#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530583void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
584{
585 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
586 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
587 hdd_config_t *cfg_param;
588 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530589 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530590
591 if (NULL == pHddCtx)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
594 "HDD Context is null !!");
595 return ;
596 }
597
598 cfg_param = pHddCtx->cfg_ini;
599
600 if (NULL == cfg_param)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "cfg_params not available !!");
604 return ;
605 }
606
607 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
608
609 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
610 {
611 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
612 (eCSR_DOT11_MODE_11ac == phyMode) ||
613 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
616 "Setting phymode to 11n!!");
617 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
618 }
619 }
620 else
621 {
622 /*New country Supports 11ac as well resetting value back from .ini*/
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
624 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
625 return ;
626 }
627
628 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
629 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
630 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
631 {
632 VOS_STATUS vosStatus;
633
634 // need to issue a disconnect to CSR.
635 INIT_COMPLETION(pAdapter->disconnect_comp_var);
636 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
637 pAdapter->sessionId,
638 eCSR_DISCONNECT_REASON_UNSPECIFIED );
639
640 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530641 {
642 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530643 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530644 if (ret <= 0)
645 {
646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
647 "wait on disconnect_comp_var is failed %ld", ret);
648 }
649 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530650
651 }
652}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700653#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530654
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700655void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
656{
657 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
658 hdd_config_t *cfg_param;
659
660 if (NULL == pHddCtx)
661 {
662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
663 "HDD Context is null !!");
664 return ;
665 }
666
667 cfg_param = pHddCtx->cfg_ini;
668
669 if (NULL == cfg_param)
670 {
671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
672 "cfg_params not available !!");
673 return ;
674 }
675
676 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
677 {
678 /*New country doesn't support DFS */
679 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
680 }
681 else
682 {
683 /*New country Supports DFS as well resetting value back from .ini*/
684 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
685 }
686
687}
688
Rajeev79dbe4c2013-10-05 11:03:42 +0530689#ifdef FEATURE_WLAN_BATCH_SCAN
690
691/**---------------------------------------------------------------------------
692
693 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
694 input string
695
696 This function extracts assigned integer from string in below format:
697 "STRING=10" : extracts integer 10 from this string
698
699 \param - pInPtr Pointer to input string
700 \param - base Base for string to int conversion(10 for decimal 16 for hex)
701 \param - pOutPtr Pointer to variable in which extracted integer needs to be
702 assigned
703 \param - pLastArg to tell whether it is last arguement in input string or
704 not
705
706 \return - NULL for failure cases
707 pointer to next arguement in input string for success cases
708 --------------------------------------------------------------------------*/
709static tANI_U8 *
710hdd_extract_assigned_int_from_str
711(
712 tANI_U8 *pInPtr,
713 tANI_U8 base,
714 tANI_U32 *pOutPtr,
715 tANI_U8 *pLastArg
716)
717{
718 int tempInt;
719 int v = 0;
720 char buf[32];
721 int val = 0;
722 *pLastArg = FALSE;
723
724 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
725 if (NULL == pInPtr)
726 {
727 return NULL;
728 }
729
730 pInPtr++;
731
732 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
733
734 val = sscanf(pInPtr, "%32s ", buf);
735 if (val < 0 && val > strlen(pInPtr))
736 {
737 return NULL;
738 }
739 pInPtr += val;
740 v = kstrtos32(buf, base, &tempInt);
741 if (v < 0)
742 {
743 return NULL;
744 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800745 if (tempInt < 0)
746 {
747 tempInt = 0;
748 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530749 *pOutPtr = tempInt;
750
751 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
752 if (NULL == pInPtr)
753 {
754 *pLastArg = TRUE;
755 return NULL;
756 }
757 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
758
759 return pInPtr;
760}
761
762/**---------------------------------------------------------------------------
763
764 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
765 input string
766
767 This function extracts assigned character from string in below format:
768 "STRING=A" : extracts char 'A' from this string
769
770 \param - pInPtr Pointer to input string
771 \param - pOutPtr Pointer to variable in which extracted char needs to be
772 assigned
773 \param - pLastArg to tell whether it is last arguement in input string or
774 not
775
776 \return - NULL for failure cases
777 pointer to next arguement in input string for success cases
778 --------------------------------------------------------------------------*/
779static tANI_U8 *
780hdd_extract_assigned_char_from_str
781(
782 tANI_U8 *pInPtr,
783 tANI_U8 *pOutPtr,
784 tANI_U8 *pLastArg
785)
786{
787 *pLastArg = FALSE;
788
789 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
790 if (NULL == pInPtr)
791 {
792 return NULL;
793 }
794
795 pInPtr++;
796
797 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
798
799 *pOutPtr = *pInPtr;
800
801 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
802 if (NULL == pInPtr)
803 {
804 *pLastArg = TRUE;
805 return NULL;
806 }
807 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
808
809 return pInPtr;
810}
811
812
813/**---------------------------------------------------------------------------
814
815 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
816
817 This function parses set batch scan command in below format:
818 WLS_BATCHING_SET <space> followed by below arguements
819 "SCANFREQ=XX" : Optional defaults to 30 sec
820 "MSCAN=XX" : Required number of scans to attempt to batch
821 "BESTN=XX" : Best Network (RSSI) defaults to 16
822 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
823 A. implies only 5 GHz , B. implies only 2.4GHz
824 "RTT=X" : optional defaults to 0
825 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
826 error
827
828 For example input commands:
829 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
830 translated into set batch scan with following parameters:
831 a) Frequence 60 seconds
832 b) Batch 10 scans together
833 c) Best RSSI to be 20
834 d) 5GHz band only
835 e) RTT is equal to 0
836
837 \param - pValue Pointer to input channel list
838 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
839
840 \return - 0 for success non-zero for failure
841
842 --------------------------------------------------------------------------*/
843static int
844hdd_parse_set_batchscan_command
845(
846 tANI_U8 *pValue,
847 tSirSetBatchScanReq *pHddSetBatchScanReq
848)
849{
850 tANI_U8 *inPtr = pValue;
851 tANI_U8 val = 0;
852 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800853 tANI_U32 nScanFreq;
854 tANI_U32 nMscan;
855 tANI_U32 nBestN;
856 tANI_U8 ucRfBand;
857 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800858 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530859
860 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800861 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
862 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
863 nRtt = 0;
864 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530865
866 /*go to space after WLS_BATCHING_SET command*/
867 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
868 /*no argument after the command*/
869 if (NULL == inPtr)
870 {
871 return -EINVAL;
872 }
873
874 /*no space after the command*/
875 else if (SPACE_ASCII_VALUE != *inPtr)
876 {
877 return -EINVAL;
878 }
879
880 /*removing empty spaces*/
881 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
882
883 /*no argument followed by spaces*/
884 if ('\0' == *inPtr)
885 {
886 return -EINVAL;
887 }
888
889 /*check and parse SCANFREQ*/
890 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
891 {
892 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800893 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800894
Rajeev Kumarc933d982013-11-18 20:04:20 -0800895 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800896 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800897 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800898 }
899
Rajeev79dbe4c2013-10-05 11:03:42 +0530900 if ( (NULL == inPtr) || (TRUE == lastArg))
901 {
902 return -EINVAL;
903 }
904 }
905
906 /*check and parse MSCAN*/
907 if ((strncmp(inPtr, "MSCAN", 5) == 0))
908 {
909 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800910 &nMscan, &lastArg);
911
912 if (0 == nMscan)
913 {
914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
915 "invalid MSCAN=%d", nMscan);
916 return -EINVAL;
917 }
918
Rajeev79dbe4c2013-10-05 11:03:42 +0530919 if (TRUE == lastArg)
920 {
921 goto done;
922 }
923 else if (NULL == inPtr)
924 {
925 return -EINVAL;
926 }
927 }
928 else
929 {
930 return -EINVAL;
931 }
932
933 /*check and parse BESTN*/
934 if ((strncmp(inPtr, "BESTN", 5) == 0))
935 {
936 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800937 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800938
Rajeev Kumarc933d982013-11-18 20:04:20 -0800939 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800940 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800941 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800942 }
943
Rajeev79dbe4c2013-10-05 11:03:42 +0530944 if (TRUE == lastArg)
945 {
946 goto done;
947 }
948 else if (NULL == inPtr)
949 {
950 return -EINVAL;
951 }
952 }
953
954 /*check and parse CHANNEL*/
955 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
956 {
957 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800958
Rajeev79dbe4c2013-10-05 11:03:42 +0530959 if (('A' == val) || ('a' == val))
960 {
c_hpothuebf89732014-02-25 13:00:24 +0530961 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530962 }
963 else if (('B' == val) || ('b' == val))
964 {
c_hpothuebf89732014-02-25 13:00:24 +0530965 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 }
967 else
968 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800969 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
970 }
971
972 if (TRUE == lastArg)
973 {
974 goto done;
975 }
976 else if (NULL == inPtr)
977 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530978 return -EINVAL;
979 }
980 }
981
982 /*check and parse RTT*/
983 if ((strncmp(inPtr, "RTT", 3) == 0))
984 {
985 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800986 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530987 if (TRUE == lastArg)
988 {
989 goto done;
990 }
991 if (NULL == inPtr)
992 {
993 return -EINVAL;
994 }
995 }
996
997
998done:
999
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001000 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1001 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1002 pHddSetBatchScanReq->bestNetwork = nBestN;
1003 pHddSetBatchScanReq->rfBand = ucRfBand;
1004 pHddSetBatchScanReq->rtt = nRtt;
1005
Rajeev79dbe4c2013-10-05 11:03:42 +05301006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1007 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1008 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1009 pHddSetBatchScanReq->scanFrequency,
1010 pHddSetBatchScanReq->numberOfScansToBatch,
1011 pHddSetBatchScanReq->bestNetwork,
1012 pHddSetBatchScanReq->rfBand,
1013 pHddSetBatchScanReq->rtt);
1014
1015 return 0;
1016}/*End of hdd_parse_set_batchscan_command*/
1017
1018/**---------------------------------------------------------------------------
1019
1020 \brief hdd_set_batch_scan_req_callback () - This function is called after
1021 receiving set batch scan response from FW and it saves set batch scan
1022 response data FW to HDD context and sets the completion event on
1023 which hdd_ioctl is waiting
1024
1025 \param - callbackContext Pointer to HDD adapter
1026 \param - pRsp Pointer to set batch scan response data received from FW
1027
1028 \return - nothing
1029
1030 --------------------------------------------------------------------------*/
1031static void hdd_set_batch_scan_req_callback
1032(
1033 void *callbackContext,
1034 tSirSetBatchScanRsp *pRsp
1035)
1036{
1037 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1038 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1039
1040 /*sanity check*/
1041 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1042 {
1043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1044 "%s: Invalid pAdapter magic", __func__);
1045 VOS_ASSERT(0);
1046 return;
1047 }
1048 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1049
1050 /*save set batch scan response*/
1051 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1052
1053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1054 "Received set batch scan rsp from FW with nScansToBatch=%d",
1055 pHddSetBatchScanRsp->nScansToBatch);
1056
1057 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1058 complete(&pAdapter->hdd_set_batch_scan_req_var);
1059
1060 return;
1061}/*End of hdd_set_batch_scan_req_callback*/
1062
1063
1064/**---------------------------------------------------------------------------
1065
1066 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1067 info in hdd batch scan response queue
1068
1069 \param - pAdapter Pointer to hdd adapter
1070 \param - pAPMetaInfo Pointer to access point meta info
1071 \param - scanId scan ID of batch scan response
1072 \param - isLastAp tells whether AP is last AP in batch scan response or not
1073
1074 \return - nothing
1075
1076 --------------------------------------------------------------------------*/
1077static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1078 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1079{
1080 tHddBatchScanRsp *pHead;
1081 tHddBatchScanRsp *pNode;
1082 tHddBatchScanRsp *pPrev;
1083 tHddBatchScanRsp *pTemp;
1084 tANI_U8 ssidLen;
1085
1086 /*head of hdd batch scan response queue*/
1087 pHead = pAdapter->pBatchScanRsp;
1088
1089 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1090 if (NULL == pNode)
1091 {
1092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1093 "%s: Could not allocate memory", __func__);
1094 VOS_ASSERT(0);
1095 return;
1096 }
1097
1098 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1099 sizeof(pNode->ApInfo.bssid));
1100 ssidLen = strlen(pApMetaInfo->ssid);
1101 if (SIR_MAX_SSID_SIZE < ssidLen)
1102 {
1103 /*invalid scan result*/
1104 vos_mem_free(pNode);
1105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1106 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1107 return;
1108 }
1109 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1110 /*null terminate ssid*/
1111 pNode->ApInfo.ssid[ssidLen] = '\0';
1112 pNode->ApInfo.ch = pApMetaInfo->ch;
1113 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1114 pNode->ApInfo.age = pApMetaInfo->timestamp;
1115 pNode->ApInfo.batchId = scanId;
1116 pNode->ApInfo.isLastAp = isLastAp;
1117
1118 pNode->pNext = NULL;
1119 if (NULL == pHead)
1120 {
1121 pAdapter->pBatchScanRsp = pNode;
1122 }
1123 else
1124 {
1125 pTemp = pHead;
1126 while (NULL != pTemp)
1127 {
1128 pPrev = pTemp;
1129 pTemp = pTemp->pNext;
1130 }
1131 pPrev->pNext = pNode;
1132 }
1133
1134 return;
1135}/*End of hdd_populate_batch_scan_rsp_queue*/
1136
1137/**---------------------------------------------------------------------------
1138
1139 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1140 receiving batch scan response indication from FW. It saves get batch scan
1141 response data in HDD batch scan response queue. This callback sets the
1142 completion event on which hdd_ioctl is waiting only after getting complete
1143 batch scan response data from FW
1144
1145 \param - callbackContext Pointer to HDD adapter
1146 \param - pRsp Pointer to get batch scan response data received from FW
1147
1148 \return - nothing
1149
1150 --------------------------------------------------------------------------*/
1151static void hdd_batch_scan_result_ind_callback
1152(
1153 void *callbackContext,
1154 void *pRsp
1155)
1156{
1157 v_BOOL_t isLastAp;
1158 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001159 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301160 tANI_U32 numberScanList;
1161 tANI_U32 nextScanListOffset;
1162 tANI_U32 nextApMetaInfoOffset;
1163 hdd_adapter_t* pAdapter;
1164 tpSirBatchScanList pScanList;
1165 tpSirBatchScanNetworkInfo pApMetaInfo;
1166 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1167 tSirSetBatchScanReq *pReq;
1168
1169 pAdapter = (hdd_adapter_t *)callbackContext;
1170 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001171 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301172 {
1173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1174 "%s: Invalid pAdapter magic", __func__);
1175 VOS_ASSERT(0);
1176 return;
1177 }
1178
1179 /*initialize locals*/
1180 pReq = &pAdapter->hddSetBatchScanReq;
1181 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1182 isLastAp = FALSE;
1183 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001184 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301185 numberScanList = 0;
1186 nextScanListOffset = 0;
1187 nextApMetaInfoOffset = 0;
1188 pScanList = NULL;
1189 pApMetaInfo = NULL;
1190
1191 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1192 {
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1195 isLastAp = TRUE;
1196 goto done;
1197 }
1198
1199 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "Batch scan rsp: numberScalList %d", numberScanList);
1202
1203 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1204 {
1205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1206 "%s: numberScanList %d", __func__, numberScanList);
1207 isLastAp = TRUE;
1208 goto done;
1209 }
1210
1211 while (numberScanList)
1212 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001213 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301214 nextScanListOffset);
1215 if (NULL == pScanList)
1216 {
1217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1218 "%s: pScanList is %p", __func__, pScanList);
1219 isLastAp = TRUE;
1220 goto done;
1221 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001222 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001224 "Batch scan rsp: numApMetaInfo %d scanId %d",
1225 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301226
1227 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1228 {
1229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1230 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1231 isLastAp = TRUE;
1232 goto done;
1233 }
1234
Rajeev Kumarce651e42013-10-21 18:57:15 -07001235 /*Initialize next AP meta info offset for next scan list*/
1236 nextApMetaInfoOffset = 0;
1237
Rajeev79dbe4c2013-10-05 11:03:42 +05301238 while (numApMetaInfo)
1239 {
1240 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1241 nextApMetaInfoOffset);
1242 if (NULL == pApMetaInfo)
1243 {
1244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1245 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1246 isLastAp = TRUE;
1247 goto done;
1248 }
1249 /*calculate AP age*/
1250 pApMetaInfo->timestamp =
1251 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1252
1253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001254 "%s: bssId "MAC_ADDRESS_STR
1255 " ch %d rssi %d timestamp %d", __func__,
1256 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1257 pApMetaInfo->ch, pApMetaInfo->rssi,
1258 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301259
1260 /*mark last AP in batch scan response*/
1261 if ((TRUE == pBatchScanRsp->isLastResult) &&
1262 (1 == numberScanList) && (1 == numApMetaInfo))
1263 {
1264 isLastAp = TRUE;
1265 }
1266
1267 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1268 /*store batch scan repsonse in hdd queue*/
1269 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1270 pScanList->scanId, isLastAp);
1271 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1272
1273 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1274 numApMetaInfo--;
1275 }
1276
Rajeev Kumarce651e42013-10-21 18:57:15 -07001277 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1278 + (sizeof(tSirBatchScanNetworkInfo)
1279 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301280 numberScanList--;
1281 }
1282
1283done:
1284
1285 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1286 requested from hdd_ioctl*/
1287 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1288 (TRUE == isLastAp))
1289 {
1290 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1291 complete(&pAdapter->hdd_get_batch_scan_req_var);
1292 }
1293
1294 return;
1295}/*End of hdd_batch_scan_result_ind_callback*/
1296
1297/**---------------------------------------------------------------------------
1298
1299 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1300 response as per batch scan FR request format by putting proper markers
1301
1302 \param - pDest pointer to destination buffer
1303 \param - cur_len current length
1304 \param - tot_len total remaining size which can be written to user space
1305 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1306 \param - pAdapter Pointer to HDD adapter
1307
1308 \return - ret no of characters written
1309
1310 --------------------------------------------------------------------------*/
1311static tANI_U32
1312hdd_format_batch_scan_rsp
1313(
1314 tANI_U8 *pDest,
1315 tANI_U32 cur_len,
1316 tANI_U32 tot_len,
1317 tHddBatchScanRsp *pApMetaInfo,
1318 hdd_adapter_t* pAdapter
1319)
1320{
1321 tANI_U32 ret = 0;
1322 tANI_U32 rem_len = 0;
1323 tANI_U8 temp_len = 0;
1324 tANI_U8 temp_total_len = 0;
1325 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1326 tANI_U8 *pTemp = temp;
1327
1328 /*Batch scan reponse needs to be returned to user space in
1329 following format:
1330 "scancount=X\n" where X is the number of scans in current batch
1331 batch
1332 "trunc\n" optional present if current scan truncated
1333 "bssid=XX:XX:XX:XX:XX:XX\n"
1334 "ssid=XXXX\n"
1335 "freq=X\n" frequency in Mhz
1336 "level=XX\n"
1337 "age=X\n" ms
1338 "dist=X\n" cm (-1 if not available)
1339 "errror=X\n" (-1if not available)
1340 "====\n" (end of ap marker)
1341 "####\n" (end of scan marker)
1342 "----\n" (end of results)*/
1343 /*send scan result in above format to user space based on
1344 available length*/
1345 /*The GET response may have more data than the driver can return in its
1346 buffer. In that case the buffer should be filled to the nearest complete
1347 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1348 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1349 The final buffer should end with "----\n"*/
1350
1351 /*sanity*/
1352 if (cur_len > tot_len)
1353 {
1354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1355 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1356 return 0;
1357 }
1358 else
1359 {
1360 rem_len = (tot_len - cur_len);
1361 }
1362
1363 /*end scan marker*/
1364 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1365 {
1366 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1367 pTemp += temp_len;
1368 temp_total_len += temp_len;
1369 }
1370
1371 /*bssid*/
1372 temp_len = snprintf(pTemp, sizeof(temp),
1373 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1374 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1375 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1376 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1377 pTemp += temp_len;
1378 temp_total_len += temp_len;
1379
1380 /*ssid*/
1381 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1382 pApMetaInfo->ApInfo.ssid);
1383 pTemp += temp_len;
1384 temp_total_len += temp_len;
1385
1386 /*freq*/
1387 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001388 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301389 pTemp += temp_len;
1390 temp_total_len += temp_len;
1391
1392 /*level*/
1393 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1394 pApMetaInfo->ApInfo.rssi);
1395 pTemp += temp_len;
1396 temp_total_len += temp_len;
1397
1398 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001399 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301400 pApMetaInfo->ApInfo.age);
1401 pTemp += temp_len;
1402 temp_total_len += temp_len;
1403
1404 /*dist*/
1405 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1406 pTemp += temp_len;
1407 temp_total_len += temp_len;
1408
1409 /*error*/
1410 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1411 pTemp += temp_len;
1412 temp_total_len += temp_len;
1413
1414 /*end AP marker*/
1415 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1416 pTemp += temp_len;
1417 temp_total_len += temp_len;
1418
1419 /*last AP in batch scan response*/
1420 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1421 {
1422 /*end scan marker*/
1423 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1424 pTemp += temp_len;
1425 temp_total_len += temp_len;
1426
1427 /*end batch scan result marker*/
1428 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1429 pTemp += temp_len;
1430 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001431
Rajeev79dbe4c2013-10-05 11:03:42 +05301432 }
1433
1434 if (temp_total_len < rem_len)
1435 {
1436 ret = temp_total_len + 1;
1437 strlcpy(pDest, temp, ret);
1438 pAdapter->isTruncated = FALSE;
1439 }
1440 else
1441 {
1442 pAdapter->isTruncated = TRUE;
1443 if (rem_len >= strlen("%%%%"))
1444 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001445 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301446 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001447 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301448 {
1449 ret = 0;
1450 }
1451 }
1452
1453 return ret;
1454
1455}/*End of hdd_format_batch_scan_rsp*/
1456
1457/**---------------------------------------------------------------------------
1458
1459 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1460 buffer starting with head of hdd batch scan response queue
1461
1462 \param - pAdapter Pointer to HDD adapter
1463 \param - pDest Pointer to user data buffer
1464 \param - cur_len current offset in user buffer
1465 \param - rem_len remaining no of bytes in user buffer
1466
1467 \return - number of bytes written in user buffer
1468
1469 --------------------------------------------------------------------------*/
1470
1471tANI_U32 hdd_populate_user_batch_scan_rsp
1472(
1473 hdd_adapter_t* pAdapter,
1474 tANI_U8 *pDest,
1475 tANI_U32 cur_len,
1476 tANI_U32 rem_len
1477)
1478{
1479 tHddBatchScanRsp *pHead;
1480 tHddBatchScanRsp *pPrev;
1481 tANI_U32 len;
1482
Rajeev79dbe4c2013-10-05 11:03:42 +05301483 pAdapter->isTruncated = FALSE;
1484
1485 /*head of hdd batch scan response queue*/
1486 pHead = pAdapter->pBatchScanRsp;
1487 while (pHead)
1488 {
1489 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1490 pAdapter);
1491 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001492 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301493 cur_len += len;
1494 if(TRUE == pAdapter->isTruncated)
1495 {
1496 /*result is truncated return rest of scan rsp in next req*/
1497 cur_len = rem_len;
1498 break;
1499 }
1500 pPrev = pHead;
1501 pHead = pHead->pNext;
1502 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001503 if (TRUE == pPrev->ApInfo.isLastAp)
1504 {
1505 pAdapter->prev_batch_id = 0;
1506 }
1507 else
1508 {
1509 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1510 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301511 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001512 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301513 }
1514
1515 return cur_len;
1516}/*End of hdd_populate_user_batch_scan_rsp*/
1517
1518/**---------------------------------------------------------------------------
1519
1520 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1521 scan response data from HDD queue to user space
1522 It does following in detail:
1523 a) if HDD has enough data in its queue then it 1st copies data to user
1524 space and then send get batch scan indication message to FW. In this
1525 case it does not wait on any event and batch scan response data will
1526 be populated in HDD response queue in MC thread context after receiving
1527 indication from FW
1528 b) else send get batch scan indication message to FW and wait on an event
1529 which will be set once HDD receives complete batch scan response from
1530 FW and then this function returns batch scan response to user space
1531
1532 \param - pAdapter Pointer to HDD adapter
1533 \param - pPrivData Pointer to priv_data
1534
1535 \return - 0 for success -EFAULT for failure
1536
1537 --------------------------------------------------------------------------*/
1538
1539int hdd_return_batch_scan_rsp_to_user
1540(
1541 hdd_adapter_t* pAdapter,
1542 hdd_priv_data_t *pPrivData,
1543 tANI_U8 *command
1544)
1545{
1546 tANI_U8 *pDest;
1547 tANI_U32 count = 0;
1548 tANI_U32 len = 0;
1549 tANI_U32 cur_len = 0;
1550 tANI_U32 rem_len = 0;
1551 eHalStatus halStatus;
1552 unsigned long rc;
1553 tSirTriggerBatchScanResultInd *pReq;
1554
1555 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1556 pReq->param = 0;/*batch scan client*/
1557 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1558 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1559
1560 cur_len = pPrivData->used_len;
1561 if (pPrivData->total_len > pPrivData->used_len)
1562 {
1563 rem_len = pPrivData->total_len - pPrivData->used_len;
1564 }
1565 else
1566 {
1567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1568 "%s: Invalid user data buffer total_len %d used_len %d",
1569 __func__, pPrivData->total_len, pPrivData->used_len);
1570 return -EFAULT;
1571 }
1572
1573 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1574 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1575 cur_len, rem_len);
1576 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1577
1578 /*enough scan result available in cache to return to user space or
1579 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001580 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301581 {
1582 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1583 halStatus = sme_TriggerBatchScanResultInd(
1584 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1585 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1586 pAdapter);
1587 if ( eHAL_STATUS_SUCCESS == halStatus )
1588 {
1589 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1590 {
1591 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1592 rc = wait_for_completion_timeout(
1593 &pAdapter->hdd_get_batch_scan_req_var,
1594 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1595 if (0 == rc)
1596 {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 "%s: Timeout waiting to fetch batch scan rsp from fw",
1599 __func__);
1600 return -EFAULT;
1601 }
1602 }
1603
1604 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001605 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301606 pDest += len;
1607 cur_len += len;
1608
1609 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1610 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1611 cur_len, rem_len);
1612 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1613
1614 count = 0;
1615 len = (len - pPrivData->used_len);
1616 pDest = (command + pPrivData->used_len);
1617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001618 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301619 while(count < len)
1620 {
1621 printk("%c", *(pDest + count));
1622 count++;
1623 }
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1625 "%s: copy %d data to user buffer", __func__, len);
1626 if (copy_to_user(pPrivData->buf, pDest, len))
1627 {
1628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1629 "%s: failed to copy data to user buffer", __func__);
1630 return -EFAULT;
1631 }
1632 }
1633 else
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "sme_GetBatchScanScan returned failure halStatus %d",
1637 halStatus);
1638 return -EINVAL;
1639 }
1640 }
1641 else
1642 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301643 count = 0;
1644 len = (len - pPrivData->used_len);
1645 pDest = (command + pPrivData->used_len);
1646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001647 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301648 while(count < len)
1649 {
1650 printk("%c", *(pDest + count));
1651 count++;
1652 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1654 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 if (copy_to_user(pPrivData->buf, pDest, len))
1656 {
1657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1658 "%s: failed to copy data to user buffer", __func__);
1659 return -EFAULT;
1660 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301661 }
1662
1663 return 0;
1664} /*End of hdd_return_batch_scan_rsp_to_user*/
1665
Rajeev Kumar8b373292014-01-08 20:36:55 -08001666
1667/**---------------------------------------------------------------------------
1668
1669 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1670 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1671 WLS_BATCHING VERSION
1672 WLS_BATCHING SET
1673 WLS_BATCHING GET
1674 WLS_BATCHING STOP
1675
1676 \param - pAdapter Pointer to HDD adapter
1677 \param - pPrivdata Pointer to priv_data
1678 \param - command Pointer to command
1679
1680 \return - 0 for success -EFAULT for failure
1681
1682 --------------------------------------------------------------------------*/
1683
1684int hdd_handle_batch_scan_ioctl
1685(
1686 hdd_adapter_t *pAdapter,
1687 hdd_priv_data_t *pPrivdata,
1688 tANI_U8 *command
1689)
1690{
1691 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001692 hdd_context_t *pHddCtx;
1693
1694 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1695 ret = wlan_hdd_validate_context(pHddCtx);
1696 if (ret)
1697 {
1698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1699 "%s: HDD context is not valid!", __func__);
1700 goto exit;
1701 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001702
1703 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1704 {
1705 char extra[32];
1706 tANI_U8 len = 0;
1707 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1708
1709 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1710 {
1711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1712 "%s: Batch scan feature is not supported by FW", __func__);
1713 ret = -EINVAL;
1714 goto exit;
1715 }
1716
1717 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1718 version);
1719 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1720 {
1721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1722 "%s: failed to copy data to user buffer", __func__);
1723 ret = -EFAULT;
1724 goto exit;
1725 }
1726 ret = HDD_BATCH_SCAN_VERSION;
1727 }
1728 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1729 {
1730 int status;
1731 tANI_U8 *value = (command + 16);
1732 eHalStatus halStatus;
1733 unsigned long rc;
1734 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1735 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1736
1737 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1738 {
1739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1740 "%s: Batch scan feature is not supported by FW", __func__);
1741 ret = -EINVAL;
1742 goto exit;
1743 }
1744
1745 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1746 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1747 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1748 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1749 {
1750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301751 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001752 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301753 hdd_device_modetoString(pAdapter->device_mode),
1754 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001755 ret = -EINVAL;
1756 goto exit;
1757 }
1758
1759 status = hdd_parse_set_batchscan_command(value, pReq);
1760 if (status)
1761 {
1762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1763 "Invalid WLS_BATCHING SET command");
1764 ret = -EINVAL;
1765 goto exit;
1766 }
1767
1768
1769 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1770 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1771 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1772 pAdapter);
1773
1774 if ( eHAL_STATUS_SUCCESS == halStatus )
1775 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301776 char extra[32];
1777 tANI_U8 len = 0;
1778 tANI_U8 mScan = 0;
1779
Rajeev Kumar8b373292014-01-08 20:36:55 -08001780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1781 "sme_SetBatchScanReq returned success halStatus %d",
1782 halStatus);
1783 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1784 {
1785 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1786 rc = wait_for_completion_timeout(
1787 &pAdapter->hdd_set_batch_scan_req_var,
1788 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1789 if (0 == rc)
1790 {
1791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 "%s: Timeout waiting for set batch scan to complete",
1793 __func__);
1794 ret = -EINVAL;
1795 goto exit;
1796 }
1797 }
1798 if ( !pRsp->nScansToBatch )
1799 {
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1801 "%s: Received set batch scan failure response from FW",
1802 __func__);
1803 ret = -EINVAL;
1804 goto exit;
1805 }
1806 /*As per the Batch Scan Framework API we should return the MIN of
1807 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301808 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001809
1810 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1811
1812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1813 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301814 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1815 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1816 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1817 {
1818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 "%s: failed to copy MSCAN value to user buffer", __func__);
1820 ret = -EFAULT;
1821 goto exit;
1822 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001823 }
1824 else
1825 {
1826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1827 "sme_SetBatchScanReq returned failure halStatus %d",
1828 halStatus);
1829 ret = -EINVAL;
1830 goto exit;
1831 }
1832 }
1833 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1834 {
1835 eHalStatus halStatus;
1836 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1837 pInd->param = 0;
1838
1839 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1840 {
1841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1842 "%s: Batch scan feature is not supported by FW", __func__);
1843 ret = -EINVAL;
1844 goto exit;
1845 }
1846
1847 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1848 {
1849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1850 "Batch scan is not yet enabled batch scan state %d",
1851 pAdapter->batchScanState);
1852 ret = -EINVAL;
1853 goto exit;
1854 }
1855
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001856 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1857 hdd_deinit_batch_scan(pAdapter);
1858 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1859
Rajeev Kumar8b373292014-01-08 20:36:55 -08001860 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1861
1862 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1863 pAdapter->sessionId);
1864 if ( eHAL_STATUS_SUCCESS == halStatus )
1865 {
1866 ret = 0;
1867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "sme_StopBatchScanInd returned success halStatus %d",
1869 halStatus);
1870 }
1871 else
1872 {
1873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1874 "sme_StopBatchScanInd returned failure halStatus %d",
1875 halStatus);
1876 ret = -EINVAL;
1877 goto exit;
1878 }
1879 }
1880 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1881 {
1882 tANI_U32 remain_len;
1883
1884 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1885 {
1886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1887 "%s: Batch scan feature is not supported by FW", __func__);
1888 ret = -EINVAL;
1889 goto exit;
1890 }
1891
1892 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1893 {
1894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1895 "Batch scan is not yet enabled could not return results"
1896 "Batch Scan state %d",
1897 pAdapter->batchScanState);
1898 ret = -EINVAL;
1899 goto exit;
1900 }
1901
1902 pPrivdata->used_len = 16;
1903 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1904 if (remain_len < pPrivdata->total_len)
1905 {
1906 /*Clear previous batch scan response data if any*/
1907 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1908 }
1909 else
1910 {
1911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1912 "Invalid total length from user space can't fetch batch"
1913 " scan response total_len %d used_len %d remain len %d",
1914 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1915 ret = -EINVAL;
1916 goto exit;
1917 }
1918 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1919 }
1920
1921exit:
1922
1923 return ret;
1924}
1925
1926
Rajeev79dbe4c2013-10-05 11:03:42 +05301927#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1928
c_hpothu92367912014-05-01 15:18:17 +05301929static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1930{
c_hpothu39eb1e32014-06-26 16:31:50 +05301931 bcnMissRateContext_t *pCBCtx;
1932
1933 if (NULL == data)
1934 {
1935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1936 return;
1937 }
c_hpothu92367912014-05-01 15:18:17 +05301938
1939 /* there is a race condition that exists between this callback
1940 function and the caller since the caller could time out either
1941 before or while this code is executing. we use a spinlock to
1942 serialize these actions */
1943 spin_lock(&hdd_context_lock);
1944
c_hpothu39eb1e32014-06-26 16:31:50 +05301945 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301946 gbcnMissRate = -1;
1947
c_hpothu39eb1e32014-06-26 16:31:50 +05301948 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301952 spin_unlock(&hdd_context_lock);
1953 return ;
1954 }
1955
1956 if (VOS_STATUS_SUCCESS == status)
1957 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301959 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301960 else
1961 {
1962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1963 }
1964
c_hpothu92367912014-05-01 15:18:17 +05301965 complete(&(pCBCtx->completion));
1966 spin_unlock(&hdd_context_lock);
1967
1968 return;
1969}
1970
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301971static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1972{
1973 int ret = 0;
1974
1975 if (!pCfg || !command || !extra || !len)
1976 {
1977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1978 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1979 ret = -EINVAL;
1980 return ret;
1981 }
1982
1983 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1984 {
1985 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1986 (int)pCfg->nActiveMaxChnTime);
1987 return ret;
1988 }
1989 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1990 {
1991 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1992 (int)pCfg->nActiveMinChnTime);
1993 return ret;
1994 }
1995 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1996 {
1997 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1998 (int)pCfg->nPassiveMaxChnTime);
1999 return ret;
2000 }
2001 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2002 {
2003 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2004 (int)pCfg->nPassiveMinChnTime);
2005 return ret;
2006 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302007 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2008 {
2009 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2010 (int)pCfg->nActiveMaxChnTime);
2011 return ret;
2012 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302013 else
2014 {
2015 ret = -EINVAL;
2016 }
2017
2018 return ret;
2019}
2020
2021static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2022{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302023 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302024 hdd_config_t *pCfg;
2025 tANI_U8 *value = command;
2026 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302027 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302028
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302029 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2030 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302031 {
2032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2033 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2034 ret = -EINVAL;
2035 return ret;
2036 }
2037
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302038 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2039 sme_GetConfigParam(hHal, &smeConfig);
2040
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302041 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2042 {
2043 value = value + 24;
2044 temp = kstrtou32(value, 10, &val);
2045 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2046 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2047 {
2048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2049 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2050 ret = -EFAULT;
2051 return ret;
2052 }
2053 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302054 smeConfig.csrConfig.nActiveMaxChnTime = val;
2055 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302056 }
2057 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2058 {
2059 value = value + 24;
2060 temp = kstrtou32(value, 10, &val);
2061 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2062 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2063 {
2064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2065 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2066 ret = -EFAULT;
2067 return ret;
2068 }
2069 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302070 smeConfig.csrConfig.nActiveMinChnTime = val;
2071 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302072 }
2073 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2074 {
2075 value = value + 25;
2076 temp = kstrtou32(value, 10, &val);
2077 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2078 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2079 {
2080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2081 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2082 ret = -EFAULT;
2083 return ret;
2084 }
2085 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302086 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2087 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302088 }
2089 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2090 {
2091 value = value + 25;
2092 temp = kstrtou32(value, 10, &val);
2093 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2094 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2095 {
2096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2097 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2098 ret = -EFAULT;
2099 return ret;
2100 }
2101 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302102 smeConfig.csrConfig.nPassiveMinChnTime = val;
2103 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302104 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302105 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2106 {
2107 value = value + 13;
2108 temp = kstrtou32(value, 10, &val);
2109 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2110 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2111 {
2112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2113 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2114 ret = -EFAULT;
2115 return ret;
2116 }
2117 pCfg->nActiveMaxChnTime = val;
2118 smeConfig.csrConfig.nActiveMaxChnTime = val;
2119 sme_UpdateConfig(hHal, &smeConfig);
2120 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302121 else
2122 {
2123 ret = -EINVAL;
2124 }
2125
2126 return ret;
2127}
2128
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002129static int hdd_driver_command(hdd_adapter_t *pAdapter,
2130 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002131{
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 hdd_priv_data_t priv_data;
2133 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002134 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002135
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002136 /*
2137 * Note that valid pointers are provided by caller
2138 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002139
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002140 /* copy to local struct to avoid numerous changes to legacy code */
2141 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002143 if (priv_data.total_len <= 0 ||
2144 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002145 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002146 hddLog(VOS_TRACE_LEVEL_WARN,
2147 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2148 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002149 ret = -EINVAL;
2150 goto exit;
2151 }
2152
2153 /* Allocate +1 for '\0' */
2154 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 if (!command)
2156 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002157 hddLog(VOS_TRACE_LEVEL_ERROR,
2158 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 ret = -ENOMEM;
2160 goto exit;
2161 }
2162
2163 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2164 {
2165 ret = -EFAULT;
2166 goto exit;
2167 }
2168
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002169 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002170 command[priv_data.total_len] = '\0';
2171
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002172 /* at one time the following block of code was conditional. braces
2173 * have been retained to avoid re-indenting the legacy code
2174 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 {
2176 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2177
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002179 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002180
2181 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2182 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2184 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2185 pAdapter->sessionId, (unsigned)
2186 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2187 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2188 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2189 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2191 sizeof(tSirMacAddr)))
2192 {
2193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002194 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 ret = -EFAULT;
2196 }
2197 }
Amar Singhal0974e402013-02-12 14:27:46 -08002198 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 {
Amar Singhal0974e402013-02-12 14:27:46 -08002200 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002201
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002203
2204 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002207 "%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 -07002208 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002209 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302210 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302211 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002212 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002213 }
Kiet Lamf040f472013-11-20 21:15:23 +05302214 else if(strncmp(command, "SETWMMPS", 8) == 0)
2215 {
2216 tANI_U8 *ptr = command;
2217 ret = hdd_wmmps_helper(pAdapter, ptr);
2218 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002219 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2220 {
2221 char *country_code;
2222
2223 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002224
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002225 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002226 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002227#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302228 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002229#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002230 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2231 (void *)(tSmeChangeCountryCallback)
2232 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302233 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002234 if (eHAL_STATUS_SUCCESS == ret)
2235 {
2236 ret = wait_for_completion_interruptible_timeout(
2237 &pAdapter->change_country_code,
2238 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2239 if (0 >= ret)
2240 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302242 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002243 }
2244 }
2245 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002246 {
2247 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002248 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002249 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002250 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002251
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002252 }
2253 /*
2254 command should be a string having format
2255 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2256 */
Amar Singhal0974e402013-02-12 14:27:46 -08002257 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002258 {
Amar Singhal0974e402013-02-12 14:27:46 -08002259 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002260
2261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002262 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002263
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002264 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002265 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002266 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2267 {
2268 int suspend = 0;
2269 tANI_U8 *ptr = (tANI_U8*)command + 15;
2270
2271 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302272 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2273 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2274 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002275 hdd_set_wlan_suspend_mode(suspend);
2276 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002277#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2278 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2279 {
2280 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002281 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002282 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2283 eHalStatus status = eHAL_STATUS_SUCCESS;
2284
2285 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2286 value = value + 15;
2287
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002288 /* Convert the value from ascii to integer */
2289 ret = kstrtos8(value, 10, &rssi);
2290 if (ret < 0)
2291 {
2292 /* If the input value is greater than max value of datatype, then also
2293 kstrtou8 fails */
2294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2295 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002296 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002297 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2298 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2299 ret = -EINVAL;
2300 goto exit;
2301 }
2302
Srinivas Girigowdade697412013-02-14 16:31:48 -08002303 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002304
Srinivas Girigowdade697412013-02-14 16:31:48 -08002305 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2306 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2307 {
2308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2309 "Neighbor lookup threshold value %d is out of range"
2310 " (Min: %d Max: %d)", lookUpThreshold,
2311 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2312 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2313 ret = -EINVAL;
2314 goto exit;
2315 }
2316
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302317 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2318 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2319 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2321 "%s: Received Command to Set Roam trigger"
2322 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2323
2324 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2325 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2326 if (eHAL_STATUS_SUCCESS != status)
2327 {
2328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2329 "%s: Failed to set roam trigger, try again", __func__);
2330 ret = -EPERM;
2331 goto exit;
2332 }
2333
2334 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302335 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002336 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2337 }
2338 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2339 {
2340 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2341 int rssi = (-1) * lookUpThreshold;
2342 char extra[32];
2343 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2345 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2346 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002347 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002348 if (copy_to_user(priv_data.buf, &extra, len + 1))
2349 {
2350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2351 "%s: failed to copy data to user buffer", __func__);
2352 ret = -EFAULT;
2353 goto exit;
2354 }
2355 }
2356 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2357 {
2358 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002359 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002360 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002361
Srinivas Girigowdade697412013-02-14 16:31:48 -08002362 /* input refresh period is in terms of seconds */
2363 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2364 value = value + 18;
2365 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002366 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002367 if (ret < 0)
2368 {
2369 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002370 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002372 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002373 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002374 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2375 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002376 ret = -EINVAL;
2377 goto exit;
2378 }
2379
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002380 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2381 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002382 {
2383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002384 "Roam scan period value %d is out of range"
2385 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002386 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2387 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388 ret = -EINVAL;
2389 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302390 }
2391 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2392 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2393 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002394 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002395
2396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2397 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002398 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002399
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002400 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2401 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002402 }
2403 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2404 {
2405 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2406 char extra[32];
2407 tANI_U8 len = 0;
2408
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302409 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2410 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2411 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002412 len = scnprintf(extra, sizeof(extra), "%s %d",
2413 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002414 /* Returned value is in units of seconds */
2415 if (copy_to_user(priv_data.buf, &extra, len + 1))
2416 {
2417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2418 "%s: failed to copy data to user buffer", __func__);
2419 ret = -EFAULT;
2420 goto exit;
2421 }
2422 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002423 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2424 {
2425 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002426 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002427 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002428
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002429 /* input refresh period is in terms of seconds */
2430 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2431 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002432
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002433 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002434 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002435 if (ret < 0)
2436 {
2437 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002441 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002442 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2443 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2444 ret = -EINVAL;
2445 goto exit;
2446 }
2447
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002448 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2449 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2450 {
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2452 "Neighbor scan results refresh period value %d is out of range"
2453 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2454 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2455 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2456 ret = -EINVAL;
2457 goto exit;
2458 }
2459 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2460
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2462 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002463 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002464
2465 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2466 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2467 }
2468 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2469 {
2470 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2471 char extra[32];
2472 tANI_U8 len = 0;
2473
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002474 len = scnprintf(extra, sizeof(extra), "%s %d",
2475 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 /* Returned value is in units of seconds */
2477 if (copy_to_user(priv_data.buf, &extra, len + 1))
2478 {
2479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2480 "%s: failed to copy data to user buffer", __func__);
2481 ret = -EFAULT;
2482 goto exit;
2483 }
2484 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002485#ifdef FEATURE_WLAN_LFR
2486 /* SETROAMMODE */
2487 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2488 {
2489 tANI_U8 *value = command;
2490 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2491
2492 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2493 value = value + SIZE_OF_SETROAMMODE + 1;
2494
2495 /* Convert the value from ascii to integer */
2496 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2497 if (ret < 0)
2498 {
2499 /* If the input value is greater than max value of datatype, then also
2500 kstrtou8 fails */
2501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2502 "%s: kstrtou8 failed range [%d - %d]", __func__,
2503 CFG_LFR_FEATURE_ENABLED_MIN,
2504 CFG_LFR_FEATURE_ENABLED_MAX);
2505 ret = -EINVAL;
2506 goto exit;
2507 }
2508 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2509 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2510 {
2511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2512 "Roam Mode value %d is out of range"
2513 " (Min: %d Max: %d)", roamMode,
2514 CFG_LFR_FEATURE_ENABLED_MIN,
2515 CFG_LFR_FEATURE_ENABLED_MAX);
2516 ret = -EINVAL;
2517 goto exit;
2518 }
2519
2520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2521 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2522 /*
2523 * Note that
2524 * SETROAMMODE 0 is to enable LFR while
2525 * SETROAMMODE 1 is to disable LFR, but
2526 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2527 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2528 */
2529 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2530 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2531 else
2532 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2533
2534 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2535 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2536 }
2537 /* GETROAMMODE */
2538 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2539 {
2540 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2541 char extra[32];
2542 tANI_U8 len = 0;
2543
2544 /*
2545 * roamMode value shall be inverted because the sementics is different.
2546 */
2547 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2548 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2549 else
2550 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2551
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002552 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002553 if (copy_to_user(priv_data.buf, &extra, len + 1))
2554 {
2555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2556 "%s: failed to copy data to user buffer", __func__);
2557 ret = -EFAULT;
2558 goto exit;
2559 }
2560 }
2561#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002562#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002563#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002564 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2565 {
2566 tANI_U8 *value = command;
2567 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2568
2569 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2570 value = value + 13;
2571 /* Convert the value from ascii to integer */
2572 ret = kstrtou8(value, 10, &roamRssiDiff);
2573 if (ret < 0)
2574 {
2575 /* If the input value is greater than max value of datatype, then also
2576 kstrtou8 fails */
2577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2578 "%s: kstrtou8 failed range [%d - %d]", __func__,
2579 CFG_ROAM_RSSI_DIFF_MIN,
2580 CFG_ROAM_RSSI_DIFF_MAX);
2581 ret = -EINVAL;
2582 goto exit;
2583 }
2584
2585 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2586 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2587 {
2588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2589 "Roam rssi diff value %d is out of range"
2590 " (Min: %d Max: %d)", roamRssiDiff,
2591 CFG_ROAM_RSSI_DIFF_MIN,
2592 CFG_ROAM_RSSI_DIFF_MAX);
2593 ret = -EINVAL;
2594 goto exit;
2595 }
2596
2597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2598 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2599
2600 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2601 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2602 }
2603 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2604 {
2605 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2606 char extra[32];
2607 tANI_U8 len = 0;
2608
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2610 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2611 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002612 len = scnprintf(extra, sizeof(extra), "%s %d",
2613 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002614 if (copy_to_user(priv_data.buf, &extra, len + 1))
2615 {
2616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2617 "%s: failed to copy data to user buffer", __func__);
2618 ret = -EFAULT;
2619 goto exit;
2620 }
2621 }
2622#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002623#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002624 else if (strncmp(command, "GETBAND", 7) == 0)
2625 {
2626 int band = -1;
2627 char extra[32];
2628 tANI_U8 len = 0;
2629 hdd_getBand_helper(pHddCtx, &band);
2630
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2632 TRACE_CODE_HDD_GETBAND_IOCTL,
2633 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002634 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002635 if (copy_to_user(priv_data.buf, &extra, len + 1))
2636 {
2637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2638 "%s: failed to copy data to user buffer", __func__);
2639 ret = -EFAULT;
2640 goto exit;
2641 }
2642 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002643 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2644 {
2645 tANI_U8 *value = command;
2646 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2647 tANI_U8 numChannels = 0;
2648 eHalStatus status = eHAL_STATUS_SUCCESS;
2649
2650 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2651 if (eHAL_STATUS_SUCCESS != status)
2652 {
2653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2654 "%s: Failed to parse channel list information", __func__);
2655 ret = -EINVAL;
2656 goto exit;
2657 }
2658
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2660 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2661 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002662 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2663 {
2664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2665 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2666 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2667 ret = -EINVAL;
2668 goto exit;
2669 }
2670 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2671 numChannels);
2672 if (eHAL_STATUS_SUCCESS != status)
2673 {
2674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2675 "%s: Failed to update channel list information", __func__);
2676 ret = -EINVAL;
2677 goto exit;
2678 }
2679 }
2680 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2681 {
2682 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2683 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002684 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002685 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002686 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002687
2688 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2689 ChannelList, &numChannels ))
2690 {
2691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2692 "%s: failed to get roam scan channel list", __func__);
2693 ret = -EFAULT;
2694 goto exit;
2695 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2697 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2698 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002699 /* output channel list is of the format
2700 [Number of roam scan channels][Channel1][Channel2]... */
2701 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002702 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 for (j = 0; (j < numChannels); j++)
2704 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002705 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2706 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002707 }
2708
2709 if (copy_to_user(priv_data.buf, &extra, len + 1))
2710 {
2711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2712 "%s: failed to copy data to user buffer", __func__);
2713 ret = -EFAULT;
2714 goto exit;
2715 }
2716 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002717 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2718 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002719 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002720 char extra[32];
2721 tANI_U8 len = 0;
2722
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002723 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002724 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002725 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002726 hdd_is_okc_mode_enabled(pHddCtx) &&
2727 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2728 {
2729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002730 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002731 " hence this operation is not permitted!", __func__);
2732 ret = -EPERM;
2733 goto exit;
2734 }
2735
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002736 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002737 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002738 if (copy_to_user(priv_data.buf, &extra, len + 1))
2739 {
2740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2741 "%s: failed to copy data to user buffer", __func__);
2742 ret = -EFAULT;
2743 goto exit;
2744 }
2745 }
2746 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2747 {
2748 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2749 char extra[32];
2750 tANI_U8 len = 0;
2751
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002752 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002753 then this operation is not permitted (return FAILURE) */
2754 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002755 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002756 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2757 {
2758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002759 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002760 " hence this operation is not permitted!", __func__);
2761 ret = -EPERM;
2762 goto exit;
2763 }
2764
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002765 len = scnprintf(extra, sizeof(extra), "%s %d",
2766 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002767 if (copy_to_user(priv_data.buf, &extra, len + 1))
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: failed to copy data to user buffer", __func__);
2771 ret = -EFAULT;
2772 goto exit;
2773 }
2774 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002775 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002776 {
2777 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2778 char extra[32];
2779 tANI_U8 len = 0;
2780
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002781 len = scnprintf(extra, sizeof(extra), "%s %d",
2782 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002783 if (copy_to_user(priv_data.buf, &extra, len + 1))
2784 {
2785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2786 "%s: failed to copy data to user buffer", __func__);
2787 ret = -EFAULT;
2788 goto exit;
2789 }
2790 }
2791 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2792 {
2793 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2794 char extra[32];
2795 tANI_U8 len = 0;
2796
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002797 len = scnprintf(extra, sizeof(extra), "%s %d",
2798 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002799 if (copy_to_user(priv_data.buf, &extra, len + 1))
2800 {
2801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2802 "%s: failed to copy data to user buffer", __func__);
2803 ret = -EFAULT;
2804 goto exit;
2805 }
2806 }
2807 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2808 {
2809 tANI_U8 *value = command;
2810 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2811
2812 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2813 value = value + 26;
2814 /* Convert the value from ascii to integer */
2815 ret = kstrtou8(value, 10, &minTime);
2816 if (ret < 0)
2817 {
2818 /* If the input value is greater than max value of datatype, then also
2819 kstrtou8 fails */
2820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2821 "%s: kstrtou8 failed range [%d - %d]", __func__,
2822 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2823 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2824 ret = -EINVAL;
2825 goto exit;
2826 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002827 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2828 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2829 {
2830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2831 "scan min channel time value %d is out of range"
2832 " (Min: %d Max: %d)", minTime,
2833 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2834 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2835 ret = -EINVAL;
2836 goto exit;
2837 }
2838
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302839 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2840 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2841 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2843 "%s: Received Command to change channel min time = %d", __func__, minTime);
2844
2845 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2846 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2847 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002848 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2849 {
2850 tANI_U8 *value = command;
2851 tANI_U8 channel = 0;
2852 tANI_U8 dwellTime = 0;
2853 tANI_U8 bufLen = 0;
2854 tANI_U8 *buf = NULL;
2855 tSirMacAddr targetApBssid;
2856 eHalStatus status = eHAL_STATUS_SUCCESS;
2857 struct ieee80211_channel chan;
2858 tANI_U8 finalLen = 0;
2859 tANI_U8 *finalBuf = NULL;
2860 tANI_U8 temp = 0;
2861 u64 cookie;
2862 hdd_station_ctx_t *pHddStaCtx = NULL;
2863 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2864
2865 /* if not associated, no need to send action frame */
2866 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2867 {
2868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2869 ret = -EINVAL;
2870 goto exit;
2871 }
2872
2873 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2874 &dwellTime, &buf, &bufLen);
2875 if (eHAL_STATUS_SUCCESS != status)
2876 {
2877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2878 "%s: Failed to parse send action frame data", __func__);
2879 ret = -EINVAL;
2880 goto exit;
2881 }
2882
2883 /* if the target bssid is different from currently associated AP,
2884 then no need to send action frame */
2885 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2886 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2887 {
2888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2889 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002890 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002891 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002892 goto exit;
2893 }
2894
2895 /* if the channel number is different from operating channel then
2896 no need to send action frame */
2897 if (channel != pHddStaCtx->conn_info.operationChannel)
2898 {
2899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2900 "%s: channel(%d) is different from operating channel(%d)",
2901 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2902 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002903 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002904 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002905 goto exit;
2906 }
2907 chan.center_freq = sme_ChnToFreq(channel);
2908
2909 finalLen = bufLen + 24;
2910 finalBuf = vos_mem_malloc(finalLen);
2911 if (NULL == finalBuf)
2912 {
2913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2914 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002915 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002916 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002917 goto exit;
2918 }
2919 vos_mem_zero(finalBuf, finalLen);
2920
2921 /* Fill subtype */
2922 temp = SIR_MAC_MGMT_ACTION << 4;
2923 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2924
2925 /* Fill type */
2926 temp = SIR_MAC_MGMT_FRAME;
2927 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2928
2929 /* Fill destination address (bssid of the AP) */
2930 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2931
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002932 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002933 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2934
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002935 /* Fill BSSID (AP mac address) */
2936 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002937
2938 /* Fill received buffer from 24th address */
2939 vos_mem_copy(finalBuf + 24, buf, bufLen);
2940
Jeff Johnson11c33152013-04-16 17:52:40 -07002941 /* done with the parsed buffer */
2942 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002943 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002944
DARAM SUDHA39eede62014-02-12 11:16:40 +05302945 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2947 &(pAdapter->wdev),
2948#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002949 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002950#endif
2951 &chan, 0,
2952#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2953 NL80211_CHAN_HT20, 1,
2954#endif
2955 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002956 1, &cookie );
2957 vos_mem_free(finalBuf);
2958 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002959 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2960 {
2961 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2962 char extra[32];
2963 tANI_U8 len = 0;
2964
2965 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002966 len = scnprintf(extra, sizeof(extra), "%s %d",
2967 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2969 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2970 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002971 if (copy_to_user(priv_data.buf, &extra, len + 1))
2972 {
2973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2974 "%s: failed to copy data to user buffer", __func__);
2975 ret = -EFAULT;
2976 goto exit;
2977 }
2978 }
2979 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2980 {
2981 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002982 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002983
2984 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2985 value = value + 19;
2986 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002987 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002988 if (ret < 0)
2989 {
2990 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002991 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002993 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002994 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2995 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2996 ret = -EINVAL;
2997 goto exit;
2998 }
2999
3000 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3001 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3002 {
3003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3004 "lfr mode value %d is out of range"
3005 " (Min: %d Max: %d)", maxTime,
3006 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3007 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3008 ret = -EINVAL;
3009 goto exit;
3010 }
3011
3012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3013 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3014
3015 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3016 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3017 }
3018 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3019 {
3020 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3021 char extra[32];
3022 tANI_U8 len = 0;
3023
3024 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003025 len = scnprintf(extra, sizeof(extra), "%s %d",
3026 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003027 if (copy_to_user(priv_data.buf, &extra, len + 1))
3028 {
3029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3030 "%s: failed to copy data to user buffer", __func__);
3031 ret = -EFAULT;
3032 goto exit;
3033 }
3034 }
3035 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3036 {
3037 tANI_U8 *value = command;
3038 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3039
3040 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3041 value = value + 16;
3042 /* Convert the value from ascii to integer */
3043 ret = kstrtou16(value, 10, &val);
3044 if (ret < 0)
3045 {
3046 /* If the input value is greater than max value of datatype, then also
3047 kstrtou16 fails */
3048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "%s: kstrtou16 failed range [%d - %d]", __func__,
3050 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3051 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3052 ret = -EINVAL;
3053 goto exit;
3054 }
3055
3056 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3057 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3058 {
3059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3060 "scan home time value %d is out of range"
3061 " (Min: %d Max: %d)", val,
3062 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3063 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067
3068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3069 "%s: Received Command to change scan home time = %d", __func__, val);
3070
3071 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3072 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3073 }
3074 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3075 {
3076 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3077 char extra[32];
3078 tANI_U8 len = 0;
3079
3080 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003081 len = scnprintf(extra, sizeof(extra), "%s %d",
3082 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003083 if (copy_to_user(priv_data.buf, &extra, len + 1))
3084 {
3085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3086 "%s: failed to copy data to user buffer", __func__);
3087 ret = -EFAULT;
3088 goto exit;
3089 }
3090 }
3091 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3092 {
3093 tANI_U8 *value = command;
3094 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3095
3096 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3097 value = value + 17;
3098 /* Convert the value from ascii to integer */
3099 ret = kstrtou8(value, 10, &val);
3100 if (ret < 0)
3101 {
3102 /* If the input value is greater than max value of datatype, then also
3103 kstrtou8 fails */
3104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3105 "%s: kstrtou8 failed range [%d - %d]", __func__,
3106 CFG_ROAM_INTRA_BAND_MIN,
3107 CFG_ROAM_INTRA_BAND_MAX);
3108 ret = -EINVAL;
3109 goto exit;
3110 }
3111
3112 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3113 (val > CFG_ROAM_INTRA_BAND_MAX))
3114 {
3115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3116 "intra band mode value %d is out of range"
3117 " (Min: %d Max: %d)", val,
3118 CFG_ROAM_INTRA_BAND_MIN,
3119 CFG_ROAM_INTRA_BAND_MAX);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3124 "%s: Received Command to change intra band = %d", __func__, val);
3125
3126 pHddCtx->cfg_ini->nRoamIntraBand = val;
3127 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3128 }
3129 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3130 {
3131 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3132 char extra[32];
3133 tANI_U8 len = 0;
3134
3135 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003136 len = scnprintf(extra, sizeof(extra), "%s %d",
3137 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003138 if (copy_to_user(priv_data.buf, &extra, len + 1))
3139 {
3140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3141 "%s: failed to copy data to user buffer", __func__);
3142 ret = -EFAULT;
3143 goto exit;
3144 }
3145 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003146 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3147 {
3148 tANI_U8 *value = command;
3149 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3150
3151 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3152 value = value + 15;
3153 /* Convert the value from ascii to integer */
3154 ret = kstrtou8(value, 10, &nProbes);
3155 if (ret < 0)
3156 {
3157 /* If the input value is greater than max value of datatype, then also
3158 kstrtou8 fails */
3159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3160 "%s: kstrtou8 failed range [%d - %d]", __func__,
3161 CFG_ROAM_SCAN_N_PROBES_MIN,
3162 CFG_ROAM_SCAN_N_PROBES_MAX);
3163 ret = -EINVAL;
3164 goto exit;
3165 }
3166
3167 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3168 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3169 {
3170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3171 "NProbes value %d is out of range"
3172 " (Min: %d Max: %d)", nProbes,
3173 CFG_ROAM_SCAN_N_PROBES_MIN,
3174 CFG_ROAM_SCAN_N_PROBES_MAX);
3175 ret = -EINVAL;
3176 goto exit;
3177 }
3178
3179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3180 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3181
3182 pHddCtx->cfg_ini->nProbes = nProbes;
3183 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3184 }
3185 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3186 {
3187 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3188 char extra[32];
3189 tANI_U8 len = 0;
3190
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003191 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003192 if (copy_to_user(priv_data.buf, &extra, len + 1))
3193 {
3194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3195 "%s: failed to copy data to user buffer", __func__);
3196 ret = -EFAULT;
3197 goto exit;
3198 }
3199 }
3200 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3201 {
3202 tANI_U8 *value = command;
3203 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3204
3205 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3206 /* input value is in units of msec */
3207 value = value + 20;
3208 /* Convert the value from ascii to integer */
3209 ret = kstrtou16(value, 10, &homeAwayTime);
3210 if (ret < 0)
3211 {
3212 /* If the input value is greater than max value of datatype, then also
3213 kstrtou8 fails */
3214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3215 "%s: kstrtou8 failed range [%d - %d]", __func__,
3216 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3217 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3218 ret = -EINVAL;
3219 goto exit;
3220 }
3221
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003222 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3223 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3224 {
3225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3226 "homeAwayTime value %d is out of range"
3227 " (Min: %d Max: %d)", homeAwayTime,
3228 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3229 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3230 ret = -EINVAL;
3231 goto exit;
3232 }
3233
3234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3235 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003236 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3237 {
3238 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3239 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3240 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003241 }
3242 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3243 {
3244 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3245 char extra[32];
3246 tANI_U8 len = 0;
3247
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003248 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003249 if (copy_to_user(priv_data.buf, &extra, len + 1))
3250 {
3251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3252 "%s: failed to copy data to user buffer", __func__);
3253 ret = -EFAULT;
3254 goto exit;
3255 }
3256 }
3257 else if (strncmp(command, "REASSOC", 7) == 0)
3258 {
3259 tANI_U8 *value = command;
3260 tANI_U8 channel = 0;
3261 tSirMacAddr targetApBssid;
3262 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003263#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3264 tCsrHandoffRequest handoffInfo;
3265#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003266 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003267 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3268
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003269 /* if not associated, no need to proceed with reassoc */
3270 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3271 {
3272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3273 ret = -EINVAL;
3274 goto exit;
3275 }
3276
3277 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3278 if (eHAL_STATUS_SUCCESS != status)
3279 {
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "%s: Failed to parse reassoc command data", __func__);
3282 ret = -EINVAL;
3283 goto exit;
3284 }
3285
3286 /* if the target bssid is same as currently associated AP,
3287 then no need to proceed with reassoc */
3288 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3289 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3290 {
3291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3292 ret = -EINVAL;
3293 goto exit;
3294 }
3295
3296 /* Check channel number is a valid channel number */
3297 if(VOS_STATUS_SUCCESS !=
3298 wlan_hdd_validate_operation_channel(pAdapter, channel))
3299 {
3300 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003301 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003302 return -EINVAL;
3303 }
3304
3305 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003306#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3307 handoffInfo.channel = channel;
3308 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3309 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3310#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003311 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003312 else if (strncmp(command, "SETWESMODE", 10) == 0)
3313 {
3314 tANI_U8 *value = command;
3315 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3316
3317 /* Move pointer to ahead of SETWESMODE<delimiter> */
3318 value = value + 11;
3319 /* Convert the value from ascii to integer */
3320 ret = kstrtou8(value, 10, &wesMode);
3321 if (ret < 0)
3322 {
3323 /* If the input value is greater than max value of datatype, then also
3324 kstrtou8 fails */
3325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3326 "%s: kstrtou8 failed range [%d - %d]", __func__,
3327 CFG_ENABLE_WES_MODE_NAME_MIN,
3328 CFG_ENABLE_WES_MODE_NAME_MAX);
3329 ret = -EINVAL;
3330 goto exit;
3331 }
3332
3333 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3334 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3337 "WES Mode value %d is out of range"
3338 " (Min: %d Max: %d)", wesMode,
3339 CFG_ENABLE_WES_MODE_NAME_MIN,
3340 CFG_ENABLE_WES_MODE_NAME_MAX);
3341 ret = -EINVAL;
3342 goto exit;
3343 }
3344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3345 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3346
3347 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3348 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3349 }
3350 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3351 {
3352 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3353 char extra[32];
3354 tANI_U8 len = 0;
3355
Arif Hussain826d9412013-11-12 16:44:54 -08003356 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003357 if (copy_to_user(priv_data.buf, &extra, len + 1))
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: failed to copy data to user buffer", __func__);
3361 ret = -EFAULT;
3362 goto exit;
3363 }
3364 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003365#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003366#ifdef FEATURE_WLAN_LFR
3367 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3368 {
3369 tANI_U8 *value = command;
3370 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3371
3372 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3373 value = value + 12;
3374 /* Convert the value from ascii to integer */
3375 ret = kstrtou8(value, 10, &lfrMode);
3376 if (ret < 0)
3377 {
3378 /* If the input value is greater than max value of datatype, then also
3379 kstrtou8 fails */
3380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3381 "%s: kstrtou8 failed range [%d - %d]", __func__,
3382 CFG_LFR_FEATURE_ENABLED_MIN,
3383 CFG_LFR_FEATURE_ENABLED_MAX);
3384 ret = -EINVAL;
3385 goto exit;
3386 }
3387
3388 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3389 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3390 {
3391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3392 "lfr mode value %d is out of range"
3393 " (Min: %d Max: %d)", lfrMode,
3394 CFG_LFR_FEATURE_ENABLED_MIN,
3395 CFG_LFR_FEATURE_ENABLED_MAX);
3396 ret = -EINVAL;
3397 goto exit;
3398 }
3399
3400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3401 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3402
3403 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3404 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3405 }
3406#endif
3407#ifdef WLAN_FEATURE_VOWIFI_11R
3408 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3409 {
3410 tANI_U8 *value = command;
3411 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3412
3413 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3414 value = value + 18;
3415 /* Convert the value from ascii to integer */
3416 ret = kstrtou8(value, 10, &ft);
3417 if (ret < 0)
3418 {
3419 /* If the input value is greater than max value of datatype, then also
3420 kstrtou8 fails */
3421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3422 "%s: kstrtou8 failed range [%d - %d]", __func__,
3423 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3424 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3425 ret = -EINVAL;
3426 goto exit;
3427 }
3428
3429 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3430 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3431 {
3432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3433 "ft mode value %d is out of range"
3434 " (Min: %d Max: %d)", ft,
3435 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3436 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3437 ret = -EINVAL;
3438 goto exit;
3439 }
3440
3441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3442 "%s: Received Command to change ft mode = %d", __func__, ft);
3443
3444 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3445 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3446 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303447
3448 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3449 {
3450 tANI_U8 *value = command;
3451 tSirMacAddr targetApBssid;
3452 tANI_U8 trigger = 0;
3453 eHalStatus status = eHAL_STATUS_SUCCESS;
3454 hdd_station_ctx_t *pHddStaCtx = NULL;
3455 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3456
3457 /* if not associated, no need to proceed with reassoc */
3458 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3459 {
3460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3461 ret = -EINVAL;
3462 goto exit;
3463 }
3464
3465 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3466 if (eHAL_STATUS_SUCCESS != status)
3467 {
3468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3469 "%s: Failed to parse reassoc command data", __func__);
3470 ret = -EINVAL;
3471 goto exit;
3472 }
3473
3474 /* if the target bssid is same as currently associated AP,
3475 then no need to proceed with reassoc */
3476 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3477 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3478 {
3479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3480 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3481 __func__);
3482 ret = -EINVAL;
3483 goto exit;
3484 }
3485
3486 /* Proceed with scan/roam */
3487 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3488 &targetApBssid[0],
3489 (tSmeFastRoamTrigger)(trigger));
3490 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003491#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003492#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003493 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3494 {
3495 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003496 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003497
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003498 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003499 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003500 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003501 hdd_is_okc_mode_enabled(pHddCtx) &&
3502 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3503 {
3504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003505 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003506 " hence this operation is not permitted!", __func__);
3507 ret = -EPERM;
3508 goto exit;
3509 }
3510
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003511 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3512 value = value + 11;
3513 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003514 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003515 if (ret < 0)
3516 {
3517 /* If the input value is greater than max value of datatype, then also
3518 kstrtou8 fails */
3519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3520 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003521 CFG_ESE_FEATURE_ENABLED_MIN,
3522 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003523 ret = -EINVAL;
3524 goto exit;
3525 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003526 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3527 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003528 {
3529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003530 "Ese mode value %d is out of range"
3531 " (Min: %d Max: %d)", eseMode,
3532 CFG_ESE_FEATURE_ENABLED_MIN,
3533 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003534 ret = -EINVAL;
3535 goto exit;
3536 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003538 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003539
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003540 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3541 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003542 }
3543#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003544 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3545 {
3546 tANI_U8 *value = command;
3547 tANI_BOOLEAN roamScanControl = 0;
3548
3549 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3550 value = value + 19;
3551 /* Convert the value from ascii to integer */
3552 ret = kstrtou8(value, 10, &roamScanControl);
3553 if (ret < 0)
3554 {
3555 /* If the input value is greater than max value of datatype, then also
3556 kstrtou8 fails */
3557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3558 "%s: kstrtou8 failed ", __func__);
3559 ret = -EINVAL;
3560 goto exit;
3561 }
3562
3563 if (0 != roamScanControl)
3564 {
3565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3566 "roam scan control invalid value = %d",
3567 roamScanControl);
3568 ret = -EINVAL;
3569 goto exit;
3570 }
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3572 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3573
3574 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3575 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003576#ifdef FEATURE_WLAN_OKC
3577 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3578 {
3579 tANI_U8 *value = command;
3580 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3581
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003582 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003583 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003584 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003585 hdd_is_okc_mode_enabled(pHddCtx) &&
3586 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3587 {
3588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003589 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003590 " hence this operation is not permitted!", __func__);
3591 ret = -EPERM;
3592 goto exit;
3593 }
3594
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003595 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3596 value = value + 11;
3597 /* Convert the value from ascii to integer */
3598 ret = kstrtou8(value, 10, &okcMode);
3599 if (ret < 0)
3600 {
3601 /* If the input value is greater than max value of datatype, then also
3602 kstrtou8 fails */
3603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3604 "%s: kstrtou8 failed range [%d - %d]", __func__,
3605 CFG_OKC_FEATURE_ENABLED_MIN,
3606 CFG_OKC_FEATURE_ENABLED_MAX);
3607 ret = -EINVAL;
3608 goto exit;
3609 }
3610
3611 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3612 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3613 {
3614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3615 "Okc mode value %d is out of range"
3616 " (Min: %d Max: %d)", okcMode,
3617 CFG_OKC_FEATURE_ENABLED_MIN,
3618 CFG_OKC_FEATURE_ENABLED_MAX);
3619 ret = -EINVAL;
3620 goto exit;
3621 }
3622
3623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3624 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3625
3626 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3627 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003628#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003629 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3630 {
3631 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3632 char extra[32];
3633 tANI_U8 len = 0;
3634
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003635 len = scnprintf(extra, sizeof(extra), "%s %d",
3636 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003637 if (copy_to_user(priv_data.buf, &extra, len + 1))
3638 {
3639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3640 "%s: failed to copy data to user buffer", __func__);
3641 ret = -EFAULT;
3642 goto exit;
3643 }
3644 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303645#ifdef WLAN_FEATURE_PACKET_FILTERING
3646 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3647 {
3648 tANI_U8 filterType = 0;
3649 tANI_U8 *value = command;
3650
3651 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3652 value = value + 22;
3653
3654 /* Convert the value from ascii to integer */
3655 ret = kstrtou8(value, 10, &filterType);
3656 if (ret < 0)
3657 {
3658 /* If the input value is greater than max value of datatype,
3659 * then also kstrtou8 fails
3660 */
3661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3662 "%s: kstrtou8 failed range ", __func__);
3663 ret = -EINVAL;
3664 goto exit;
3665 }
3666
3667 if (filterType != 0 && filterType != 1)
3668 {
3669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3670 "%s: Accepted Values are 0 and 1 ", __func__);
3671 ret = -EINVAL;
3672 goto exit;
3673 }
3674 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3675 pAdapter->sessionId);
3676 }
3677#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303678 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3679 {
Kiet Lamad161252014-07-22 11:23:32 -07003680 char *dhcpPhase;
3681 dhcpPhase = command + 11;
3682 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303683 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003685 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303686
3687 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003688
3689 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3690 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303691 }
Kiet Lamad161252014-07-22 11:23:32 -07003692 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303693 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003695 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303696
3697 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003698
3699 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3700 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303701 }
3702 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003703 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3704 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3706 FL("making default scan to ACTIVE"));
3707 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003708 }
3709 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3710 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3712 FL("making default scan to PASSIVE"));
3713 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003714 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303715 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3716 {
3717 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3718 char extra[32];
3719 tANI_U8 len = 0;
3720
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303721 memset(extra, 0, sizeof(extra));
3722 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3723 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303724 {
3725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3726 "%s: failed to copy data to user buffer", __func__);
3727 ret = -EFAULT;
3728 goto exit;
3729 }
3730 ret = len;
3731 }
3732 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3733 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303734 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303735 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003736 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3737 {
3738 tANI_U8 filterType = 0;
3739 tANI_U8 *value;
3740 value = command + 9;
3741
3742 /* Convert the value from ascii to integer */
3743 ret = kstrtou8(value, 10, &filterType);
3744 if (ret < 0)
3745 {
3746 /* If the input value is greater than max value of datatype,
3747 * then also kstrtou8 fails
3748 */
3749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3750 "%s: kstrtou8 failed range ", __func__);
3751 ret = -EINVAL;
3752 goto exit;
3753 }
3754 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3755 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3756 {
3757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3758 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3759 " 2-Sink ", __func__);
3760 ret = -EINVAL;
3761 goto exit;
3762 }
3763 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3764 pHddCtx->drvr_miracast = filterType;
3765 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3766 }
Leo Chang614d2072013-08-22 14:59:44 -07003767 else if (strncmp(command, "SETMCRATE", 9) == 0)
3768 {
Leo Chang614d2072013-08-22 14:59:44 -07003769 tANI_U8 *value = command;
3770 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003771 tSirRateUpdateInd *rateUpdate;
3772 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003773
3774 /* Only valid for SAP mode */
3775 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3776 {
3777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3778 "%s: SAP mode is not running", __func__);
3779 ret = -EFAULT;
3780 goto exit;
3781 }
3782
3783 /* Move pointer to ahead of SETMCRATE<delimiter> */
3784 /* input value is in units of hundred kbps */
3785 value = value + 10;
3786 /* Convert the value from ascii to integer, decimal base */
3787 ret = kstrtouint(value, 10, &targetRate);
3788
Leo Chang1f98cbd2013-10-17 15:03:52 -07003789 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3790 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003791 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003792 hddLog(VOS_TRACE_LEVEL_ERROR,
3793 "%s: SETMCRATE indication alloc fail", __func__);
3794 ret = -EFAULT;
3795 goto exit;
3796 }
3797 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3798
3799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3800 "MC Target rate %d", targetRate);
3801 /* Ignore unicast */
3802 rateUpdate->ucastDataRate = -1;
3803 rateUpdate->mcastDataRate24GHz = targetRate;
3804 rateUpdate->mcastDataRate5GHz = targetRate;
3805 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3806 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3807 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3808 if (eHAL_STATUS_SUCCESS != status)
3809 {
3810 hddLog(VOS_TRACE_LEVEL_ERROR,
3811 "%s: SET_MC_RATE failed", __func__);
3812 vos_mem_free(rateUpdate);
3813 ret = -EFAULT;
3814 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003815 }
3816 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303817#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003818 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303819 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003820 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303821 }
3822#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003823#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003824 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3825 {
3826 tANI_U8 *value = command;
3827 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3828 tANI_U8 numChannels = 0;
3829 eHalStatus status = eHAL_STATUS_SUCCESS;
3830
3831 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3832 if (eHAL_STATUS_SUCCESS != status)
3833 {
3834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3835 "%s: Failed to parse channel list information", __func__);
3836 ret = -EINVAL;
3837 goto exit;
3838 }
3839
3840 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3841 {
3842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3843 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3844 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3845 ret = -EINVAL;
3846 goto exit;
3847 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003848 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003849 ChannelList,
3850 numChannels);
3851 if (eHAL_STATUS_SUCCESS != status)
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "%s: Failed to update channel list information", __func__);
3855 ret = -EINVAL;
3856 goto exit;
3857 }
3858 }
3859 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3860 {
3861 tANI_U8 *value = command;
3862 char extra[128] = {0};
3863 int len = 0;
3864 tANI_U8 tid = 0;
3865 hdd_station_ctx_t *pHddStaCtx = NULL;
3866 tAniTrafStrmMetrics tsmMetrics;
3867 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3868
3869 /* if not associated, return error */
3870 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3871 {
3872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3873 ret = -EINVAL;
3874 goto exit;
3875 }
3876
3877 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3878 value = value + 12;
3879 /* Convert the value from ascii to integer */
3880 ret = kstrtou8(value, 10, &tid);
3881 if (ret < 0)
3882 {
3883 /* If the input value is greater than max value of datatype, then also
3884 kstrtou8 fails */
3885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3886 "%s: kstrtou8 failed range [%d - %d]", __func__,
3887 TID_MIN_VALUE,
3888 TID_MAX_VALUE);
3889 ret = -EINVAL;
3890 goto exit;
3891 }
3892
3893 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3894 {
3895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3896 "tid value %d is out of range"
3897 " (Min: %d Max: %d)", tid,
3898 TID_MIN_VALUE,
3899 TID_MAX_VALUE);
3900 ret = -EINVAL;
3901 goto exit;
3902 }
3903
3904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3905 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3906
3907 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3908 {
3909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3910 "%s: failed to get tsm stats", __func__);
3911 ret = -EFAULT;
3912 goto exit;
3913 }
3914
3915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3916 "UplinkPktQueueDly(%d)\n"
3917 "UplinkPktQueueDlyHist[0](%d)\n"
3918 "UplinkPktQueueDlyHist[1](%d)\n"
3919 "UplinkPktQueueDlyHist[2](%d)\n"
3920 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303921 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003922 "UplinkPktLoss(%d)\n"
3923 "UplinkPktCount(%d)\n"
3924 "RoamingCount(%d)\n"
3925 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3926 tsmMetrics.UplinkPktQueueDlyHist[0],
3927 tsmMetrics.UplinkPktQueueDlyHist[1],
3928 tsmMetrics.UplinkPktQueueDlyHist[2],
3929 tsmMetrics.UplinkPktQueueDlyHist[3],
3930 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3931 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3932
3933 /* Output TSM stats is of the format
3934 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3935 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003936 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003937 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3938 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3939 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3940 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3941 tsmMetrics.RoamingDly);
3942
3943 if (copy_to_user(priv_data.buf, &extra, len + 1))
3944 {
3945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3946 "%s: failed to copy data to user buffer", __func__);
3947 ret = -EFAULT;
3948 goto exit;
3949 }
3950 }
3951 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3952 {
3953 tANI_U8 *value = command;
3954 tANI_U8 *cckmIe = NULL;
3955 tANI_U8 cckmIeLen = 0;
3956 eHalStatus status = eHAL_STATUS_SUCCESS;
3957
3958 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3959 if (eHAL_STATUS_SUCCESS != status)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: Failed to parse cckm ie data", __func__);
3963 ret = -EINVAL;
3964 goto exit;
3965 }
3966
3967 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3968 {
3969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3970 "%s: CCKM Ie input length is more than max[%d]", __func__,
3971 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003972 vos_mem_free(cckmIe);
3973 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003974 ret = -EINVAL;
3975 goto exit;
3976 }
3977 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003978 vos_mem_free(cckmIe);
3979 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003980 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003981 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3982 {
3983 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003984 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003985 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003986
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003987 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003988 if (eHAL_STATUS_SUCCESS != status)
3989 {
3990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003991 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003992 ret = -EINVAL;
3993 goto exit;
3994 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003995 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3996 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3997 hdd_indicateEseBcnReportNoResults (pAdapter,
3998 eseBcnReq.bcnReq[0].measurementToken,
3999 0x02, //BIT(1) set for measurement done
4000 0); // no BSS
4001 goto exit;
4002 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004003
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004004 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4005 if (eHAL_STATUS_SUCCESS != status)
4006 {
4007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4008 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4009 ret = -EINVAL;
4010 goto exit;
4011 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004012 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004013#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304014 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4015 {
4016 eHalStatus status;
4017 char buf[32], len;
4018 long waitRet;
4019 bcnMissRateContext_t getBcnMissRateCtx;
4020
4021 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4022
4023 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4024 {
4025 hddLog(VOS_TRACE_LEVEL_WARN,
4026 FL("GETBCNMISSRATE: STA is not in connected state"));
4027 ret = -1;
4028 goto exit;
4029 }
4030
4031 init_completion(&(getBcnMissRateCtx.completion));
4032 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4033
4034 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4035 pAdapter->sessionId,
4036 (void *)getBcnMissRateCB,
4037 (void *)(&getBcnMissRateCtx));
4038 if( eHAL_STATUS_SUCCESS != status)
4039 {
4040 hddLog(VOS_TRACE_LEVEL_INFO,
4041 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4042 ret = -EINVAL;
4043 goto exit;
4044 }
4045
4046 waitRet = wait_for_completion_interruptible_timeout
4047 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4048 if(waitRet <= 0)
4049 {
4050 hddLog(VOS_TRACE_LEVEL_ERROR,
4051 FL("failed to wait on bcnMissRateComp %d"), ret);
4052
4053 //Make magic number to zero so that callback is not called.
4054 spin_lock(&hdd_context_lock);
4055 getBcnMissRateCtx.magic = 0x0;
4056 spin_unlock(&hdd_context_lock);
4057 ret = -EINVAL;
4058 goto exit;
4059 }
4060
4061 hddLog(VOS_TRACE_LEVEL_INFO,
4062 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4063
4064 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4065 if (copy_to_user(priv_data.buf, &buf, len + 1))
4066 {
4067 hddLog(VOS_TRACE_LEVEL_ERROR,
4068 "%s: failed to copy data to user buffer", __func__);
4069 ret = -EFAULT;
4070 goto exit;
4071 }
4072 ret = len;
4073 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004074 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4076 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4077 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004078 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4079 __func__, command);
4080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 }
4082exit:
4083 if (command)
4084 {
4085 kfree(command);
4086 }
4087 return ret;
4088}
4089
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004090#ifdef CONFIG_COMPAT
4091static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4092{
4093 struct {
4094 compat_uptr_t buf;
4095 int used_len;
4096 int total_len;
4097 } compat_priv_data;
4098 hdd_priv_data_t priv_data;
4099 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004100
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004101 /*
4102 * Note that pAdapter and ifr have already been verified by caller,
4103 * and HDD context has also been validated
4104 */
4105 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4106 sizeof(compat_priv_data))) {
4107 ret = -EFAULT;
4108 goto exit;
4109 }
4110 priv_data.buf = compat_ptr(compat_priv_data.buf);
4111 priv_data.used_len = compat_priv_data.used_len;
4112 priv_data.total_len = compat_priv_data.total_len;
4113 ret = hdd_driver_command(pAdapter, &priv_data);
4114 exit:
4115 return ret;
4116}
4117#else /* CONFIG_COMPAT */
4118static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4119{
4120 /* will never be invoked */
4121 return 0;
4122}
4123#endif /* CONFIG_COMPAT */
4124
4125static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4126{
4127 hdd_priv_data_t priv_data;
4128 int ret = 0;
4129
4130 /*
4131 * Note that pAdapter and ifr have already been verified by caller,
4132 * and HDD context has also been validated
4133 */
4134 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4135 ret = -EFAULT;
4136 } else {
4137 ret = hdd_driver_command(pAdapter, &priv_data);
4138 }
4139 return ret;
4140}
4141
4142int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4143{
4144 hdd_adapter_t *pAdapter;
4145 hdd_context_t *pHddCtx;
4146 int ret;
4147
4148 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4149 if (NULL == pAdapter) {
4150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4151 "%s: HDD adapter context is Null", __func__);
4152 ret = -ENODEV;
4153 goto exit;
4154 }
4155 if (dev != pAdapter->dev) {
4156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4157 "%s: HDD adapter/dev inconsistency", __func__);
4158 ret = -ENODEV;
4159 goto exit;
4160 }
4161
4162 if ((!ifr) || (!ifr->ifr_data)) {
4163 ret = -EINVAL;
4164 goto exit;
4165 }
4166
4167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4168 ret = wlan_hdd_validate_context(pHddCtx);
4169 if (ret) {
4170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4171 "%s: invalid context", __func__);
4172 ret = -EBUSY;
4173 goto exit;
4174 }
4175
4176 switch (cmd) {
4177 case (SIOCDEVPRIVATE + 1):
4178 if (is_compat_task())
4179 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4180 else
4181 ret = hdd_driver_ioctl(pAdapter, ifr);
4182 break;
4183 default:
4184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4185 __func__, cmd);
4186 ret = -EINVAL;
4187 break;
4188 }
4189 exit:
4190 return ret;
4191}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004192
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004193#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004194/**---------------------------------------------------------------------------
4195
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004196 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004197
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004198 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004199 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4200 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4201 <space>Scan Mode N<space>Meas Duration N
4202 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4203 then take N.
4204 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4205 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4206 This function does not take care of removing duplicate channels from the list
4207
4208 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004209 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004210
4211 \return - 0 for success non-zero for failure
4212
4213 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004214static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4215 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004216{
4217 tANI_U8 *inPtr = pValue;
4218 int tempInt = 0;
4219 int j = 0, i = 0, v = 0;
4220 char buf[32];
4221
4222 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4223 /*no argument after the command*/
4224 if (NULL == inPtr)
4225 {
4226 return -EINVAL;
4227 }
4228 /*no space after the command*/
4229 else if (SPACE_ASCII_VALUE != *inPtr)
4230 {
4231 return -EINVAL;
4232 }
4233
4234 /*removing empty spaces*/
4235 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4236
4237 /*no argument followed by spaces*/
4238 if ('\0' == *inPtr) return -EINVAL;
4239
4240 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004241 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004242 if (1 != v) return -EINVAL;
4243
4244 v = kstrtos32(buf, 10, &tempInt);
4245 if ( v < 0) return -EINVAL;
4246
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004247 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004248
4249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004250 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004251
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004252 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004253 {
4254 for (i = 0; i < 4; i++)
4255 {
4256 /*inPtr pointing to the beginning of first space after number of ie fields*/
4257 inPtr = strpbrk( inPtr, " " );
4258 /*no ie data after the number of ie fields argument*/
4259 if (NULL == inPtr) return -EINVAL;
4260
4261 /*removing empty space*/
4262 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4263
4264 /*no ie data after the number of ie fields argument and spaces*/
4265 if ( '\0' == *inPtr ) return -EINVAL;
4266
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004267 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004268 if (1 != v) return -EINVAL;
4269
4270 v = kstrtos32(buf, 10, &tempInt);
4271 if (v < 0) return -EINVAL;
4272
4273 switch (i)
4274 {
4275 case 0: /* Measurement token */
4276 if (tempInt <= 0)
4277 {
4278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4279 "Invalid Measurement Token(%d)", tempInt);
4280 return -EINVAL;
4281 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004282 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004283 break;
4284
4285 case 1: /* Channel number */
4286 if ((tempInt <= 0) ||
4287 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4288 {
4289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4290 "Invalid Channel Number(%d)", tempInt);
4291 return -EINVAL;
4292 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004293 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004294 break;
4295
4296 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004297 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004298 {
4299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4300 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4301 return -EINVAL;
4302 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004303 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004304 break;
4305
4306 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004307 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4308 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004309 {
4310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4311 "Invalid Measurement Duration(%d)", tempInt);
4312 return -EINVAL;
4313 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004314 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004315 break;
4316 }
4317 }
4318 }
4319
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004320 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004321 {
4322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304323 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004324 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004325 pEseBcnReq->bcnReq[j].measurementToken,
4326 pEseBcnReq->bcnReq[j].channel,
4327 pEseBcnReq->bcnReq[j].scanMode,
4328 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004329 }
4330
4331 return VOS_STATUS_SUCCESS;
4332}
4333
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004334static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4335{
4336 struct statsContext *pStatsContext = NULL;
4337 hdd_adapter_t *pAdapter = NULL;
4338
4339 if (NULL == pContext)
4340 {
4341 hddLog(VOS_TRACE_LEVEL_ERROR,
4342 "%s: Bad param, pContext [%p]",
4343 __func__, pContext);
4344 return;
4345 }
4346
Jeff Johnson72a40512013-12-19 10:14:15 -08004347 /* there is a race condition that exists between this callback
4348 function and the caller since the caller could time out either
4349 before or while this code is executing. we use a spinlock to
4350 serialize these actions */
4351 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004352
4353 pStatsContext = pContext;
4354 pAdapter = pStatsContext->pAdapter;
4355 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4356 {
4357 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004358 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004359 hddLog(VOS_TRACE_LEVEL_WARN,
4360 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4361 __func__, pAdapter, pStatsContext->magic);
4362 return;
4363 }
4364
Jeff Johnson72a40512013-12-19 10:14:15 -08004365 /* context is valid so caller is still waiting */
4366
4367 /* paranoia: invalidate the magic */
4368 pStatsContext->magic = 0;
4369
4370 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004371 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4372 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4373 tsmMetrics.UplinkPktQueueDlyHist,
4374 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4375 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4376 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4377 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4378 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4379 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4380 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4381
Jeff Johnson72a40512013-12-19 10:14:15 -08004382 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004383 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004384
4385 /* serialization is complete */
4386 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004387}
4388
4389
4390
4391static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4392 tAniTrafStrmMetrics* pTsmMetrics)
4393{
4394 hdd_station_ctx_t *pHddStaCtx = NULL;
4395 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004396 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004397 long lrc;
4398 struct statsContext context;
4399 hdd_context_t *pHddCtx = NULL;
4400
4401 if (NULL == pAdapter)
4402 {
4403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4404 return VOS_STATUS_E_FAULT;
4405 }
4406
4407 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4408 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4409
4410 /* we are connected prepare our callback context */
4411 init_completion(&context.completion);
4412 context.pAdapter = pAdapter;
4413 context.magic = STATS_CONTEXT_MAGIC;
4414
4415 /* query tsm stats */
4416 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4417 pHddStaCtx->conn_info.staId[ 0 ],
4418 pHddStaCtx->conn_info.bssId,
4419 &context, pHddCtx->pvosContext, tid);
4420
4421 if (eHAL_STATUS_SUCCESS != hstatus)
4422 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4424 __func__);
4425 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004426 }
4427 else
4428 {
4429 /* request was sent -- wait for the response */
4430 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4431 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004432 if (lrc <= 0)
4433 {
4434 hddLog(VOS_TRACE_LEVEL_ERROR,
4435 "%s: SME %s while retrieving statistics",
4436 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004437 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004438 }
4439 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004440
Jeff Johnson72a40512013-12-19 10:14:15 -08004441 /* either we never sent a request, we sent a request and received a
4442 response or we sent a request and timed out. if we never sent a
4443 request or if we sent a request and got a response, we want to
4444 clear the magic out of paranoia. if we timed out there is a
4445 race condition such that the callback function could be
4446 executing at the same time we are. of primary concern is if the
4447 callback function had already verified the "magic" but had not
4448 yet set the completion variable when a timeout occurred. we
4449 serialize these activities by invalidating the magic while
4450 holding a shared spinlock which will cause us to block if the
4451 callback is currently executing */
4452 spin_lock(&hdd_context_lock);
4453 context.magic = 0;
4454 spin_unlock(&hdd_context_lock);
4455
4456 if (VOS_STATUS_SUCCESS == vstatus)
4457 {
4458 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4459 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4460 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4461 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4462 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4463 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4464 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4465 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4466 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4467 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4468 }
4469 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004470}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004471#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004472
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004473#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004474void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4475{
4476 eCsrBand band = -1;
4477 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4478 switch (band)
4479 {
4480 case eCSR_BAND_ALL:
4481 *pBand = WLAN_HDD_UI_BAND_AUTO;
4482 break;
4483
4484 case eCSR_BAND_24:
4485 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4486 break;
4487
4488 case eCSR_BAND_5G:
4489 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4490 break;
4491
4492 default:
4493 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4494 *pBand = -1;
4495 break;
4496 }
4497}
4498
4499/**---------------------------------------------------------------------------
4500
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004501 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4502
4503 This function parses the send action frame data passed in the format
4504 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4505
Srinivas Girigowda56076852013-08-20 14:00:50 -07004506 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004507 \param - pTargetApBssid Pointer to target Ap bssid
4508 \param - pChannel Pointer to the Target AP channel
4509 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4510 \param - pBuf Pointer to data
4511 \param - pBufLen Pointer to data length
4512
4513 \return - 0 for success non-zero for failure
4514
4515 --------------------------------------------------------------------------*/
4516VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4517 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4518{
4519 tANI_U8 *inPtr = pValue;
4520 tANI_U8 *dataEnd;
4521 int tempInt;
4522 int j = 0;
4523 int i = 0;
4524 int v = 0;
4525 tANI_U8 tempBuf[32];
4526 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004527 /* 12 hexa decimal digits, 5 ':' and '\0' */
4528 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004529
4530 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4531 /*no argument after the command*/
4532 if (NULL == inPtr)
4533 {
4534 return -EINVAL;
4535 }
4536
4537 /*no space after the command*/
4538 else if (SPACE_ASCII_VALUE != *inPtr)
4539 {
4540 return -EINVAL;
4541 }
4542
4543 /*removing empty spaces*/
4544 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4545
4546 /*no argument followed by spaces*/
4547 if ('\0' == *inPtr)
4548 {
4549 return -EINVAL;
4550 }
4551
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004552 v = sscanf(inPtr, "%17s", macAddress);
4553 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004554 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4556 "Invalid MAC address or All hex inputs are not read (%d)", v);
4557 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004558 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004559
4560 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4561 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4562 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4563 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4564 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4565 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004566
4567 /* point to the next argument */
4568 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4569 /*no argument after the command*/
4570 if (NULL == inPtr) return -EINVAL;
4571
4572 /*removing empty spaces*/
4573 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4574
4575 /*no argument followed by spaces*/
4576 if ('\0' == *inPtr)
4577 {
4578 return -EINVAL;
4579 }
4580
4581 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004582 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004583 if (1 != v) return -EINVAL;
4584
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004585 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304586 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304587 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004588
4589 *pChannel = tempInt;
4590
4591 /* point to the next argument */
4592 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4593 /*no argument after the command*/
4594 if (NULL == inPtr) return -EINVAL;
4595 /*removing empty spaces*/
4596 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4597
4598 /*no argument followed by spaces*/
4599 if ('\0' == *inPtr)
4600 {
4601 return -EINVAL;
4602 }
4603
4604 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004605 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004606 if (1 != v) return -EINVAL;
4607
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004608 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004609 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004610
4611 *pDwellTime = tempInt;
4612
4613 /* point to the next argument */
4614 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4615 /*no argument after the command*/
4616 if (NULL == inPtr) return -EINVAL;
4617 /*removing empty spaces*/
4618 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4619
4620 /*no argument followed by spaces*/
4621 if ('\0' == *inPtr)
4622 {
4623 return -EINVAL;
4624 }
4625
4626 /* find the length of data */
4627 dataEnd = inPtr;
4628 while(('\0' != *dataEnd) )
4629 {
4630 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004631 }
Kiet Lambe150c22013-11-21 16:30:32 +05304632 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004633 if ( *pBufLen <= 0) return -EINVAL;
4634
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004635 /* Allocate the number of bytes based on the number of input characters
4636 whether it is even or odd.
4637 if the number of input characters are even, then we need N/2 byte.
4638 if the number of input characters are odd, then we need do (N+1)/2 to
4639 compensate rounding off.
4640 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4641 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4642 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004643 if (NULL == *pBuf)
4644 {
4645 hddLog(VOS_TRACE_LEVEL_FATAL,
4646 "%s: vos_mem_alloc failed ", __func__);
4647 return -EINVAL;
4648 }
4649
4650 /* the buffer received from the upper layer is character buffer,
4651 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4652 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4653 and f0 in 3rd location */
4654 for (i = 0, j = 0; j < *pBufLen; j += 2)
4655 {
Kiet Lambe150c22013-11-21 16:30:32 +05304656 if( j+1 == *pBufLen)
4657 {
4658 tempByte = hdd_parse_hex(inPtr[j]);
4659 }
4660 else
4661 {
4662 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4663 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004664 (*pBuf)[i++] = tempByte;
4665 }
4666 *pBufLen = i;
4667 return VOS_STATUS_SUCCESS;
4668}
4669
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004670/**---------------------------------------------------------------------------
4671
Srinivas Girigowdade697412013-02-14 16:31:48 -08004672 \brief hdd_parse_channellist() - HDD Parse channel list
4673
4674 This function parses the channel list passed in the format
4675 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004676 if the Number of channels (N) does not match with the actual number of channels passed
4677 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4678 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4679 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4680 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004681
4682 \param - pValue Pointer to input channel list
4683 \param - ChannelList Pointer to local output array to record channel list
4684 \param - pNumChannels Pointer to number of roam scan channels
4685
4686 \return - 0 for success non-zero for failure
4687
4688 --------------------------------------------------------------------------*/
4689VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4690{
4691 tANI_U8 *inPtr = pValue;
4692 int tempInt;
4693 int j = 0;
4694 int v = 0;
4695 char buf[32];
4696
4697 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4698 /*no argument after the command*/
4699 if (NULL == inPtr)
4700 {
4701 return -EINVAL;
4702 }
4703
4704 /*no space after the command*/
4705 else if (SPACE_ASCII_VALUE != *inPtr)
4706 {
4707 return -EINVAL;
4708 }
4709
4710 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004711 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004712
4713 /*no argument followed by spaces*/
4714 if ('\0' == *inPtr)
4715 {
4716 return -EINVAL;
4717 }
4718
4719 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004720 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004721 if (1 != v) return -EINVAL;
4722
Srinivas Girigowdade697412013-02-14 16:31:48 -08004723 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004724 if ((v < 0) ||
4725 (tempInt <= 0) ||
4726 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4727 {
4728 return -EINVAL;
4729 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004730
4731 *pNumChannels = tempInt;
4732
4733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4734 "Number of channels are: %d", *pNumChannels);
4735
4736 for (j = 0; j < (*pNumChannels); j++)
4737 {
4738 /*inPtr pointing to the beginning of first space after number of channels*/
4739 inPtr = strpbrk( inPtr, " " );
4740 /*no channel list after the number of channels argument*/
4741 if (NULL == inPtr)
4742 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004743 if (0 != j)
4744 {
4745 *pNumChannels = j;
4746 return VOS_STATUS_SUCCESS;
4747 }
4748 else
4749 {
4750 return -EINVAL;
4751 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004752 }
4753
4754 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004755 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004756
4757 /*no channel list after the number of channels argument and spaces*/
4758 if ( '\0' == *inPtr )
4759 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004760 if (0 != j)
4761 {
4762 *pNumChannels = j;
4763 return VOS_STATUS_SUCCESS;
4764 }
4765 else
4766 {
4767 return -EINVAL;
4768 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004769 }
4770
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004771 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004772 if (1 != v) return -EINVAL;
4773
Srinivas Girigowdade697412013-02-14 16:31:48 -08004774 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004775 if ((v < 0) ||
4776 (tempInt <= 0) ||
4777 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4778 {
4779 return -EINVAL;
4780 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004781 pChannelList[j] = tempInt;
4782
4783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4784 "Channel %d added to preferred channel list",
4785 pChannelList[j] );
4786 }
4787
Srinivas Girigowdade697412013-02-14 16:31:48 -08004788 return VOS_STATUS_SUCCESS;
4789}
4790
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004791
4792/**---------------------------------------------------------------------------
4793
4794 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4795
4796 This function parses the reasoc command data passed in the format
4797 REASSOC<space><bssid><space><channel>
4798
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004799 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004800 \param - pTargetApBssid Pointer to target Ap bssid
4801 \param - pChannel Pointer to the Target AP channel
4802
4803 \return - 0 for success non-zero for failure
4804
4805 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004806VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4807 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004808{
4809 tANI_U8 *inPtr = pValue;
4810 int tempInt;
4811 int v = 0;
4812 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004813 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004814 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004815
4816 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4817 /*no argument after the command*/
4818 if (NULL == inPtr)
4819 {
4820 return -EINVAL;
4821 }
4822
4823 /*no space after the command*/
4824 else if (SPACE_ASCII_VALUE != *inPtr)
4825 {
4826 return -EINVAL;
4827 }
4828
4829 /*removing empty spaces*/
4830 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4831
4832 /*no argument followed by spaces*/
4833 if ('\0' == *inPtr)
4834 {
4835 return -EINVAL;
4836 }
4837
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004838 v = sscanf(inPtr, "%17s", macAddress);
4839 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004840 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4842 "Invalid MAC address or All hex inputs are not read (%d)", v);
4843 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004844 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004845
4846 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4847 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4848 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4849 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4850 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4851 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004852
4853 /* point to the next argument */
4854 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4855 /*no argument after the command*/
4856 if (NULL == inPtr) return -EINVAL;
4857
4858 /*removing empty spaces*/
4859 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4860
4861 /*no argument followed by spaces*/
4862 if ('\0' == *inPtr)
4863 {
4864 return -EINVAL;
4865 }
4866
4867 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004868 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004869 if (1 != v) return -EINVAL;
4870
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004871 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004872 if ((v < 0) ||
4873 (tempInt <= 0) ||
4874 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4875 {
4876 return -EINVAL;
4877 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004878
4879 *pChannel = tempInt;
4880 return VOS_STATUS_SUCCESS;
4881}
4882
4883#endif
4884
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004885#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004886/**---------------------------------------------------------------------------
4887
4888 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4889
4890 This function parses the SETCCKM IE command
4891 SETCCKMIE<space><ie data>
4892
4893 \param - pValue Pointer to input data
4894 \param - pCckmIe Pointer to output cckm Ie
4895 \param - pCckmIeLen Pointer to output cckm ie length
4896
4897 \return - 0 for success non-zero for failure
4898
4899 --------------------------------------------------------------------------*/
4900VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4901 tANI_U8 *pCckmIeLen)
4902{
4903 tANI_U8 *inPtr = pValue;
4904 tANI_U8 *dataEnd;
4905 int j = 0;
4906 int i = 0;
4907 tANI_U8 tempByte = 0;
4908
4909 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4910 /*no argument after the command*/
4911 if (NULL == inPtr)
4912 {
4913 return -EINVAL;
4914 }
4915
4916 /*no space after the command*/
4917 else if (SPACE_ASCII_VALUE != *inPtr)
4918 {
4919 return -EINVAL;
4920 }
4921
4922 /*removing empty spaces*/
4923 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4924
4925 /*no argument followed by spaces*/
4926 if ('\0' == *inPtr)
4927 {
4928 return -EINVAL;
4929 }
4930
4931 /* find the length of data */
4932 dataEnd = inPtr;
4933 while(('\0' != *dataEnd) )
4934 {
4935 dataEnd++;
4936 ++(*pCckmIeLen);
4937 }
4938 if ( *pCckmIeLen <= 0) return -EINVAL;
4939
4940 /* Allocate the number of bytes based on the number of input characters
4941 whether it is even or odd.
4942 if the number of input characters are even, then we need N/2 byte.
4943 if the number of input characters are odd, then we need do (N+1)/2 to
4944 compensate rounding off.
4945 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4946 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4947 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4948 if (NULL == *pCckmIe)
4949 {
4950 hddLog(VOS_TRACE_LEVEL_FATAL,
4951 "%s: vos_mem_alloc failed ", __func__);
4952 return -EINVAL;
4953 }
4954 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4955 /* the buffer received from the upper layer is character buffer,
4956 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4957 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4958 and f0 in 3rd location */
4959 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4960 {
4961 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4962 (*pCckmIe)[i++] = tempByte;
4963 }
4964 *pCckmIeLen = i;
4965
4966 return VOS_STATUS_SUCCESS;
4967}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004968#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004969
Jeff Johnson295189b2012-06-20 16:38:30 -07004970/**---------------------------------------------------------------------------
4971
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004972 \brief hdd_is_valid_mac_address() - Validate MAC address
4973
4974 This function validates whether the given MAC address is valid or not
4975 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4976 where X is the hexa decimal digit character and separated by ':'
4977 This algorithm works even if MAC address is not separated by ':'
4978
4979 This code checks given input string mac contains exactly 12 hexadecimal digits.
4980 and a separator colon : appears in the input string only after
4981 an even number of hex digits.
4982
4983 \param - pMacAddr pointer to the input MAC address
4984 \return - 1 for valid and 0 for invalid
4985
4986 --------------------------------------------------------------------------*/
4987
4988v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4989{
4990 int xdigit = 0;
4991 int separator = 0;
4992 while (*pMacAddr)
4993 {
4994 if (isxdigit(*pMacAddr))
4995 {
4996 xdigit++;
4997 }
4998 else if (':' == *pMacAddr)
4999 {
5000 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5001 break;
5002
5003 ++separator;
5004 }
5005 else
5006 {
5007 separator = -1;
5008 /* Invalid MAC found */
5009 return 0;
5010 }
5011 ++pMacAddr;
5012 }
5013 return (xdigit == 12 && (separator == 5 || separator == 0));
5014}
5015
5016/**---------------------------------------------------------------------------
5017
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 \brief hdd_open() - HDD Open function
5019
5020 This is called in response to ifconfig up
5021
5022 \param - dev Pointer to net_device structure
5023
5024 \return - 0 for success non-zero for failure
5025
5026 --------------------------------------------------------------------------*/
5027int hdd_open (struct net_device *dev)
5028{
5029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5030 hdd_context_t *pHddCtx;
5031 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5032 VOS_STATUS status;
5033 v_BOOL_t in_standby = TRUE;
5034
5035 if (NULL == pAdapter)
5036 {
5037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305038 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 return -ENODEV;
5040 }
5041
5042 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305043 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5044 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005045 if (NULL == pHddCtx)
5046 {
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005048 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 return -ENODEV;
5050 }
5051
5052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5053 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5054 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005055 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5056 {
5057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305058 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005059 in_standby = FALSE;
5060 break;
5061 }
5062 else
5063 {
5064 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5065 pAdapterNode = pNext;
5066 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005067 }
5068
5069 if (TRUE == in_standby)
5070 {
5071 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5072 {
5073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5074 "wlan out of power save", __func__);
5075 return -EINVAL;
5076 }
5077 }
5078
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005079 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5081 {
5082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005083 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 /* Enable TX queues only when we are connected */
5085 netif_tx_start_all_queues(dev);
5086 }
5087
5088 return 0;
5089}
5090
5091int hdd_mon_open (struct net_device *dev)
5092{
5093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5094
5095 if(pAdapter == NULL) {
5096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005097 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005098 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 }
5100
5101 netif_start_queue(dev);
5102
5103 return 0;
5104}
5105/**---------------------------------------------------------------------------
5106
5107 \brief hdd_stop() - HDD stop function
5108
5109 This is called in response to ifconfig down
5110
5111 \param - dev Pointer to net_device structure
5112
5113 \return - 0 for success non-zero for failure
5114
5115 --------------------------------------------------------------------------*/
5116
5117int hdd_stop (struct net_device *dev)
5118{
5119 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5120 hdd_context_t *pHddCtx;
5121 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5122 VOS_STATUS status;
5123 v_BOOL_t enter_standby = TRUE;
5124
5125 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 if (NULL == pAdapter)
5127 {
5128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305129 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 return -ENODEV;
5131 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305132 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5133 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5135 if (NULL == pHddCtx)
5136 {
5137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005138 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005139 return -ENODEV;
5140 }
5141
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305142 /* Nothing to be done if the interface is not opened */
5143 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5144 {
5145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5146 "%s: NETDEV Interface is not OPENED", __func__);
5147 return -ENODEV;
5148 }
5149
5150 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005151 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305153
5154 /* Disable TX on the interface, after this hard_start_xmit() will not
5155 * be called on that interface
5156 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005157 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305158
5159 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 netif_carrier_off(pAdapter->dev);
5161
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305162 /* The interface is marked as down for outside world (aka kernel)
5163 * But the driver is pretty much alive inside. The driver needs to
5164 * tear down the existing connection on the netdev (session)
5165 * cleanup the data pipes and wait until the control plane is stabilized
5166 * for this interface. The call also needs to wait until the above
5167 * mentioned actions are completed before returning to the caller.
5168 * Notice that the hdd_stop_adapter is requested not to close the session
5169 * That is intentional to be able to scan if it is a STA/P2P interface
5170 */
5171 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005172
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305173 /* DeInit the adapter. This ensures datapath cleanup as well */
5174 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 /* SoftAP ifaces should never go in power save mode
5176 making sure same here. */
5177 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5178 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005180 )
5181 {
5182 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5184 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005185 EXIT();
5186 return 0;
5187 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305188 /* Find if any iface is up. If any iface is up then can't put device to
5189 * sleep/power save mode
5190 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005191 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5192 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5193 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005194 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5195 {
5196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305197 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005198 enter_standby = FALSE;
5199 break;
5200 }
5201 else
5202 {
5203 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5204 pAdapterNode = pNext;
5205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 }
5207
5208 if (TRUE == enter_standby)
5209 {
5210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5211 "entering standby", __func__);
5212 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5213 {
5214 /*log and return success*/
5215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5216 "wlan in power save", __func__);
5217 }
5218 }
5219
5220 EXIT();
5221 return 0;
5222}
5223
5224/**---------------------------------------------------------------------------
5225
5226 \brief hdd_uninit() - HDD uninit function
5227
5228 This is called during the netdev unregister to uninitialize all data
5229associated with the device
5230
5231 \param - dev Pointer to net_device structure
5232
5233 \return - void
5234
5235 --------------------------------------------------------------------------*/
5236static void hdd_uninit (struct net_device *dev)
5237{
5238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5239
5240 ENTER();
5241
5242 do
5243 {
5244 if (NULL == pAdapter)
5245 {
5246 hddLog(VOS_TRACE_LEVEL_FATAL,
5247 "%s: NULL pAdapter", __func__);
5248 break;
5249 }
5250
5251 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5252 {
5253 hddLog(VOS_TRACE_LEVEL_FATAL,
5254 "%s: Invalid magic", __func__);
5255 break;
5256 }
5257
5258 if (NULL == pAdapter->pHddCtx)
5259 {
5260 hddLog(VOS_TRACE_LEVEL_FATAL,
5261 "%s: NULL pHddCtx", __func__);
5262 break;
5263 }
5264
5265 if (dev != pAdapter->dev)
5266 {
5267 hddLog(VOS_TRACE_LEVEL_FATAL,
5268 "%s: Invalid device reference", __func__);
5269 /* we haven't validated all cases so let this go for now */
5270 }
5271
5272 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5273
5274 /* after uninit our adapter structure will no longer be valid */
5275 pAdapter->dev = NULL;
5276 pAdapter->magic = 0;
5277 } while (0);
5278
5279 EXIT();
5280}
5281
5282/**---------------------------------------------------------------------------
5283
5284 \brief hdd_release_firmware() -
5285
5286 This function calls the release firmware API to free the firmware buffer.
5287
5288 \param - pFileName Pointer to the File Name.
5289 pCtx - Pointer to the adapter .
5290
5291
5292 \return - 0 for success, non zero for failure
5293
5294 --------------------------------------------------------------------------*/
5295
5296VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5297{
5298 VOS_STATUS status = VOS_STATUS_SUCCESS;
5299 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5300 ENTER();
5301
5302
5303 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5304
5305 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5306
5307 if(pHddCtx->fw) {
5308 release_firmware(pHddCtx->fw);
5309 pHddCtx->fw = NULL;
5310 }
5311 else
5312 status = VOS_STATUS_E_FAILURE;
5313 }
5314 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5315 if(pHddCtx->nv) {
5316 release_firmware(pHddCtx->nv);
5317 pHddCtx->nv = NULL;
5318 }
5319 else
5320 status = VOS_STATUS_E_FAILURE;
5321
5322 }
5323
5324 EXIT();
5325 return status;
5326}
5327
5328/**---------------------------------------------------------------------------
5329
5330 \brief hdd_request_firmware() -
5331
5332 This function reads the firmware file using the request firmware
5333 API and returns the the firmware data and the firmware file size.
5334
5335 \param - pfileName - Pointer to the file name.
5336 - pCtx - Pointer to the adapter .
5337 - ppfw_data - Pointer to the pointer of the firmware data.
5338 - pSize - Pointer to the file size.
5339
5340 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5341
5342 --------------------------------------------------------------------------*/
5343
5344
5345VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5346{
5347 int status;
5348 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5349 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5350 ENTER();
5351
5352 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5353
5354 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5355
5356 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5357 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5358 __func__, pfileName);
5359 retval = VOS_STATUS_E_FAILURE;
5360 }
5361
5362 else {
5363 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5364 *pSize = pHddCtx->fw->size;
5365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5366 __func__, *pSize);
5367 }
5368 }
5369 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5370
5371 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5372
5373 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5375 __func__, pfileName);
5376 retval = VOS_STATUS_E_FAILURE;
5377 }
5378
5379 else {
5380 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5381 *pSize = pHddCtx->nv->size;
5382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5383 __func__, *pSize);
5384 }
5385 }
5386
5387 EXIT();
5388 return retval;
5389}
5390/**---------------------------------------------------------------------------
5391 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5392
5393 This is the function invoked by SME to inform the result of a full power
5394 request issued by HDD
5395
5396 \param - callbackcontext - Pointer to cookie
5397 status - result of request
5398
5399 \return - None
5400
5401--------------------------------------------------------------------------*/
5402void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5403{
5404 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5405
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005406 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005407 if(&pHddCtx->full_pwr_comp_var)
5408 {
5409 complete(&pHddCtx->full_pwr_comp_var);
5410 }
5411}
5412
5413/**---------------------------------------------------------------------------
5414
5415 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5416
5417 This is the function invoked by SME to inform the result of BMPS
5418 request issued by HDD
5419
5420 \param - callbackcontext - Pointer to cookie
5421 status - result of request
5422
5423 \return - None
5424
5425--------------------------------------------------------------------------*/
5426void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5427{
5428
5429 struct completion *completion_var = (struct completion*) callbackContext;
5430
Arif Hussain6d2a3322013-11-17 19:50:10 -08005431 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 if(completion_var != NULL)
5433 {
5434 complete(completion_var);
5435 }
5436}
5437
5438/**---------------------------------------------------------------------------
5439
5440 \brief hdd_get_cfg_file_size() -
5441
5442 This function reads the configuration file using the request firmware
5443 API and returns the configuration file size.
5444
5445 \param - pCtx - Pointer to the adapter .
5446 - pFileName - Pointer to the file name.
5447 - pBufSize - Pointer to the buffer size.
5448
5449 \return - 0 for success, non zero for failure
5450
5451 --------------------------------------------------------------------------*/
5452
5453VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5454{
5455 int status;
5456 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5457
5458 ENTER();
5459
5460 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5461
5462 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5463 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5464 status = VOS_STATUS_E_FAILURE;
5465 }
5466 else {
5467 *pBufSize = pHddCtx->fw->size;
5468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5469 release_firmware(pHddCtx->fw);
5470 pHddCtx->fw = NULL;
5471 }
5472
5473 EXIT();
5474 return VOS_STATUS_SUCCESS;
5475}
5476
5477/**---------------------------------------------------------------------------
5478
5479 \brief hdd_read_cfg_file() -
5480
5481 This function reads the configuration file using the request firmware
5482 API and returns the cfg data and the buffer size of the configuration file.
5483
5484 \param - pCtx - Pointer to the adapter .
5485 - pFileName - Pointer to the file name.
5486 - pBuffer - Pointer to the data buffer.
5487 - pBufSize - Pointer to the buffer size.
5488
5489 \return - 0 for success, non zero for failure
5490
5491 --------------------------------------------------------------------------*/
5492
5493VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5494 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5495{
5496 int status;
5497 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5498
5499 ENTER();
5500
5501 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5502
5503 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5504 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5505 return VOS_STATUS_E_FAILURE;
5506 }
5507 else {
5508 if(*pBufSize != pHddCtx->fw->size) {
5509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5510 "file size", __func__);
5511 release_firmware(pHddCtx->fw);
5512 pHddCtx->fw = NULL;
5513 return VOS_STATUS_E_FAILURE;
5514 }
5515 else {
5516 if(pBuffer) {
5517 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5518 }
5519 release_firmware(pHddCtx->fw);
5520 pHddCtx->fw = NULL;
5521 }
5522 }
5523
5524 EXIT();
5525
5526 return VOS_STATUS_SUCCESS;
5527}
5528
5529/**---------------------------------------------------------------------------
5530
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 \brief hdd_set_mac_address() -
5532
5533 This function sets the user specified mac address using
5534 the command ifconfig wlanX hw ether <mac adress>.
5535
5536 \param - dev - Pointer to the net device.
5537 - addr - Pointer to the sockaddr.
5538 \return - 0 for success, non zero for failure
5539
5540 --------------------------------------------------------------------------*/
5541
5542static int hdd_set_mac_address(struct net_device *dev, void *addr)
5543{
5544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5545 struct sockaddr *psta_mac_addr = addr;
5546 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5547
5548 ENTER();
5549
5550 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5552
5553 EXIT();
5554 return halStatus;
5555}
5556
5557tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5558{
5559 int i;
5560 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5561 {
Abhishek Singheb183782014-02-06 13:37:21 +05305562 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 break;
5564 }
5565
5566 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5567 return NULL;
5568
5569 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5570 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5571}
5572
5573void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5574{
5575 int i;
5576 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5577 {
5578 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5579 {
5580 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5581 break;
5582 }
5583 }
5584 return;
5585}
5586
5587#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5588 static struct net_device_ops wlan_drv_ops = {
5589 .ndo_open = hdd_open,
5590 .ndo_stop = hdd_stop,
5591 .ndo_uninit = hdd_uninit,
5592 .ndo_start_xmit = hdd_hard_start_xmit,
5593 .ndo_tx_timeout = hdd_tx_timeout,
5594 .ndo_get_stats = hdd_stats,
5595 .ndo_do_ioctl = hdd_ioctl,
5596 .ndo_set_mac_address = hdd_set_mac_address,
5597 .ndo_select_queue = hdd_select_queue,
5598#ifdef WLAN_FEATURE_PACKET_FILTERING
5599#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5600 .ndo_set_rx_mode = hdd_set_multicast_list,
5601#else
5602 .ndo_set_multicast_list = hdd_set_multicast_list,
5603#endif //LINUX_VERSION_CODE
5604#endif
5605 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 static struct net_device_ops wlan_mon_drv_ops = {
5607 .ndo_open = hdd_mon_open,
5608 .ndo_stop = hdd_stop,
5609 .ndo_uninit = hdd_uninit,
5610 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5611 .ndo_tx_timeout = hdd_tx_timeout,
5612 .ndo_get_stats = hdd_stats,
5613 .ndo_do_ioctl = hdd_ioctl,
5614 .ndo_set_mac_address = hdd_set_mac_address,
5615 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005616
5617#endif
5618
5619void hdd_set_station_ops( struct net_device *pWlanDev )
5620{
5621#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 pWlanDev->netdev_ops = &wlan_drv_ops;
5623#else
5624 pWlanDev->open = hdd_open;
5625 pWlanDev->stop = hdd_stop;
5626 pWlanDev->uninit = hdd_uninit;
5627 pWlanDev->hard_start_xmit = NULL;
5628 pWlanDev->tx_timeout = hdd_tx_timeout;
5629 pWlanDev->get_stats = hdd_stats;
5630 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 pWlanDev->set_mac_address = hdd_set_mac_address;
5632#endif
5633}
5634
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005635static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005636{
5637 struct net_device *pWlanDev = NULL;
5638 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 /*
5640 * cfg80211 initialization and registration....
5641 */
5642 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5643
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 if(pWlanDev != NULL)
5645 {
5646
5647 //Save the pointer to the net_device in the HDD adapter
5648 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5649
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5651
5652 pAdapter->dev = pWlanDev;
5653 pAdapter->pHddCtx = pHddCtx;
5654 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05305655 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07005656
5657 init_completion(&pAdapter->session_open_comp_var);
5658 init_completion(&pAdapter->session_close_comp_var);
5659 init_completion(&pAdapter->disconnect_comp_var);
5660 init_completion(&pAdapter->linkup_event_var);
5661 init_completion(&pAdapter->cancel_rem_on_chan_var);
5662 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305663 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5665 init_completion(&pAdapter->offchannel_tx_event);
5666#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005667 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005668#ifdef FEATURE_WLAN_TDLS
5669 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005670 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005671 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305672 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005673#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 init_completion(&pHddCtx->mc_sus_event_var);
5675 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305676 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005677 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005678 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005679
Rajeev79dbe4c2013-10-05 11:03:42 +05305680#ifdef FEATURE_WLAN_BATCH_SCAN
5681 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5682 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5683 pAdapter->pBatchScanRsp = NULL;
5684 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005685 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005686 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305687 mutex_init(&pAdapter->hdd_batch_scan_lock);
5688#endif
5689
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 pAdapter->isLinkUpSvcNeeded = FALSE;
5691 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5692 //Init the net_device structure
5693 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5694
5695 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5696 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5697 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5698 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5699
5700 hdd_set_station_ops( pAdapter->dev );
5701
5702 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5704 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5705 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 /* set pWlanDev's parent to underlying device */
5707 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005708
5709 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 }
5711
5712 return pAdapter;
5713}
5714
5715VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5716{
5717 struct net_device *pWlanDev = pAdapter->dev;
5718 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5719 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5720 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5721
5722 if( rtnl_lock_held )
5723 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005724 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5726 {
5727 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5728 return VOS_STATUS_E_FAILURE;
5729 }
5730 }
5731 if (register_netdevice(pWlanDev))
5732 {
5733 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5734 return VOS_STATUS_E_FAILURE;
5735 }
5736 }
5737 else
5738 {
5739 if(register_netdev(pWlanDev))
5740 {
5741 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5742 return VOS_STATUS_E_FAILURE;
5743 }
5744 }
5745 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5746
5747 return VOS_STATUS_SUCCESS;
5748}
5749
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005750static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005751{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005752 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005753
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005754 if (NULL == pAdapter)
5755 {
5756 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5757 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005759
5760 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5761 {
5762 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5763 return eHAL_STATUS_NOT_INITIALIZED;
5764 }
5765
5766 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5767
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005768#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005769 /* need to make sure all of our scheduled work has completed.
5770 * This callback is called from MC thread context, so it is safe to
5771 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005772 *
5773 * Even though this is called from MC thread context, if there is a faulty
5774 * work item in the system, that can hang this call forever. So flushing
5775 * this global work queue is not safe; and now we make sure that
5776 * individual work queues are stopped correctly. But the cancel work queue
5777 * is a GPL only API, so the proprietary version of the driver would still
5778 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005779 */
5780 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005781#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005782
5783 /* We can be blocked while waiting for scheduled work to be
5784 * flushed, and the adapter structure can potentially be freed, in
5785 * which case the magic will have been reset. So make sure the
5786 * magic is still good, and hence the adapter structure is still
5787 * valid, before signaling completion */
5788 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5789 {
5790 complete(&pAdapter->session_close_comp_var);
5791 }
5792
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 return eHAL_STATUS_SUCCESS;
5794}
5795
5796VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5797{
5798 struct net_device *pWlanDev = pAdapter->dev;
5799 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5800 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5801 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5802 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305803 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005804
5805 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005806 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 //Open a SME session for future operation
5808 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005809 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5811 {
5812 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005813 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 halStatus, halStatus );
5815 status = VOS_STATUS_E_FAILURE;
5816 goto error_sme_open;
5817 }
5818
5819 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305820 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 &pAdapter->session_open_comp_var,
5822 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305823 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 {
5825 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305826 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 status = VOS_STATUS_E_FAILURE;
5828 goto error_sme_open;
5829 }
5830
5831 // Register wireless extensions
5832 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5833 {
5834 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005835 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 halStatus, halStatus );
5837 status = VOS_STATUS_E_FAILURE;
5838 goto error_register_wext;
5839 }
5840 //Safe to register the hard_start_xmit function again
5841#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5842 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5843#else
5844 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5845#endif
5846
5847 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305848 hddLog(VOS_TRACE_LEVEL_INFO,
5849 "%s: Set HDD connState to eConnectionState_NotConnected",
5850 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5852
5853 //Set the default operation channel
5854 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5855
5856 /* Make the default Auth Type as OPEN*/
5857 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5858
5859 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5860 {
5861 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005862 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 status, status );
5864 goto error_init_txrx;
5865 }
5866
5867 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5868
5869 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5870 {
5871 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005872 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 status, status );
5874 goto error_wmm_init;
5875 }
5876
5877 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5878
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005879#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305880 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005881 {
5882 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305883 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005884 goto error_tdls_init;
5885 }
5886 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5887#endif
5888
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 return VOS_STATUS_SUCCESS;
5890
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005891#ifdef FEATURE_WLAN_TDLS
5892error_tdls_init:
5893 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5894 hdd_wmm_adapter_close(pAdapter);
5895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005896error_wmm_init:
5897 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5898 hdd_deinit_tx_rx(pAdapter);
5899error_init_txrx:
5900 hdd_UnregisterWext(pWlanDev);
5901error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005902 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 {
5904 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005905 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005906 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005907 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305909 unsigned long rc;
5910
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305912 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005914 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305915 if (rc <= 0)
5916 hddLog(VOS_TRACE_LEVEL_ERROR,
5917 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 }
5919}
5920error_sme_open:
5921 return status;
5922}
5923
Jeff Johnson295189b2012-06-20 16:38:30 -07005924void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5925{
5926 hdd_cfg80211_state_t *cfgState;
5927
5928 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5929
5930 if( NULL != cfgState->buf )
5931 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305932 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5934 rc = wait_for_completion_interruptible_timeout(
5935 &pAdapter->tx_action_cnf_event,
5936 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305937 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305940 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5941 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 }
5943 }
5944 return;
5945}
Jeff Johnson295189b2012-06-20 16:38:30 -07005946
5947void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5948{
5949 ENTER();
5950 switch ( pAdapter->device_mode )
5951 {
5952 case WLAN_HDD_INFRA_STATION:
5953 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005954 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 {
5956 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5957 {
5958 hdd_deinit_tx_rx( pAdapter );
5959 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5960 }
5961
5962 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5963 {
5964 hdd_wmm_adapter_close( pAdapter );
5965 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5966 }
5967
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005969#ifdef FEATURE_WLAN_TDLS
5970 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5971 {
5972 wlan_hdd_tdls_exit(pAdapter);
5973 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5974 }
5975#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005976
5977 break;
5978 }
5979
5980 case WLAN_HDD_SOFTAP:
5981 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305983
5984 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5985 {
5986 hdd_wmm_adapter_close( pAdapter );
5987 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5988 }
5989
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005991
5992 hdd_unregister_hostapd(pAdapter);
5993 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 break;
5996 }
5997
5998 case WLAN_HDD_MONITOR:
5999 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6002 {
6003 hdd_deinit_tx_rx( pAdapter );
6004 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 if(NULL != pAdapterforTx)
6007 {
6008 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6009 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 break;
6011 }
6012
6013
6014 default:
6015 break;
6016 }
6017
6018 EXIT();
6019}
6020
6021void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6022{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006023 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306024
6025 ENTER();
6026 if (NULL == pAdapter)
6027 {
6028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6029 "%s: HDD adapter is Null", __func__);
6030 return;
6031 }
6032
6033 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006034
Rajeev79dbe4c2013-10-05 11:03:42 +05306035#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306036 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6037 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006038 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306039 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6040 )
6041 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006042 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306043 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006044 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6045 {
6046 hdd_deinit_batch_scan(pAdapter);
6047 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306048 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006049 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306050#endif
6051
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6053 if( rtnl_held )
6054 {
6055 unregister_netdevice(pWlanDev);
6056 }
6057 else
6058 {
6059 unregister_netdev(pWlanDev);
6060 }
6061 // note that the pAdapter is no longer valid at this point
6062 // since the memory has been reclaimed
6063 }
6064
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306065 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006066}
6067
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006068void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6069{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306070 VOS_STATUS status;
6071 hdd_adapter_t *pAdapter = NULL;
6072 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006073
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306074 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006075
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306076 /*loop through all adapters.*/
6077 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006078 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306079 pAdapter = pAdapterNode->pAdapter;
6080 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6081 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006082
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306083 { // we skip this registration for modes other than STA and P2P client modes.
6084 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6085 pAdapterNode = pNext;
6086 continue;
6087 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006088
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306089 //Apply Dynamic DTIM For P2P
6090 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6091 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6092 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6093 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6094 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6095 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6096 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6097 (eConnectionState_Associated ==
6098 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6099 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6100 {
6101 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006102
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306103 powerRequest.uIgnoreDTIM = 1;
6104 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6105
6106 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6107 {
6108 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6109 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6110 }
6111 else
6112 {
6113 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6114 }
6115
6116 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6117 * specified during Enter/Exit BMPS when LCD off*/
6118 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6119 NULL, eANI_BOOLEAN_FALSE);
6120 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6121 NULL, eANI_BOOLEAN_FALSE);
6122
6123 /* switch to the DTIM specified in cfg.ini */
6124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6125 "Switch to DTIM %d", powerRequest.uListenInterval);
6126 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6127 break;
6128
6129 }
6130
6131 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6132 pAdapterNode = pNext;
6133 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006134}
6135
6136void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6137{
6138 /*Switch back to DTIM 1*/
6139 tSirSetPowerParamsReq powerRequest = { 0 };
6140
6141 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6142 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006143 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006144
6145 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6146 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6147 NULL, eANI_BOOLEAN_FALSE);
6148 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6149 NULL, eANI_BOOLEAN_FALSE);
6150
6151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6152 "Switch to DTIM%d",powerRequest.uListenInterval);
6153 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6154
6155}
6156
Jeff Johnson295189b2012-06-20 16:38:30 -07006157VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6158{
6159 VOS_STATUS status = VOS_STATUS_SUCCESS;
6160
6161 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6162 {
6163 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6164 }
6165
6166 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6167 {
6168 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6169 }
6170
6171 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6172 {
6173 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6174 }
6175
6176 return status;
6177}
6178
6179VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6180{
6181 hdd_adapter_t *pAdapter = NULL;
6182 eHalStatus halStatus;
6183 VOS_STATUS status = VOS_STATUS_E_INVAL;
6184 v_BOOL_t disableBmps = FALSE;
6185 v_BOOL_t disableImps = FALSE;
6186
6187 switch(session_type)
6188 {
6189 case WLAN_HDD_INFRA_STATION:
6190 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006191 case WLAN_HDD_P2P_CLIENT:
6192 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 //Exit BMPS -> Is Sta/P2P Client is already connected
6194 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6195 if((NULL != pAdapter)&&
6196 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6197 {
6198 disableBmps = TRUE;
6199 }
6200
6201 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6202 if((NULL != pAdapter)&&
6203 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6204 {
6205 disableBmps = TRUE;
6206 }
6207
6208 //Exit both Bmps and Imps incase of Go/SAP Mode
6209 if((WLAN_HDD_SOFTAP == session_type) ||
6210 (WLAN_HDD_P2P_GO == session_type))
6211 {
6212 disableBmps = TRUE;
6213 disableImps = TRUE;
6214 }
6215
6216 if(TRUE == disableImps)
6217 {
6218 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6219 {
6220 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6221 }
6222 }
6223
6224 if(TRUE == disableBmps)
6225 {
6226 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6227 {
6228 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6229
6230 if(eHAL_STATUS_SUCCESS != halStatus)
6231 {
6232 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006233 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 VOS_ASSERT(0);
6235 return status;
6236 }
6237 }
6238
6239 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6240 {
6241 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6242
6243 if(eHAL_STATUS_SUCCESS != halStatus)
6244 {
6245 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006246 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 VOS_ASSERT(0);
6248 return status;
6249 }
6250 }
6251 }
6252
6253 if((TRUE == disableBmps) ||
6254 (TRUE == disableImps))
6255 {
6256 /* Now, get the chip into Full Power now */
6257 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6258 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6259 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6260
6261 if(halStatus != eHAL_STATUS_SUCCESS)
6262 {
6263 if(halStatus == eHAL_STATUS_PMC_PENDING)
6264 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306265 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306267 ret = wait_for_completion_interruptible_timeout(
6268 &pHddCtx->full_pwr_comp_var,
6269 msecs_to_jiffies(1000));
6270 if (ret <= 0)
6271 {
6272 hddLog(VOS_TRACE_LEVEL_ERROR,
6273 "%s: wait on full_pwr_comp_var failed %ld",
6274 __func__, ret);
6275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 }
6277 else
6278 {
6279 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006280 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 VOS_ASSERT(0);
6282 return status;
6283 }
6284 }
6285
6286 status = VOS_STATUS_SUCCESS;
6287 }
6288
6289 break;
6290 }
6291 return status;
6292}
6293
6294hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006295 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 tANI_U8 rtnl_held )
6297{
6298 hdd_adapter_t *pAdapter = NULL;
6299 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6300 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6301 VOS_STATUS exitbmpsStatus;
6302
Arif Hussain6d2a3322013-11-17 19:50:10 -08006303 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006304
Nirav Shah436658f2014-02-28 17:05:45 +05306305 if(macAddr == NULL)
6306 {
6307 /* Not received valid macAddr */
6308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6309 "%s:Unable to add virtual intf: Not able to get"
6310 "valid mac address",__func__);
6311 return NULL;
6312 }
6313
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 //Disable BMPS incase of Concurrency
6315 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6316
6317 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6318 {
6319 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306320 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 VOS_ASSERT(0);
6322 return NULL;
6323 }
6324
6325 switch(session_type)
6326 {
6327 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006329 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 {
6331 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6332
6333 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306334 {
6335 hddLog(VOS_TRACE_LEVEL_FATAL,
6336 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006339
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306340#ifdef FEATURE_WLAN_TDLS
6341 /* A Mutex Lock is introduced while changing/initializing the mode to
6342 * protect the concurrent access for the Adapters by TDLS module.
6343 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306344 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306345#endif
6346
Jeff Johnsone7245742012-09-05 17:12:55 -07006347 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6348 NL80211_IFTYPE_P2P_CLIENT:
6349 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306352#ifdef FEATURE_WLAN_TDLS
6353 mutex_unlock(&pHddCtx->tdls_lock);
6354#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306355
6356 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 if( VOS_STATUS_SUCCESS != status )
6358 goto err_free_netdev;
6359
6360 status = hdd_register_interface( pAdapter, rtnl_held );
6361 if( VOS_STATUS_SUCCESS != status )
6362 {
6363 hdd_deinit_adapter(pHddCtx, pAdapter);
6364 goto err_free_netdev;
6365 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306366
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306367 // Workqueue which gets scheduled in IPv4 notification callback.
6368 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6369
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306370#ifdef WLAN_NS_OFFLOAD
6371 // Workqueue which gets scheduled in IPv6 notification callback.
6372 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6373#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 //Stop the Interface TX queue.
6375 netif_tx_disable(pAdapter->dev);
6376 //netif_tx_disable(pWlanDev);
6377 netif_carrier_off(pAdapter->dev);
6378
6379 break;
6380 }
6381
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 case WLAN_HDD_SOFTAP:
6384 {
6385 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6386 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306387 {
6388 hddLog(VOS_TRACE_LEVEL_FATAL,
6389 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006392
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6394 NL80211_IFTYPE_AP:
6395 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 pAdapter->device_mode = session_type;
6397
6398 status = hdd_init_ap_mode(pAdapter);
6399 if( VOS_STATUS_SUCCESS != status )
6400 goto err_free_netdev;
6401
6402 status = hdd_register_hostapd( pAdapter, rtnl_held );
6403 if( VOS_STATUS_SUCCESS != status )
6404 {
6405 hdd_deinit_adapter(pHddCtx, pAdapter);
6406 goto err_free_netdev;
6407 }
6408
6409 netif_tx_disable(pAdapter->dev);
6410 netif_carrier_off(pAdapter->dev);
6411
6412 hdd_set_conparam( 1 );
6413 break;
6414 }
6415 case WLAN_HDD_MONITOR:
6416 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6418 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306419 {
6420 hddLog(VOS_TRACE_LEVEL_FATAL,
6421 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006424
6425 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6426 pAdapter->device_mode = session_type;
6427 status = hdd_register_interface( pAdapter, rtnl_held );
6428#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6429 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6430#else
6431 pAdapter->dev->open = hdd_mon_open;
6432 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6433#endif
6434 hdd_init_tx_rx( pAdapter );
6435 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6436 //Set adapter to be used for data tx. It will use either GO or softap.
6437 pAdapter->sessionCtx.monitor.pAdapterForTx =
6438 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6440 {
6441 pAdapter->sessionCtx.monitor.pAdapterForTx =
6442 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 /* This workqueue will be used to transmit management packet over
6445 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006446 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6447 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6448 return NULL;
6449 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006450
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6452 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 }
6454 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 case WLAN_HDD_FTM:
6456 {
6457 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6458
6459 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306460 {
6461 hddLog(VOS_TRACE_LEVEL_FATAL,
6462 FL("failed to allocate adapter for session %d"), session_type);
6463 return NULL;
6464 }
6465
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6467 * message while loading driver in FTM mode. */
6468 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6469 pAdapter->device_mode = session_type;
6470 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306471
6472 hdd_init_tx_rx( pAdapter );
6473
6474 //Stop the Interface TX queue.
6475 netif_tx_disable(pAdapter->dev);
6476 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 }
6478 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 default:
6480 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306481 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6482 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 VOS_ASSERT(0);
6484 return NULL;
6485 }
6486 }
6487
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 if( VOS_STATUS_SUCCESS == status )
6489 {
6490 //Add it to the hdd's session list.
6491 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6492 if( NULL == pHddAdapterNode )
6493 {
6494 status = VOS_STATUS_E_NOMEM;
6495 }
6496 else
6497 {
6498 pHddAdapterNode->pAdapter = pAdapter;
6499 status = hdd_add_adapter_back ( pHddCtx,
6500 pHddAdapterNode );
6501 }
6502 }
6503
6504 if( VOS_STATUS_SUCCESS != status )
6505 {
6506 if( NULL != pAdapter )
6507 {
6508 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6509 pAdapter = NULL;
6510 }
6511 if( NULL != pHddAdapterNode )
6512 {
6513 vos_mem_free( pHddAdapterNode );
6514 }
6515
6516 goto resume_bmps;
6517 }
6518
6519 if(VOS_STATUS_SUCCESS == status)
6520 {
6521 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6522
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006523 //Initialize the WoWL service
6524 if(!hdd_init_wowl(pAdapter))
6525 {
6526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6527 goto err_free_netdev;
6528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 return pAdapter;
6531
6532err_free_netdev:
6533 free_netdev(pAdapter->dev);
6534 wlan_hdd_release_intf_addr( pHddCtx,
6535 pAdapter->macAddressCurrent.bytes );
6536
6537resume_bmps:
6538 //If bmps disabled enable it
6539 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6540 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306541 if (pHddCtx->hdd_wlan_suspended)
6542 {
6543 hdd_set_pwrparams(pHddCtx);
6544 }
6545 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 }
6547 return NULL;
6548}
6549
6550VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6551 tANI_U8 rtnl_held )
6552{
6553 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6554 VOS_STATUS status;
6555
6556 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6557 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306558 {
6559 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6560 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006563
6564 while ( pCurrent->pAdapter != pAdapter )
6565 {
6566 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6567 if( VOS_STATUS_SUCCESS != status )
6568 break;
6569
6570 pCurrent = pNext;
6571 }
6572 pAdapterNode = pCurrent;
6573 if( VOS_STATUS_SUCCESS == status )
6574 {
6575 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6576 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306577
6578#ifdef FEATURE_WLAN_TDLS
6579
6580 /* A Mutex Lock is introduced while changing/initializing the mode to
6581 * protect the concurrent access for the Adapters by TDLS module.
6582 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306583 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306584#endif
6585
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 hdd_remove_adapter( pHddCtx, pAdapterNode );
6587 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006588 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006589
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306590#ifdef FEATURE_WLAN_TDLS
6591 mutex_unlock(&pHddCtx->tdls_lock);
6592#endif
6593
Jeff Johnson295189b2012-06-20 16:38:30 -07006594
6595 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306596 if ((!vos_concurrent_open_sessions_running()) &&
6597 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6598 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306600 if (pHddCtx->hdd_wlan_suspended)
6601 {
6602 hdd_set_pwrparams(pHddCtx);
6603 }
6604 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006605 }
6606
6607 return VOS_STATUS_SUCCESS;
6608 }
6609
6610 return VOS_STATUS_E_FAILURE;
6611}
6612
6613VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6614{
6615 hdd_adapter_list_node_t *pHddAdapterNode;
6616 VOS_STATUS status;
6617
6618 ENTER();
6619
6620 do
6621 {
6622 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6623 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6624 {
6625 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6626 vos_mem_free( pHddAdapterNode );
6627 }
6628 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6629
6630 EXIT();
6631
6632 return VOS_STATUS_SUCCESS;
6633}
6634
6635void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6636{
6637 v_U8_t addIE[1] = {0};
6638
6639 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6640 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6641 eANI_BOOLEAN_FALSE) )
6642 {
6643 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006644 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 }
6646
6647 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6648 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6649 eANI_BOOLEAN_FALSE) )
6650 {
6651 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006652 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 }
6654
6655 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6656 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6657 eANI_BOOLEAN_FALSE) )
6658 {
6659 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006660 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 }
6662}
6663
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306664VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6665 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006666{
6667 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6668 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6669 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306670 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306671 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006672
6673 ENTER();
6674
6675 switch(pAdapter->device_mode)
6676 {
6677 case WLAN_HDD_INFRA_STATION:
6678 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006679 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306680 {
6681 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6682 if( hdd_connIsConnected(pstation) ||
6683 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 {
6685 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6686 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6687 pAdapter->sessionId,
6688 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6689 else
6690 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6691 pAdapter->sessionId,
6692 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6693 //success implies disconnect command got queued up successfully
6694 if(halStatus == eHAL_STATUS_SUCCESS)
6695 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306696 ret = wait_for_completion_interruptible_timeout(
6697 &pAdapter->disconnect_comp_var,
6698 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6699 if (ret <= 0)
6700 {
6701 hddLog(VOS_TRACE_LEVEL_ERROR,
6702 "%s: wait on disconnect_comp_var failed %ld",
6703 __func__, ret);
6704 }
6705 }
6706 else
6707 {
6708 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6709 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 }
6711 memset(&wrqu, '\0', sizeof(wrqu));
6712 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6713 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6714 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6715 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306716 else if(pstation->conn_info.connState ==
6717 eConnectionState_Disconnecting)
6718 {
6719 ret = wait_for_completion_interruptible_timeout(
6720 &pAdapter->disconnect_comp_var,
6721 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6722 if (ret <= 0)
6723 {
6724 hddLog(VOS_TRACE_LEVEL_ERROR,
6725 FL("wait on disconnect_comp_var failed %ld"), ret);
6726 }
6727 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006728 else
6729 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306730 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6731 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306733 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6734 {
6735 while (pAdapter->is_roc_inprogress)
6736 {
6737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6738 "%s: ROC in progress for session %d!!!",
6739 __func__, pAdapter->sessionId);
6740 // waiting for ROC to expire
6741 msleep(500);
6742 /* In GO present case , if retry exceeds 3,
6743 it means something went wrong. */
6744 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6745 {
6746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6747 "%s: ROC completion is not received.!!!", __func__);
6748 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6749 pAdapter->sessionId);
6750 wait_for_completion_interruptible_timeout(
6751 &pAdapter->cancel_rem_on_chan_var,
6752 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6753 break;
6754 }
6755 }
6756 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306757#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306758#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306759 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6760#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306761 if (pAdapter->ipv6_notifier_registered)
6762 {
6763 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6764 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6765 pAdapter->ipv6_notifier_registered = false;
6766 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306767#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306768 if (pAdapter->ipv4_notifier_registered)
6769 {
6770 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6771 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6772 pAdapter->ipv4_notifier_registered = false;
6773 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306774#ifdef WLAN_OPEN_SOURCE
6775 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6776#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306777 /* It is possible that the caller of this function does not
6778 * wish to close the session
6779 */
6780 if (VOS_TRUE == bCloseSession &&
6781 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 {
6783 INIT_COMPLETION(pAdapter->session_close_comp_var);
6784 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306785 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6786 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306788 unsigned long ret;
6789
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306791 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306792 &pAdapter->session_close_comp_var,
6793 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306794 if ( 0 >= ret)
6795 {
6796 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306797 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306798 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 }
6800 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 break;
6803
6804 case WLAN_HDD_SOFTAP:
6805 case WLAN_HDD_P2P_GO:
6806 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306807 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6808 while (pAdapter->is_roc_inprogress) {
6809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6810 "%s: ROC in progress for session %d!!!",
6811 __func__, pAdapter->sessionId);
6812 msleep(500);
6813 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6815 "%s: ROC completion is not received.!!!", __func__);
6816 WLANSAP_CancelRemainOnChannel(
6817 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6818 wait_for_completion_interruptible_timeout(
6819 &pAdapter->cancel_rem_on_chan_var,
6820 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6821 break;
6822 }
6823 }
6824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 mutex_lock(&pHddCtx->sap_lock);
6826 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6827 {
6828 VOS_STATUS status;
6829 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6830
6831 //Stop Bss.
6832 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6833 if (VOS_IS_STATUS_SUCCESS(status))
6834 {
6835 hdd_hostapd_state_t *pHostapdState =
6836 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6837
6838 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6839
6840 if (!VOS_IS_STATUS_SUCCESS(status))
6841 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306842 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6843 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 }
6845 }
6846 else
6847 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006848 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 }
6850 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306851 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006852
6853 if (eHAL_STATUS_FAILURE ==
6854 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6855 0, NULL, eANI_BOOLEAN_FALSE))
6856 {
6857 hddLog(LOGE,
6858 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006859 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 }
6861
6862 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6863 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6864 eANI_BOOLEAN_FALSE) )
6865 {
6866 hddLog(LOGE,
6867 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6868 }
6869
6870 // Reset WNI_CFG_PROBE_RSP Flags
6871 wlan_hdd_reset_prob_rspies(pAdapter);
6872 kfree(pAdapter->sessionCtx.ap.beacon);
6873 pAdapter->sessionCtx.ap.beacon = NULL;
6874 }
6875 mutex_unlock(&pHddCtx->sap_lock);
6876 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006877
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006879#ifdef WLAN_OPEN_SOURCE
6880 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6881#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006883
Jeff Johnson295189b2012-06-20 16:38:30 -07006884 default:
6885 break;
6886 }
6887
6888 EXIT();
6889 return VOS_STATUS_SUCCESS;
6890}
6891
6892VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6893{
6894 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6895 VOS_STATUS status;
6896 hdd_adapter_t *pAdapter;
6897
6898 ENTER();
6899
6900 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6901
6902 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6903 {
6904 pAdapter = pAdapterNode->pAdapter;
6905 netif_tx_disable(pAdapter->dev);
6906 netif_carrier_off(pAdapter->dev);
6907
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306908 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006909
6910 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6911 pAdapterNode = pNext;
6912 }
6913
6914 EXIT();
6915
6916 return VOS_STATUS_SUCCESS;
6917}
6918
Rajeev Kumarf999e582014-01-09 17:33:29 -08006919
6920#ifdef FEATURE_WLAN_BATCH_SCAN
6921/**---------------------------------------------------------------------------
6922
6923 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6924 structures
6925
6926 \param - pAdapter Pointer to HDD adapter
6927
6928 \return - None
6929
6930 --------------------------------------------------------------------------*/
6931void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6932{
6933 tHddBatchScanRsp *pNode;
6934 tHddBatchScanRsp *pPrev;
6935
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306936 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006937 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306938 hddLog(VOS_TRACE_LEVEL_ERROR,
6939 "%s: Adapter context is Null", __func__);
6940 return;
6941 }
6942
6943 pNode = pAdapter->pBatchScanRsp;
6944 while (pNode)
6945 {
6946 pPrev = pNode;
6947 pNode = pNode->pNext;
6948 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006949 }
6950
6951 pAdapter->pBatchScanRsp = NULL;
6952 pAdapter->numScanList = 0;
6953 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6954 pAdapter->prev_batch_id = 0;
6955
6956 return;
6957}
6958#endif
6959
6960
Jeff Johnson295189b2012-06-20 16:38:30 -07006961VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6962{
6963 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6964 VOS_STATUS status;
6965 hdd_adapter_t *pAdapter;
6966
6967 ENTER();
6968
6969 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6970
6971 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6972 {
6973 pAdapter = pAdapterNode->pAdapter;
6974 netif_tx_disable(pAdapter->dev);
6975 netif_carrier_off(pAdapter->dev);
6976
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006977 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6978
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05306980
6981 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
6982
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306983 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6984 {
6985 hdd_wmm_adapter_close( pAdapter );
6986 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006988
Rajeev Kumarf999e582014-01-09 17:33:29 -08006989#ifdef FEATURE_WLAN_BATCH_SCAN
6990 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6991 {
6992 hdd_deinit_batch_scan(pAdapter);
6993 }
6994#endif
6995
Jeff Johnson295189b2012-06-20 16:38:30 -07006996 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6997 pAdapterNode = pNext;
6998 }
6999
7000 EXIT();
7001
7002 return VOS_STATUS_SUCCESS;
7003}
7004
7005VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7006{
7007 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7008 VOS_STATUS status;
7009 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307010 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007011
7012 ENTER();
7013
7014 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7015
7016 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7017 {
7018 pAdapter = pAdapterNode->pAdapter;
7019
Kumar Anand82c009f2014-05-29 00:29:42 -07007020 hdd_wmm_init( pAdapter );
7021
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 switch(pAdapter->device_mode)
7023 {
7024 case WLAN_HDD_INFRA_STATION:
7025 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007026 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307027
7028 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7029
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 hdd_init_station_mode(pAdapter);
7031 /* Open the gates for HDD to receive Wext commands */
7032 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007033 pHddCtx->scan_info.mScanPending = FALSE;
7034 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007035
7036 //Trigger the initial scan
7037 hdd_wlan_initial_scan(pAdapter);
7038
7039 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307040 if (eConnectionState_Associated == connState ||
7041 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 {
7043 union iwreq_data wrqu;
7044 memset(&wrqu, '\0', sizeof(wrqu));
7045 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7046 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7047 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007048 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007049
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 /* indicate disconnected event to nl80211 */
7051 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7052 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307054 else if (eConnectionState_Connecting == connState)
7055 {
7056 /*
7057 * Indicate connect failure to supplicant if we were in the
7058 * process of connecting
7059 */
7060 cfg80211_connect_result(pAdapter->dev, NULL,
7061 NULL, 0, NULL, 0,
7062 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7063 GFP_KERNEL);
7064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 break;
7066
7067 case WLAN_HDD_SOFTAP:
7068 /* softAP can handle SSR */
7069 break;
7070
7071 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007074 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 break;
7076
7077 case WLAN_HDD_MONITOR:
7078 /* monitor interface start */
7079 break;
7080 default:
7081 break;
7082 }
7083
7084 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7085 pAdapterNode = pNext;
7086 }
7087
7088 EXIT();
7089
7090 return VOS_STATUS_SUCCESS;
7091}
7092
7093VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7094{
7095 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7096 hdd_adapter_t *pAdapter;
7097 VOS_STATUS status;
7098 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307099 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007100
7101 ENTER();
7102
7103 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7104
7105 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7106 {
7107 pAdapter = pAdapterNode->pAdapter;
7108
7109 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7110 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7111 {
7112 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7113 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7114
Abhishek Singhf4669da2014-05-26 15:07:49 +05307115 hddLog(VOS_TRACE_LEVEL_INFO,
7116 "%s: Set HDD connState to eConnectionState_NotConnected",
7117 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7119 init_completion(&pAdapter->disconnect_comp_var);
7120 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7121 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7122
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307123 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 &pAdapter->disconnect_comp_var,
7125 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307126 if (0 >= ret)
7127 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7128 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129
7130 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7131 pHddCtx->isAmpAllowed = VOS_FALSE;
7132 sme_RoamConnect(pHddCtx->hHal,
7133 pAdapter->sessionId, &(pWextState->roamProfile),
7134 &roamId);
7135 }
7136
7137 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7138 pAdapterNode = pNext;
7139 }
7140
7141 EXIT();
7142
7143 return VOS_STATUS_SUCCESS;
7144}
7145
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007146void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7147{
7148 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7149 VOS_STATUS status;
7150 hdd_adapter_t *pAdapter;
7151 hdd_station_ctx_t *pHddStaCtx;
7152 hdd_ap_ctx_t *pHddApCtx;
7153 hdd_hostapd_state_t * pHostapdState;
7154 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7155 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7156 const char *p2pMode = "DEV";
7157 const char *ccMode = "Standalone";
7158 int n;
7159
7160 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7161 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7162 {
7163 pAdapter = pAdapterNode->pAdapter;
7164 switch (pAdapter->device_mode) {
7165 case WLAN_HDD_INFRA_STATION:
7166 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7167 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7168 staChannel = pHddStaCtx->conn_info.operationChannel;
7169 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7170 }
7171 break;
7172 case WLAN_HDD_P2P_CLIENT:
7173 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7174 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7175 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7176 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7177 p2pMode = "CLI";
7178 }
7179 break;
7180 case WLAN_HDD_P2P_GO:
7181 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7182 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7183 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7184 p2pChannel = pHddApCtx->operatingChannel;
7185 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7186 }
7187 p2pMode = "GO";
7188 break;
7189 case WLAN_HDD_SOFTAP:
7190 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7191 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7192 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7193 apChannel = pHddApCtx->operatingChannel;
7194 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7195 }
7196 break;
7197 default:
7198 break;
7199 }
7200 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7201 pAdapterNode = pNext;
7202 }
7203 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7204 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7205 }
7206 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7207 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7208 if (p2pChannel > 0) {
7209 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7210 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7211 }
7212 if (apChannel > 0) {
7213 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7214 apChannel, MAC_ADDR_ARRAY(apBssid));
7215 }
7216
7217 if (p2pChannel > 0 && apChannel > 0) {
7218 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7219 }
7220}
7221
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007222bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007223{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007224 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007225}
7226
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007227/* Once SSR is disabled then it cannot be set. */
7228void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007229{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007230 if (HDD_SSR_DISABLED == isSsrRequired)
7231 return;
7232
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 isSsrRequired = value;
7234}
7235
7236VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7237 hdd_adapter_list_node_t** ppAdapterNode)
7238{
7239 VOS_STATUS status;
7240 spin_lock(&pHddCtx->hddAdapters.lock);
7241 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7242 (hdd_list_node_t**) ppAdapterNode );
7243 spin_unlock(&pHddCtx->hddAdapters.lock);
7244 return status;
7245}
7246
7247VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7248 hdd_adapter_list_node_t* pAdapterNode,
7249 hdd_adapter_list_node_t** pNextAdapterNode)
7250{
7251 VOS_STATUS status;
7252 spin_lock(&pHddCtx->hddAdapters.lock);
7253 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7254 (hdd_list_node_t*) pAdapterNode,
7255 (hdd_list_node_t**)pNextAdapterNode );
7256
7257 spin_unlock(&pHddCtx->hddAdapters.lock);
7258 return status;
7259}
7260
7261VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7262 hdd_adapter_list_node_t* pAdapterNode)
7263{
7264 VOS_STATUS status;
7265 spin_lock(&pHddCtx->hddAdapters.lock);
7266 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7267 &pAdapterNode->node );
7268 spin_unlock(&pHddCtx->hddAdapters.lock);
7269 return status;
7270}
7271
7272VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7273 hdd_adapter_list_node_t** ppAdapterNode)
7274{
7275 VOS_STATUS status;
7276 spin_lock(&pHddCtx->hddAdapters.lock);
7277 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7278 (hdd_list_node_t**) ppAdapterNode );
7279 spin_unlock(&pHddCtx->hddAdapters.lock);
7280 return status;
7281}
7282
7283VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7284 hdd_adapter_list_node_t* pAdapterNode)
7285{
7286 VOS_STATUS status;
7287 spin_lock(&pHddCtx->hddAdapters.lock);
7288 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7289 (hdd_list_node_t*) pAdapterNode );
7290 spin_unlock(&pHddCtx->hddAdapters.lock);
7291 return status;
7292}
7293
7294VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7295 hdd_adapter_list_node_t* pAdapterNode)
7296{
7297 VOS_STATUS status;
7298 spin_lock(&pHddCtx->hddAdapters.lock);
7299 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7300 (hdd_list_node_t*) pAdapterNode );
7301 spin_unlock(&pHddCtx->hddAdapters.lock);
7302 return status;
7303}
7304
7305hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7306 tSirMacAddr macAddr )
7307{
7308 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7309 hdd_adapter_t *pAdapter;
7310 VOS_STATUS status;
7311
7312 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7313
7314 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7315 {
7316 pAdapter = pAdapterNode->pAdapter;
7317
7318 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7319 macAddr, sizeof(tSirMacAddr) ) )
7320 {
7321 return pAdapter;
7322 }
7323 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7324 pAdapterNode = pNext;
7325 }
7326
7327 return NULL;
7328
7329}
7330
7331hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7332{
7333 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7334 hdd_adapter_t *pAdapter;
7335 VOS_STATUS status;
7336
7337 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7338
7339 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7340 {
7341 pAdapter = pAdapterNode->pAdapter;
7342
7343 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7344 IFNAMSIZ ) )
7345 {
7346 return pAdapter;
7347 }
7348 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7349 pAdapterNode = pNext;
7350 }
7351
7352 return NULL;
7353
7354}
7355
7356hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7357{
7358 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7359 hdd_adapter_t *pAdapter;
7360 VOS_STATUS status;
7361
7362 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7363
7364 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7365 {
7366 pAdapter = pAdapterNode->pAdapter;
7367
7368 if( pAdapter && (mode == pAdapter->device_mode) )
7369 {
7370 return pAdapter;
7371 }
7372 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7373 pAdapterNode = pNext;
7374 }
7375
7376 return NULL;
7377
7378}
7379
7380//Remove this function later
7381hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7382{
7383 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7384 hdd_adapter_t *pAdapter;
7385 VOS_STATUS status;
7386
7387 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7388
7389 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7390 {
7391 pAdapter = pAdapterNode->pAdapter;
7392
7393 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7394 {
7395 return pAdapter;
7396 }
7397
7398 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7399 pAdapterNode = pNext;
7400 }
7401
7402 return NULL;
7403
7404}
7405
Jeff Johnson295189b2012-06-20 16:38:30 -07007406/**---------------------------------------------------------------------------
7407
7408 \brief hdd_set_monitor_tx_adapter() -
7409
7410 This API initializes the adapter to be used while transmitting on monitor
7411 adapter.
7412
7413 \param - pHddCtx - Pointer to the HDD context.
7414 pAdapter - Adapter that will used for TX. This can be NULL.
7415 \return - None.
7416 --------------------------------------------------------------------------*/
7417void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7418{
7419 hdd_adapter_t *pMonAdapter;
7420
7421 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7422
7423 if( NULL != pMonAdapter )
7424 {
7425 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7426 }
7427}
Jeff Johnson295189b2012-06-20 16:38:30 -07007428/**---------------------------------------------------------------------------
7429
7430 \brief hdd_select_queue() -
7431
7432 This API returns the operating channel of the requested device mode
7433
7434 \param - pHddCtx - Pointer to the HDD context.
7435 - mode - Device mode for which operating channel is required
7436 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7437 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7438 \return - channel number. "0" id the requested device is not found OR it is not connected.
7439 --------------------------------------------------------------------------*/
7440v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7441{
7442 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7443 VOS_STATUS status;
7444 hdd_adapter_t *pAdapter;
7445 v_U8_t operatingChannel = 0;
7446
7447 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7448
7449 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7450 {
7451 pAdapter = pAdapterNode->pAdapter;
7452
7453 if( mode == pAdapter->device_mode )
7454 {
7455 switch(pAdapter->device_mode)
7456 {
7457 case WLAN_HDD_INFRA_STATION:
7458 case WLAN_HDD_P2P_CLIENT:
7459 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7460 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7461 break;
7462 case WLAN_HDD_SOFTAP:
7463 case WLAN_HDD_P2P_GO:
7464 /*softap connection info */
7465 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7466 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7467 break;
7468 default:
7469 break;
7470 }
7471
7472 break; //Found the device of interest. break the loop
7473 }
7474
7475 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7476 pAdapterNode = pNext;
7477 }
7478 return operatingChannel;
7479}
7480
7481#ifdef WLAN_FEATURE_PACKET_FILTERING
7482/**---------------------------------------------------------------------------
7483
7484 \brief hdd_set_multicast_list() -
7485
7486 This used to set the multicast address list.
7487
7488 \param - dev - Pointer to the WLAN device.
7489 - skb - Pointer to OS packet (sk_buff).
7490 \return - success/fail
7491
7492 --------------------------------------------------------------------------*/
7493static void hdd_set_multicast_list(struct net_device *dev)
7494{
7495 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 int mc_count;
7497 int i = 0;
7498 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307499
7500 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 {
7502 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307503 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007504 return;
7505 }
7506
7507 if (dev->flags & IFF_ALLMULTI)
7508 {
7509 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007510 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307511 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 }
7513 else
7514 {
7515 mc_count = netdev_mc_count(dev);
7516 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007517 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007518 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7519 {
7520 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007521 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307522 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 return;
7524 }
7525
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307526 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007527
7528 netdev_for_each_mc_addr(ha, dev) {
7529 if (i == mc_count)
7530 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307531 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7532 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007533 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307535 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 i++;
7537 }
7538 }
7539 return;
7540}
7541#endif
7542
7543/**---------------------------------------------------------------------------
7544
7545 \brief hdd_select_queue() -
7546
7547 This function is registered with the Linux OS for network
7548 core to decide which queue to use first.
7549
7550 \param - dev - Pointer to the WLAN device.
7551 - skb - Pointer to OS packet (sk_buff).
7552 \return - ac, Queue Index/access category corresponding to UP in IP header
7553
7554 --------------------------------------------------------------------------*/
7555v_U16_t hdd_select_queue(struct net_device *dev,
7556 struct sk_buff *skb)
7557{
7558 return hdd_wmm_select_queue(dev, skb);
7559}
7560
7561
7562/**---------------------------------------------------------------------------
7563
7564 \brief hdd_wlan_initial_scan() -
7565
7566 This function triggers the initial scan
7567
7568 \param - pAdapter - Pointer to the HDD adapter.
7569
7570 --------------------------------------------------------------------------*/
7571void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7572{
7573 tCsrScanRequest scanReq;
7574 tCsrChannelInfo channelInfo;
7575 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007576 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007577 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7578
7579 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7580 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7581 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7582
7583 if(sme_Is11dSupported(pHddCtx->hHal))
7584 {
7585 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7586 if ( HAL_STATUS_SUCCESS( halStatus ) )
7587 {
7588 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7589 if( !scanReq.ChannelInfo.ChannelList )
7590 {
7591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7592 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007593 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007594 return;
7595 }
7596 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7597 channelInfo.numOfChannels);
7598 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7599 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007600 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007601 }
7602
7603 scanReq.scanType = eSIR_PASSIVE_SCAN;
7604 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7605 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7606 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7607 }
7608 else
7609 {
7610 scanReq.scanType = eSIR_ACTIVE_SCAN;
7611 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7612 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7613 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7614 }
7615
7616 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7617 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7618 {
7619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7620 __func__, halStatus );
7621 }
7622
7623 if(sme_Is11dSupported(pHddCtx->hHal))
7624 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7625}
7626
Jeff Johnson295189b2012-06-20 16:38:30 -07007627/**---------------------------------------------------------------------------
7628
7629 \brief hdd_full_power_callback() - HDD full power callback function
7630
7631 This is the function invoked by SME to inform the result of a full power
7632 request issued by HDD
7633
7634 \param - callbackcontext - Pointer to cookie
7635 \param - status - result of request
7636
7637 \return - None
7638
7639 --------------------------------------------------------------------------*/
7640static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7641{
Jeff Johnson72a40512013-12-19 10:14:15 -08007642 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007643
7644 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307645 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007646
7647 if (NULL == callbackContext)
7648 {
7649 hddLog(VOS_TRACE_LEVEL_ERROR,
7650 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007651 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 return;
7653 }
7654
Jeff Johnson72a40512013-12-19 10:14:15 -08007655 /* there is a race condition that exists between this callback
7656 function and the caller since the caller could time out either
7657 before or while this code is executing. we use a spinlock to
7658 serialize these actions */
7659 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007660
7661 if (POWER_CONTEXT_MAGIC != pContext->magic)
7662 {
7663 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007664 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 hddLog(VOS_TRACE_LEVEL_WARN,
7666 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007667 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 return;
7669 }
7670
Jeff Johnson72a40512013-12-19 10:14:15 -08007671 /* context is valid so caller is still waiting */
7672
7673 /* paranoia: invalidate the magic */
7674 pContext->magic = 0;
7675
7676 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007677 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007678
7679 /* serialization is complete */
7680 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007681}
7682
7683/**---------------------------------------------------------------------------
7684
7685 \brief hdd_wlan_exit() - HDD WLAN exit function
7686
7687 This is the driver exit point (invoked during rmmod)
7688
7689 \param - pHddCtx - Pointer to the HDD Context
7690
7691 \return - None
7692
7693 --------------------------------------------------------------------------*/
7694void hdd_wlan_exit(hdd_context_t *pHddCtx)
7695{
7696 eHalStatus halStatus;
7697 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7698 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307699 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007700 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007701 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007702 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307703 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007704
7705 ENTER();
7706
Jeff Johnson88ba7742013-02-27 14:36:02 -08007707 if (VOS_FTM_MODE != hdd_get_conparam())
7708 {
7709 // Unloading, restart logic is no more required.
7710 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007711
c_hpothu5ab05e92014-06-13 17:34:05 +05307712 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7713 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307715 pAdapter = pAdapterNode->pAdapter;
7716 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307718 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7719 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7720 {
7721 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7722 hdd_UnregisterWext(pAdapter->dev);
7723 }
7724 // Cancel any outstanding scan requests. We are about to close all
7725 // of our adapters, but an adapter structure is what SME passes back
7726 // to our callback function. Hence if there are any outstanding scan
7727 // requests then there is a race condition between when the adapter
7728 // is closed and when the callback is invoked.We try to resolve that
7729 // race condition here by canceling any outstanding scans before we
7730 // close the adapters.
7731 // Note that the scans may be cancelled in an asynchronous manner,
7732 // so ideally there needs to be some kind of synchronization. Rather
7733 // than introduce a new synchronization here, we will utilize the
7734 // fact that we are about to Request Full Power, and since that is
7735 // synchronized, the expectation is that by the time Request Full
7736 // Power has completed all scans will be cancelled.
7737 if (pHddCtx->scan_info.mScanPending)
7738 {
7739 hddLog(VOS_TRACE_LEVEL_INFO,
7740 FL("abort scan mode: %d sessionId: %d"),
7741 pAdapter->device_mode,
7742 pAdapter->sessionId);
7743 hdd_abort_mac_scan(pHddCtx,
7744 pAdapter->sessionId,
7745 eCSR_SCAN_ABORT_DEFAULT);
7746 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307748 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7749 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 }
7751 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307752 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007753 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307754 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007755 wlan_hdd_ftm_close(pHddCtx);
7756 goto free_hdd_ctx;
7757 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 /* DeRegister with platform driver as client for Suspend/Resume */
7760 vosStatus = hddDeregisterPmOps(pHddCtx);
7761 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7762 {
7763 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7764 VOS_ASSERT(0);
7765 }
7766
7767 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7768 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7769 {
7770 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7771 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007772
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007773 //Stop the traffic monitor timer
7774 if ( VOS_TIMER_STATE_RUNNING ==
7775 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7776 {
7777 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7778 }
7779
7780 // Destroy the traffic monitor timer
7781 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7782 &pHddCtx->tx_rx_trafficTmr)))
7783 {
7784 hddLog(VOS_TRACE_LEVEL_ERROR,
7785 "%s: Cannot deallocate Traffic monitor timer", __func__);
7786 }
7787
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 //Disable IMPS/BMPS as we do not want the device to enter any power
7789 //save mode during shutdown
7790 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7791 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7792 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7793
7794 //Ensure that device is in full power as we will touch H/W during vos_Stop
7795 init_completion(&powerContext.completion);
7796 powerContext.magic = POWER_CONTEXT_MAGIC;
7797
7798 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7799 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7800
7801 if (eHAL_STATUS_SUCCESS != halStatus)
7802 {
7803 if (eHAL_STATUS_PMC_PENDING == halStatus)
7804 {
7805 /* request was sent -- wait for the response */
7806 lrc = wait_for_completion_interruptible_timeout(
7807 &powerContext.completion,
7808 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 if (lrc <= 0)
7810 {
7811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007812 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 }
7814 }
7815 else
7816 {
7817 hddLog(VOS_TRACE_LEVEL_ERROR,
7818 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007819 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 /* continue -- need to clean up as much as possible */
7821 }
7822 }
7823
Jeff Johnson72a40512013-12-19 10:14:15 -08007824 /* either we never sent a request, we sent a request and received a
7825 response or we sent a request and timed out. if we never sent a
7826 request or if we sent a request and got a response, we want to
7827 clear the magic out of paranoia. if we timed out there is a
7828 race condition such that the callback function could be
7829 executing at the same time we are. of primary concern is if the
7830 callback function had already verified the "magic" but had not
7831 yet set the completion variable when a timeout occurred. we
7832 serialize these activities by invalidating the magic while
7833 holding a shared spinlock which will cause us to block if the
7834 callback is currently executing */
7835 spin_lock(&hdd_context_lock);
7836 powerContext.magic = 0;
7837 spin_unlock(&hdd_context_lock);
7838
Yue Ma0d4891e2013-08-06 17:01:45 -07007839 hdd_debugfs_exit(pHddCtx);
7840
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 // Unregister the Net Device Notifier
7842 unregister_netdevice_notifier(&hdd_netdev_notifier);
7843
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 hdd_stop_all_adapters( pHddCtx );
7845
Jeff Johnson295189b2012-06-20 16:38:30 -07007846#ifdef WLAN_BTAMP_FEATURE
7847 vosStatus = WLANBAP_Stop(pVosContext);
7848 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7849 {
7850 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7851 "%s: Failed to stop BAP",__func__);
7852 }
7853#endif //WLAN_BTAMP_FEATURE
7854
7855 //Stop all the modules
7856 vosStatus = vos_stop( pVosContext );
7857 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7858 {
7859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7860 "%s: Failed to stop VOSS",__func__);
7861 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7862 }
7863
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 //Assert Deep sleep signal now to put Libra HW in lowest power state
7865 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7866 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7867
7868 //Vote off any PMIC voltage supplies
7869 vos_chipPowerDown(NULL, NULL, NULL);
7870
7871 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7872
Leo Chang59cdc7e2013-07-10 10:08:21 -07007873
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007875 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007876
7877 //Close the scheduler before calling vos_close to make sure no thread is
7878 // scheduled after the each module close is called i.e after all the data
7879 // structures are freed.
7880 vosStatus = vos_sched_close( pVosContext );
7881 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7882 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7883 "%s: Failed to close VOSS Scheduler",__func__);
7884 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7885 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007886#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007887#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7888 /* Destroy the wake lock */
7889 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7890#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007891 /* Destroy the wake lock */
7892 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007893#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007894
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307895#ifdef CONFIG_ENABLE_LINUX_REG
7896 vosStatus = vos_nv_close();
7897 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7898 {
7899 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7900 "%s: Failed to close NV", __func__);
7901 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7902 }
7903#endif
7904
Jeff Johnson295189b2012-06-20 16:38:30 -07007905 //Close VOSS
7906 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7907 vos_close(pVosContext);
7908
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 //Close Watchdog
7910 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7911 vos_watchdog_close(pVosContext);
7912
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307913 //Clean up HDD Nlink Service
7914 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307915
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307916#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307917 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307918 {
7919 wlan_logging_sock_deactivate_svc();
7920 }
7921#endif
7922
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05307923#ifdef WLAN_KD_READY_NOTIFIER
7924 nl_srv_exit(pHddCtx->ptt_pid);
7925#else
7926 nl_srv_exit();
7927#endif /* WLAN_KD_READY_NOTIFIER */
7928
7929
Jeff Johnson295189b2012-06-20 16:38:30 -07007930 /* Cancel the vote for XO Core ON.
7931 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7932 * exited at this point
7933 */
7934 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007935 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7937 {
7938 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7939 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007940 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 }
7942
7943 hdd_close_all_adapters( pHddCtx );
7944
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 /* free the power on lock from platform driver */
7946 if (free_riva_power_on_lock("wlan"))
7947 {
7948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7949 __func__);
7950 }
7951
Jeff Johnson88ba7742013-02-27 14:36:02 -08007952free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307953
7954 //Free up dynamically allocated members inside HDD Adapter
7955 if (pHddCtx->cfg_ini)
7956 {
7957 kfree(pHddCtx->cfg_ini);
7958 pHddCtx->cfg_ini= NULL;
7959 }
7960
Leo Changf04ddad2013-09-18 13:46:38 -07007961 /* FTM mode, WIPHY did not registered
7962 If un-register here, system crash will happen */
7963 if (VOS_FTM_MODE != hdd_get_conparam())
7964 {
7965 wiphy_unregister(wiphy) ;
7966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 if (hdd_is_ssr_required())
7969 {
7970 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007971 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 msleep(5000);
7973 }
7974 hdd_set_ssr_required (VOS_FALSE);
7975}
7976
7977
7978/**---------------------------------------------------------------------------
7979
7980 \brief hdd_update_config_from_nv() - Function to update the contents of
7981 the running configuration with parameters taken from NV storage
7982
7983 \param - pHddCtx - Pointer to the HDD global context
7984
7985 \return - VOS_STATUS_SUCCESS if successful
7986
7987 --------------------------------------------------------------------------*/
7988static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7989{
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 v_BOOL_t itemIsValid = VOS_FALSE;
7991 VOS_STATUS status;
7992 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7993 v_U8_t macLoop;
7994
7995 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7996 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7997 if(status != VOS_STATUS_SUCCESS)
7998 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007999 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008000 return VOS_STATUS_E_FAILURE;
8001 }
8002
8003 if (itemIsValid == VOS_TRUE)
8004 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008005 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8007 VOS_MAX_CONCURRENCY_PERSONA);
8008 if(status != VOS_STATUS_SUCCESS)
8009 {
8010 /* Get MAC from NV fail, not update CFG info
8011 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008012 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 return VOS_STATUS_E_FAILURE;
8014 }
8015
8016 /* If first MAC is not valid, treat all others are not valid
8017 * Then all MACs will be got from ini file */
8018 if(vos_is_macaddr_zero(&macFromNV[0]))
8019 {
8020 /* MAC address in NV file is not configured yet */
8021 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8022 return VOS_STATUS_E_INVAL;
8023 }
8024
8025 /* Get MAC address from NV, update CFG info */
8026 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8027 {
8028 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8029 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308030 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 /* This MAC is not valid, skip it
8032 * This MAC will be got from ini file */
8033 }
8034 else
8035 {
8036 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8037 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8038 VOS_MAC_ADDR_SIZE);
8039 }
8040 }
8041 }
8042 else
8043 {
8044 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8045 return VOS_STATUS_E_FAILURE;
8046 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008047
Jeff Johnson295189b2012-06-20 16:38:30 -07008048
8049 return VOS_STATUS_SUCCESS;
8050}
8051
8052/**---------------------------------------------------------------------------
8053
8054 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8055
8056 \param - pAdapter - Pointer to the HDD
8057
8058 \return - None
8059
8060 --------------------------------------------------------------------------*/
8061VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8062{
8063 eHalStatus halStatus;
8064 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308065 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008066
Jeff Johnson295189b2012-06-20 16:38:30 -07008067
8068 // Send ready indication to the HDD. This will kick off the MAC
8069 // into a 'running' state and should kick off an initial scan.
8070 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8071 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8072 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308073 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 "code %08d [x%08x]",__func__, halStatus, halStatus );
8075 return VOS_STATUS_E_FAILURE;
8076 }
8077
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308078 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8080 // And RIVA will crash
8081 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8082 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308083 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8084 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8085
8086
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 return VOS_STATUS_SUCCESS;
8088}
8089
Jeff Johnson295189b2012-06-20 16:38:30 -07008090/* wake lock APIs for HDD */
8091void hdd_prevent_suspend(void)
8092{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008093#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008094 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008095#else
8096 wcnss_prevent_suspend();
8097#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008098}
8099
8100void hdd_allow_suspend(void)
8101{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008102#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008104#else
8105 wcnss_allow_suspend();
8106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008107}
8108
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308109void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008110{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008111#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008112 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008113#else
8114 /* Do nothing as there is no API in wcnss for timeout*/
8115#endif
8116}
8117
Jeff Johnson295189b2012-06-20 16:38:30 -07008118/**---------------------------------------------------------------------------
8119
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008120 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8121 information between Host and Riva
8122
8123 This function gets reported version of FW
8124 It also finds the version of Riva headers used to compile the host
8125 It compares the above two and prints a warning if they are different
8126 It gets the SW and HW version string
8127 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8128 indicating the features they support through a bitmap
8129
8130 \param - pHddCtx - Pointer to HDD context
8131
8132 \return - void
8133
8134 --------------------------------------------------------------------------*/
8135
8136void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8137{
8138
8139 tSirVersionType versionCompiled;
8140 tSirVersionType versionReported;
8141 tSirVersionString versionString;
8142 tANI_U8 fwFeatCapsMsgSupported = 0;
8143 VOS_STATUS vstatus;
8144
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008145 memset(&versionCompiled, 0, sizeof(versionCompiled));
8146 memset(&versionReported, 0, sizeof(versionReported));
8147
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008148 /* retrieve and display WCNSS version information */
8149 do {
8150
8151 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8152 &versionCompiled);
8153 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8154 {
8155 hddLog(VOS_TRACE_LEVEL_FATAL,
8156 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008157 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008158 break;
8159 }
8160
8161 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8162 &versionReported);
8163 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8164 {
8165 hddLog(VOS_TRACE_LEVEL_FATAL,
8166 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008167 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008168 break;
8169 }
8170
8171 if ((versionCompiled.major != versionReported.major) ||
8172 (versionCompiled.minor != versionReported.minor) ||
8173 (versionCompiled.version != versionReported.version) ||
8174 (versionCompiled.revision != versionReported.revision))
8175 {
8176 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8177 "Host expected %u.%u.%u.%u\n",
8178 WLAN_MODULE_NAME,
8179 (int)versionReported.major,
8180 (int)versionReported.minor,
8181 (int)versionReported.version,
8182 (int)versionReported.revision,
8183 (int)versionCompiled.major,
8184 (int)versionCompiled.minor,
8185 (int)versionCompiled.version,
8186 (int)versionCompiled.revision);
8187 }
8188 else
8189 {
8190 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8191 WLAN_MODULE_NAME,
8192 (int)versionReported.major,
8193 (int)versionReported.minor,
8194 (int)versionReported.version,
8195 (int)versionReported.revision);
8196 }
8197
8198 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8199 versionString,
8200 sizeof(versionString));
8201 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8202 {
8203 hddLog(VOS_TRACE_LEVEL_FATAL,
8204 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008205 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008206 break;
8207 }
8208
8209 pr_info("%s: WCNSS software version %s\n",
8210 WLAN_MODULE_NAME, versionString);
8211
8212 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8213 versionString,
8214 sizeof(versionString));
8215 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8216 {
8217 hddLog(VOS_TRACE_LEVEL_FATAL,
8218 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008219 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008220 break;
8221 }
8222
8223 pr_info("%s: WCNSS hardware version %s\n",
8224 WLAN_MODULE_NAME, versionString);
8225
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008226 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8227 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008228 send the message only if it the riva is 1.1
8229 minor numbers for different riva branches:
8230 0 -> (1.0)Mainline Build
8231 1 -> (1.1)Mainline Build
8232 2->(1.04) Stability Build
8233 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008234 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008235 ((versionReported.minor>=1) && (versionReported.version>=1)))
8236 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8237 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008238
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008239 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008240 {
8241#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8242 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8243 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8244#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008245 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8246 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8247 {
8248 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8249 }
8250
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008251 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008252 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008253
8254 } while (0);
8255
8256}
8257
8258/**---------------------------------------------------------------------------
8259
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308260 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8261
8262 \param - pHddCtx - Pointer to the hdd context
8263
8264 \return - true if hardware supports 5GHz
8265
8266 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308267boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308268{
8269 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8270 * then hardware support 5Ghz.
8271 */
8272 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8273 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308275 return true;
8276 }
8277 else
8278 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308280 __func__);
8281 return false;
8282 }
8283}
8284
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308285/**---------------------------------------------------------------------------
8286
8287 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8288 generate function
8289
8290 This is generate the random mac address for WLAN interface
8291
8292 \param - pHddCtx - Pointer to HDD context
8293 idx - Start interface index to get auto
8294 generated mac addr.
8295 mac_addr - Mac address
8296
8297 \return - 0 for success, < 0 for failure
8298
8299 --------------------------------------------------------------------------*/
8300
8301static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8302 int idx, v_MACADDR_t mac_addr)
8303{
8304 int i;
8305 unsigned int serialno;
8306 serialno = wcnss_get_serial_number();
8307
8308 if (0 != serialno)
8309 {
8310 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8311 bytes of the serial number that can be used to generate
8312 the other 3 bytes of the MAC address. Mask off all but
8313 the lower 3 bytes (this will also make sure we don't
8314 overflow in the next step) */
8315 serialno &= 0x00FFFFFF;
8316
8317 /* we need a unique address for each session */
8318 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8319
8320 /* autogen other Mac addresses */
8321 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8322 {
8323 /* start with the entire default address */
8324 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8325 /* then replace the lower 3 bytes */
8326 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8327 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8328 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8329
8330 serialno++;
8331 hddLog(VOS_TRACE_LEVEL_ERROR,
8332 "%s: Derived Mac Addr: "
8333 MAC_ADDRESS_STR, __func__,
8334 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8335 }
8336
8337 }
8338 else
8339 {
8340 hddLog(LOGE, FL("Failed to Get Serial NO"));
8341 return -1;
8342 }
8343 return 0;
8344}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308345
8346/**---------------------------------------------------------------------------
8347
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308348 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8349 completed to flush out the scan results
8350
8351 11d scan is done during driver load and is a passive scan on all
8352 channels supported by the device, 11d scans may find some APs on
8353 frequencies which are forbidden to be used in the regulatory domain
8354 the device is operating in. If these APs are notified to the supplicant
8355 it may try to connect to these APs, thus flush out all the scan results
8356 which are present in SME after 11d scan is done.
8357
8358 \return - eHalStatus
8359
8360 --------------------------------------------------------------------------*/
8361static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8362 tANI_U32 scanId, eCsrScanStatus status)
8363{
8364 ENTER();
8365
8366 sme_ScanFlushResult(halHandle, 0);
8367
8368 EXIT();
8369
8370 return eHAL_STATUS_SUCCESS;
8371}
8372
8373/**---------------------------------------------------------------------------
8374
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 \brief hdd_wlan_startup() - HDD init function
8376
8377 This is the driver startup code executed once a WLAN device has been detected
8378
8379 \param - dev - Pointer to the underlying device
8380
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008381 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008382
8383 --------------------------------------------------------------------------*/
8384
8385int hdd_wlan_startup(struct device *dev )
8386{
8387 VOS_STATUS status;
8388 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008389 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 hdd_context_t *pHddCtx = NULL;
8391 v_CONTEXT_t pVosContext= NULL;
8392#ifdef WLAN_BTAMP_FEATURE
8393 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8394 WLANBAP_ConfigType btAmpConfig;
8395 hdd_config_t *pConfig;
8396#endif
8397 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308399 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008400
8401 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 /*
8403 * cfg80211: wiphy allocation
8404 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308405 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008406
8407 if(wiphy == NULL)
8408 {
8409 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008410 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 }
8412
8413 pHddCtx = wiphy_priv(wiphy);
8414
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 //Initialize the adapter context to zeros.
8416 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8417
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308420 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008421
8422 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8423
8424 /*Get vos context here bcoz vos_open requires it*/
8425 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8426
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008427 if(pVosContext == NULL)
8428 {
8429 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8430 goto err_free_hdd_context;
8431 }
8432
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 //Save the Global VOSS context in adapter context for future.
8434 pHddCtx->pvosContext = pVosContext;
8435
8436 //Save the adapter context in global context for future.
8437 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8438
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 pHddCtx->parent_dev = dev;
8440
8441 init_completion(&pHddCtx->full_pwr_comp_var);
8442 init_completion(&pHddCtx->standby_comp_var);
8443 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008444 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008445 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308446 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308447 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008448
8449#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008450 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008451#else
8452 init_completion(&pHddCtx->driver_crda_req);
8453#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008454
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308455 spin_lock_init(&pHddCtx->schedScan_lock);
8456
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8458
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308459#ifdef FEATURE_WLAN_TDLS
8460 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8461 * invoked by other instances also) to protect the concurrent
8462 * access for the Adapters by TDLS module.
8463 */
8464 mutex_init(&pHddCtx->tdls_lock);
8465#endif
Agarwal Ashish1f422872014-07-22 00:11:55 +05308466 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308467
Agarwal Ashish1f422872014-07-22 00:11:55 +05308468 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 // Load all config first as TL config is needed during vos_open
8470 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8471 if(pHddCtx->cfg_ini == NULL)
8472 {
8473 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8474 goto err_free_hdd_context;
8475 }
8476
8477 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8478
8479 // Read and parse the qcom_cfg.ini file
8480 status = hdd_parse_config_ini( pHddCtx );
8481 if ( VOS_STATUS_SUCCESS != status )
8482 {
8483 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8484 __func__, WLAN_INI_FILE);
8485 goto err_config;
8486 }
Arif Hussaind5218912013-12-05 01:10:55 -08008487#ifdef MEMORY_DEBUG
8488 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8489 vos_mem_init();
8490
8491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8492 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8493#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008494
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308495 /* INI has been read, initialise the configuredMcastBcastFilter with
8496 * INI value as this will serve as the default value
8497 */
8498 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8499 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8500 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308501
8502 if (false == hdd_is_5g_supported(pHddCtx))
8503 {
8504 //5Ghz is not supported.
8505 if (1 != pHddCtx->cfg_ini->nBandCapability)
8506 {
8507 hddLog(VOS_TRACE_LEVEL_INFO,
8508 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8509 pHddCtx->cfg_ini->nBandCapability = 1;
8510 }
8511 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308512
8513 /* If SNR Monitoring is enabled, FW has to parse all beacons
8514 * for calcaluting and storing the average SNR, so set Nth beacon
8515 * filter to 1 to enable FW to parse all the beaocons
8516 */
8517 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8518 {
8519 /* The log level is deliberately set to WARN as overriding
8520 * nthBeaconFilter to 1 will increase power cosumption and this
8521 * might just prove helpful to detect the power issue.
8522 */
8523 hddLog(VOS_TRACE_LEVEL_WARN,
8524 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8525 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308528 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008529 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008530 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008532 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8533 {
8534 hddLog(VOS_TRACE_LEVEL_FATAL,
8535 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8536 goto err_config;
8537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008539
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008540 // Update VOS trace levels based upon the cfg.ini
8541 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8542 pHddCtx->cfg_ini->vosTraceEnableBAP);
8543 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8544 pHddCtx->cfg_ini->vosTraceEnableTL);
8545 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8546 pHddCtx->cfg_ini->vosTraceEnableWDI);
8547 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8548 pHddCtx->cfg_ini->vosTraceEnableHDD);
8549 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8550 pHddCtx->cfg_ini->vosTraceEnableSME);
8551 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8552 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308553 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8554 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008555 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8556 pHddCtx->cfg_ini->vosTraceEnableWDA);
8557 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8558 pHddCtx->cfg_ini->vosTraceEnableSYS);
8559 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8560 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008561 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8562 pHddCtx->cfg_ini->vosTraceEnableSAP);
8563 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8564 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008565
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 // Update WDI trace levels based upon the cfg.ini
8567 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8568 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8569 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8570 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8571 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8572 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8573 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8574 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008575
Jeff Johnson88ba7742013-02-27 14:36:02 -08008576 if (VOS_FTM_MODE == hdd_get_conparam())
8577 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8579 {
8580 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8581 goto err_free_hdd_context;
8582 }
8583 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308584
8585 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008587 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008588
Jeff Johnson88ba7742013-02-27 14:36:02 -08008589 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8591 {
8592 status = vos_watchdog_open(pVosContext,
8593 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8594
8595 if(!VOS_IS_STATUS_SUCCESS( status ))
8596 {
8597 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308598 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 }
8600 }
8601
8602 pHddCtx->isLogpInProgress = FALSE;
8603 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8604
Jeff Johnson295189b2012-06-20 16:38:30 -07008605 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8606 if(!VOS_IS_STATUS_SUCCESS(status))
8607 {
8608 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 }
8611
Amar Singhala49cbc52013-10-08 18:37:44 -07008612#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008613 /* initialize the NV module. This is required so that
8614 we can initialize the channel information in wiphy
8615 from the NV.bin data. The channel information in
8616 wiphy needs to be initialized before wiphy registration */
8617
8618 status = vos_nv_open();
8619 if (!VOS_IS_STATUS_SUCCESS(status))
8620 {
8621 /* NV module cannot be initialized */
8622 hddLog( VOS_TRACE_LEVEL_FATAL,
8623 "%s: vos_nv_open failed", __func__);
8624 goto err_clkvote;
8625 }
8626
8627 status = vos_init_wiphy_from_nv_bin();
8628 if (!VOS_IS_STATUS_SUCCESS(status))
8629 {
8630 /* NV module cannot be initialized */
8631 hddLog( VOS_TRACE_LEVEL_FATAL,
8632 "%s: vos_init_wiphy failed", __func__);
8633 goto err_vos_nv_close;
8634 }
8635
Amar Singhala49cbc52013-10-08 18:37:44 -07008636#endif
8637
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308638 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 if ( !VOS_IS_STATUS_SUCCESS( status ))
8640 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008641 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308642 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 }
8644
Jeff Johnson295189b2012-06-20 16:38:30 -07008645 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8646
8647 if ( NULL == pHddCtx->hHal )
8648 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008649 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008650 goto err_vosclose;
8651 }
8652
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008653 status = vos_preStart( pHddCtx->pvosContext );
8654 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8655 {
8656 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308657 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008658 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008659
Arif Hussaineaf68602013-12-30 23:10:44 -08008660 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8661 {
8662 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8663 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8664 __func__, enable_dfs_chan_scan);
8665 }
8666 if (0 == enable_11d || 1 == enable_11d)
8667 {
8668 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8669 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8670 __func__, enable_11d);
8671 }
8672
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008673 /* Note that the vos_preStart() sequence triggers the cfg download.
8674 The cfg download must occur before we update the SME config
8675 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 status = hdd_set_sme_config( pHddCtx );
8677
8678 if ( VOS_STATUS_SUCCESS != status )
8679 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008680 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308681 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008683
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 /* In the integrated architecture we update the configuration from
8685 the INI file and from NV before vOSS has been started so that
8686 the final contents are available to send down to the cCPU */
8687
8688 // Apply the cfg.ini to cfg.dat
8689 if (FALSE == hdd_update_config_dat(pHddCtx))
8690 {
8691 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308692 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 }
8694
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308695 // Get mac addr from platform driver
8696 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8697
8698 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308700 /* Store the mac addr for first interface */
8701 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8702
8703 hddLog(VOS_TRACE_LEVEL_ERROR,
8704 "%s: WLAN Mac Addr: "
8705 MAC_ADDRESS_STR, __func__,
8706 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8707
8708 /* Here, passing Arg2 as 1 because we do not want to change the
8709 last 3 bytes (means non OUI bytes) of first interface mac
8710 addr.
8711 */
8712 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8713 {
8714 hddLog(VOS_TRACE_LEVEL_ERROR,
8715 "%s: Failed to generate wlan interface mac addr "
8716 "using MAC from ini file ", __func__);
8717 }
8718 }
8719 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8720 {
8721 // Apply the NV to cfg.dat
8722 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008723#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8724 /* There was not a valid set of MAC Addresses in NV. See if the
8725 default addresses were modified by the cfg.ini settings. If so,
8726 we'll use them, but if not, we'll autogenerate a set of MAC
8727 addresses based upon the device serial number */
8728
8729 static const v_MACADDR_t default_address =
8730 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008731
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308732 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8733 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 {
8735 /* cfg.ini has the default address, invoke autogen logic */
8736
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308737 /* Here, passing Arg2 as 0 because we want to change the
8738 last 3 bytes (means non OUI bytes) of all the interfaces
8739 mac addr.
8740 */
8741 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8742 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308744 hddLog(VOS_TRACE_LEVEL_ERROR,
8745 "%s: Failed to generate wlan interface mac addr "
8746 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8747 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 }
8750 else
8751#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8752 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008753 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 "%s: Invalid MAC address in NV, using MAC from ini file "
8755 MAC_ADDRESS_STR, __func__,
8756 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8757 }
8758 }
8759 {
8760 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308761
8762 /* Set the MAC Address Currently this is used by HAL to
8763 * add self sta. Remove this once self sta is added as
8764 * part of session open.
8765 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8767 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8768 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308769
Jeff Johnson295189b2012-06-20 16:38:30 -07008770 if (!HAL_STATUS_SUCCESS( halStatus ))
8771 {
8772 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8773 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308774 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 }
8776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008777
8778 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8779 Note: Firmware image will be read and downloaded inside vos_start API */
8780 status = vos_start( pHddCtx->pvosContext );
8781 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8782 {
8783 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308784 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 }
8786
Leo Chang6cec3e22014-01-21 15:33:49 -08008787#ifdef FEATURE_WLAN_CH_AVOID
8788 /* Plug in avoid channel notification callback
8789 * This should happen before ADD_SELF_STA
8790 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308791
8792 /* check the Channel Avoidance is enabled */
8793 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8794 {
8795 sme_AddChAvoidCallback(pHddCtx->hHal,
8796 hdd_hostapd_ch_avoid_cb);
8797 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008798#endif /* FEATURE_WLAN_CH_AVOID */
8799
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008800 /* Exchange capability info between Host and FW and also get versioning info from FW */
8801 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008802
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308803#ifdef CONFIG_ENABLE_LINUX_REG
8804 status = wlan_hdd_init_channels(pHddCtx);
8805 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8806 {
8807 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8808 __func__);
8809 goto err_vosstop;
8810 }
8811#endif
8812
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 status = hdd_post_voss_start_config( pHddCtx );
8814 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8815 {
8816 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8817 __func__);
8818 goto err_vosstop;
8819 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008820
8821#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308822 wlan_hdd_cfg80211_update_reg_info( wiphy );
8823
8824 /* registration of wiphy dev with cfg80211 */
8825 if (0 > wlan_hdd_cfg80211_register(wiphy))
8826 {
8827 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8828 goto err_vosstop;
8829 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008831
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308832#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308833 /* registration of wiphy dev with cfg80211 */
8834 if (0 > wlan_hdd_cfg80211_register(wiphy))
8835 {
8836 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8837 goto err_vosstop;
8838 }
8839
8840 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8841 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8842 {
8843 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8844 __func__);
8845 goto err_unregister_wiphy;
8846 }
8847#endif
8848
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8850 {
8851 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8852 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8853 }
8854 else
8855 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008856 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8857 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8858 if (pAdapter != NULL)
8859 {
kaidde69982014-06-18 13:23:21 +08008860 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308862 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8863 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8864 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008865
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308866 /* Generate the P2P Device Address. This consists of the device's
8867 * primary MAC address with the locally administered bit set.
8868 */
8869 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008870 }
8871 else
8872 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308873 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8874 if (p2p_dev_addr != NULL)
8875 {
8876 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8877 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8878 }
8879 else
8880 {
8881 hddLog(VOS_TRACE_LEVEL_FATAL,
8882 "%s: Failed to allocate mac_address for p2p_device",
8883 __func__);
8884 goto err_close_adapter;
8885 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008887
8888 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8889 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8890 if ( NULL == pP2pAdapter )
8891 {
8892 hddLog(VOS_TRACE_LEVEL_FATAL,
8893 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008894 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008895 goto err_close_adapter;
8896 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008897 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008898 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008899
8900 if( pAdapter == NULL )
8901 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8903 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008905
Arif Hussain66559122013-11-21 10:11:40 -08008906 if (country_code)
8907 {
8908 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008909 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008910 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8911#ifndef CONFIG_ENABLE_LINUX_REG
8912 hdd_checkandupdate_phymode(pAdapter, country_code);
8913#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008914 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8915 (void *)(tSmeChangeCountryCallback)
8916 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008917 country_code,
8918 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308919 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008920 if (eHAL_STATUS_SUCCESS == ret)
8921 {
Arif Hussaincb607082013-12-20 11:57:42 -08008922 ret = wait_for_completion_interruptible_timeout(
8923 &pAdapter->change_country_code,
8924 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8925
8926 if (0 >= ret)
8927 {
8928 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8929 "%s: SME while setting country code timed out", __func__);
8930 }
Arif Hussain66559122013-11-21 10:11:40 -08008931 }
8932 else
8933 {
Arif Hussaincb607082013-12-20 11:57:42 -08008934 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8935 "%s: SME Change Country code from module param fail ret=%d",
8936 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008937 }
8938 }
8939
Jeff Johnson295189b2012-06-20 16:38:30 -07008940#ifdef WLAN_BTAMP_FEATURE
8941 vStatus = WLANBAP_Open(pVosContext);
8942 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8943 {
8944 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8945 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008946 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 }
8948
8949 vStatus = BSL_Init(pVosContext);
8950 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8951 {
8952 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8953 "%s: Failed to Init BSL",__func__);
8954 goto err_bap_close;
8955 }
8956 vStatus = WLANBAP_Start(pVosContext);
8957 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8958 {
8959 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8960 "%s: Failed to start TL",__func__);
8961 goto err_bap_close;
8962 }
8963
8964 pConfig = pHddCtx->cfg_ini;
8965 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8966 status = WLANBAP_SetConfig(&btAmpConfig);
8967
8968#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008969
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008970#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8971 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8972 {
8973 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8974 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8975 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8976 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8977 }
8978#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008979
Agarwal Ashish4b87f922014-06-18 03:03:21 +05308980 wlan_hdd_tdls_init(pHddCtx);
8981
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308982 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8983
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 /* Register with platform driver as client for Suspend/Resume */
8985 status = hddRegisterPmOps(pHddCtx);
8986 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8987 {
8988 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8989#ifdef WLAN_BTAMP_FEATURE
8990 goto err_bap_stop;
8991#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008992 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008993#endif //WLAN_BTAMP_FEATURE
8994 }
8995
Yue Ma0d4891e2013-08-06 17:01:45 -07008996 /* Open debugfs interface */
8997 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8998 {
8999 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9000 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009001 }
9002
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 /* Register TM level change handler function to the platform */
9004 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9005 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9006 {
9007 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9008 goto err_unregister_pmops;
9009 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009010
9011 /* register for riva power on lock to platform driver */
9012 if (req_riva_power_on_lock("wlan"))
9013 {
9014 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9015 __func__);
9016 goto err_unregister_pmops;
9017 }
9018
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 // register net device notifier for device change notification
9020 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9021
9022 if(ret < 0)
9023 {
9024 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9025 goto err_free_power_on_lock;
9026 }
9027
9028 //Initialize the nlink service
9029 if(nl_srv_init() != 0)
9030 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 goto err_reg_netdev;
9033 }
9034
Leo Chang4ce1cc52013-10-21 18:27:15 -07009035#ifdef WLAN_KD_READY_NOTIFIER
9036 pHddCtx->kd_nl_init = 1;
9037#endif /* WLAN_KD_READY_NOTIFIER */
9038
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 //Initialize the BTC service
9040 if(btc_activate_service(pHddCtx) != 0)
9041 {
9042 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9043 goto err_nl_srv;
9044 }
9045
9046#ifdef PTT_SOCK_SVC_ENABLE
9047 //Initialize the PTT service
9048 if(ptt_sock_activate_svc(pHddCtx) != 0)
9049 {
9050 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9051 goto err_nl_srv;
9052 }
9053#endif
9054
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309055#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9056 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9057 {
9058 if(wlan_logging_sock_activate_svc(
9059 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9060 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9061 {
9062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9063 " failed", __func__);
9064 goto err_nl_srv;
9065 }
9066 }
9067#endif
9068
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009070 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009071 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009072 /* Action frame registered in one adapter which will
9073 * applicable to all interfaces
9074 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309075 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009077
9078 mutex_init(&pHddCtx->sap_lock);
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009081#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009082#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9083 /* Initialize the wake lcok */
9084 wake_lock_init(&pHddCtx->rx_wake_lock,
9085 WAKE_LOCK_SUSPEND,
9086 "qcom_rx_wakelock");
9087#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009088 /* Initialize the wake lcok */
9089 wake_lock_init(&pHddCtx->sap_wake_lock,
9090 WAKE_LOCK_SUSPEND,
9091 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009092#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009093
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009094 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9095 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009096
Katya Nigam5c306ea2014-06-19 15:39:54 +05309097 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9099 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309100
9101#ifdef FEATURE_WLAN_SCAN_PNO
9102 /*SME must send channel update configuration to RIVA*/
9103 sme_UpdateChannelConfig(pHddCtx->hHal);
9104#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309105 /* Send the update default channel list to the FW*/
9106 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309107#ifndef CONFIG_ENABLE_LINUX_REG
9108 /*updating wiphy so that regulatory user hints can be processed*/
9109 if (wiphy)
9110 {
9111 regulatory_hint(wiphy, "00");
9112 }
9113#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009114 // Initialize the restart logic
9115 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309116
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009117 //Register the traffic monitor timer now
9118 if ( pHddCtx->cfg_ini->dynSplitscan)
9119 {
9120 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9121 VOS_TIMER_TYPE_SW,
9122 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9123 (void *)pHddCtx);
9124 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309125#ifdef WLAN_FEATURE_EXTSCAN
9126 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9127 wlan_hdd_cfg80211_extscan_callback,
9128 pHddCtx);
9129#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 goto success;
9131
9132err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009133#ifdef WLAN_KD_READY_NOTIFIER
9134 nl_srv_exit(pHddCtx->ptt_pid);
9135#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009137#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009138err_reg_netdev:
9139 unregister_netdevice_notifier(&hdd_netdev_notifier);
9140
9141err_free_power_on_lock:
9142 free_riva_power_on_lock("wlan");
9143
9144err_unregister_pmops:
9145 hddDevTmUnregisterNotifyCallback(pHddCtx);
9146 hddDeregisterPmOps(pHddCtx);
9147
Yue Ma0d4891e2013-08-06 17:01:45 -07009148 hdd_debugfs_exit(pHddCtx);
9149
Jeff Johnson295189b2012-06-20 16:38:30 -07009150#ifdef WLAN_BTAMP_FEATURE
9151err_bap_stop:
9152 WLANBAP_Stop(pVosContext);
9153#endif
9154
9155#ifdef WLAN_BTAMP_FEATURE
9156err_bap_close:
9157 WLANBAP_Close(pVosContext);
9158#endif
9159
Jeff Johnson295189b2012-06-20 16:38:30 -07009160err_close_adapter:
9161 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309162#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309163err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309164#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309165 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009166err_vosstop:
9167 vos_stop(pVosContext);
9168
Amar Singhala49cbc52013-10-08 18:37:44 -07009169err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 status = vos_sched_close( pVosContext );
9171 if (!VOS_IS_STATUS_SUCCESS(status)) {
9172 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9173 "%s: Failed to close VOSS Scheduler", __func__);
9174 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9175 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009176 vos_close(pVosContext );
9177
Amar Singhal0a402232013-10-11 20:57:16 -07009178err_vos_nv_close:
9179
c_hpothue6a36282014-03-19 12:27:38 +05309180#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009181 vos_nv_close();
9182
Jeff Johnson295189b2012-06-20 16:38:30 -07009183err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309184#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009185 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009186
9187err_wdclose:
9188 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9189 vos_watchdog_close(pVosContext);
9190
Jeff Johnson295189b2012-06-20 16:38:30 -07009191err_config:
9192 kfree(pHddCtx->cfg_ini);
9193 pHddCtx->cfg_ini= NULL;
9194
9195err_free_hdd_context:
9196 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 wiphy_free(wiphy) ;
9198 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 VOS_BUG(1);
9200
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009201 if (hdd_is_ssr_required())
9202 {
9203 /* WDI timeout had happened during load, so SSR is needed here */
9204 subsystem_restart("wcnss");
9205 msleep(5000);
9206 }
9207 hdd_set_ssr_required (VOS_FALSE);
9208
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009209 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009210
9211success:
9212 EXIT();
9213 return 0;
9214}
9215
9216/**---------------------------------------------------------------------------
9217
Jeff Johnson32d95a32012-09-10 13:15:23 -07009218 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009219
Jeff Johnson32d95a32012-09-10 13:15:23 -07009220 This is the driver entry point - called in different timeline depending
9221 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009222
9223 \param - None
9224
9225 \return - 0 for success, non zero for failure
9226
9227 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009228static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009229{
9230 VOS_STATUS status;
9231 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 struct device *dev = NULL;
9233 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009234#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9235 int max_retries = 0;
9236#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009237
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309238#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9239 wlan_logging_sock_init_svc();
9240#endif
9241
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 ENTER();
9243
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009244#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009246#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009247
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309248 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9250 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9251
9252 //Power Up Libra WLAN card first if not already powered up
9253 status = vos_chipPowerUp(NULL,NULL,NULL);
9254 if (!VOS_IS_STATUS_SUCCESS(status))
9255 {
9256 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9257 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309258#ifdef WLAN_OPEN_SOURCE
9259 wake_lock_destroy(&wlan_wake_lock);
9260#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309261
9262#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9263 wlan_logging_sock_deinit_svc();
9264#endif
9265
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009266 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 }
9268
Jeff Johnson295189b2012-06-20 16:38:30 -07009269#ifdef ANI_BUS_TYPE_PCI
9270
9271 dev = wcnss_wlan_get_device();
9272
9273#endif // ANI_BUS_TYPE_PCI
9274
9275#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009276
9277#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9278 /* wait until WCNSS driver downloads NV */
9279 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9280 msleep(1000);
9281 }
9282 if (max_retries >= 5) {
9283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309284#ifdef WLAN_OPEN_SOURCE
9285 wake_lock_destroy(&wlan_wake_lock);
9286#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309287
9288#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9289 wlan_logging_sock_deinit_svc();
9290#endif
9291
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009292 return -ENODEV;
9293 }
9294#endif
9295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 dev = wcnss_wlan_get_device();
9297#endif // ANI_BUS_TYPE_PLATFORM
9298
9299
9300 do {
9301 if (NULL == dev) {
9302 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9303 ret_status = -1;
9304 break;
9305 }
9306
Jeff Johnson295189b2012-06-20 16:38:30 -07009307#ifdef TIMER_MANAGER
9308 vos_timer_manager_init();
9309#endif
9310
9311 /* Preopen VOSS so that it is ready to start at least SAL */
9312 status = vos_preOpen(&pVosContext);
9313
9314 if (!VOS_IS_STATUS_SUCCESS(status))
9315 {
9316 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9317 ret_status = -1;
9318 break;
9319 }
9320
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009321#ifndef MODULE
9322 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9323 */
9324 hdd_set_conparam((v_UINT_t)con_mode);
9325#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009326
9327 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009328 if (hdd_wlan_startup(dev))
9329 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009331 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 vos_preClose( &pVosContext );
9333 ret_status = -1;
9334 break;
9335 }
9336
9337 /* Cancel the vote for XO Core ON
9338 * This is done here for safety purposes in case we re-initialize without turning
9339 * it OFF in any error scenario.
9340 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009341 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009343 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9345 {
9346 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009347 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 }
9349 } while (0);
9350
9351 if (0 != ret_status)
9352 {
9353 //Assert Deep sleep signal now to put Libra HW in lowest power state
9354 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9355 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9356
9357 //Vote off any PMIC voltage supplies
9358 vos_chipPowerDown(NULL, NULL, NULL);
9359#ifdef TIMER_MANAGER
9360 vos_timer_exit();
9361#endif
9362#ifdef MEMORY_DEBUG
9363 vos_mem_exit();
9364#endif
9365
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009366#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009368#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309369
9370#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9371 wlan_logging_sock_deinit_svc();
9372#endif
9373
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9375 }
9376 else
9377 {
9378 //Send WLAN UP indication to Nlink Service
9379 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9380
9381 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 }
9383
9384 EXIT();
9385
9386 return ret_status;
9387}
9388
Jeff Johnson32d95a32012-09-10 13:15:23 -07009389/**---------------------------------------------------------------------------
9390
9391 \brief hdd_module_init() - Init Function
9392
9393 This is the driver entry point (invoked when module is loaded using insmod)
9394
9395 \param - None
9396
9397 \return - 0 for success, non zero for failure
9398
9399 --------------------------------------------------------------------------*/
9400#ifdef MODULE
9401static int __init hdd_module_init ( void)
9402{
9403 return hdd_driver_init();
9404}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009405#else /* #ifdef MODULE */
9406static int __init hdd_module_init ( void)
9407{
9408 /* Driver initialization is delayed to fwpath_changed_handler */
9409 return 0;
9410}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009411#endif /* #ifdef MODULE */
9412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413
9414/**---------------------------------------------------------------------------
9415
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009416 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009417
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009418 This is the driver exit point (invoked when module is unloaded using rmmod
9419 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009420
9421 \param - None
9422
9423 \return - None
9424
9425 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009426static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009427{
9428 hdd_context_t *pHddCtx = NULL;
9429 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309430 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309431 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009432
9433 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9434
9435 //Get the global vos context
9436 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9437
9438 if(!pVosContext)
9439 {
9440 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9441 goto done;
9442 }
9443
9444 //Get the HDD context.
9445 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9446
9447 if(!pHddCtx)
9448 {
9449 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9450 }
9451 else
9452 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309453 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9454
9455 if (pHddCtx->isLogpInProgress)
9456 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309458 "%s:SSR in Progress; block rmmod !!!", __func__);
9459 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9460 msecs_to_jiffies(30000));
9461 if(!rc)
9462 {
9463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9464 "%s:SSR timedout, fatal error", __func__);
9465 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009466 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009468
Mihir Shete18156292014-03-11 15:38:30 +05309469 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9471
Agarwal Ashish8db39882014-07-30 21:56:07 +05309472 /* Driver Need to send country code 00 in below condition
9473 * 1) If gCountryCodePriority is set to 1; and last country
9474 * code set is through 11d. This needs to be done in case
9475 * when NV country code is 00.
9476 * This Needs to be done as when kernel store last country
9477 * code and if stored country code is not through 11d,
9478 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9479 * in next load/unload as soon as we get any country through
9480 * 11d. In sme_HandleChangeCountryCodeByUser
9481 * pMsg->countryCode will be last countryCode and
9482 * pMac->scan.countryCode11d will be country through 11d so
9483 * due to mismatch driver will disable 11d.
9484 *
9485 * 2) When NV country Code is non-zero ;
9486 * There are chances that kernel last country and default
9487 * country can be same. In this case if Driver doesn't pass 00 to
9488 * kernel, at the time of driver loading next timer, driver will not
9489 * call any hint to kernel as country is same. This can add 3 sec
9490 * delay in driver loading.
9491 */
9492
9493 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309494 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Agarwal Ashish8db39882014-07-30 21:56:07 +05309495 sme_Is11dSupported(pHddCtx->hHal)) || (vos_is_nv_country_non_zero() ))
Agarwal Ashish5e414792014-06-08 15:25:23 +05309496 {
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309497 hddLog(VOS_TRACE_LEVEL_INFO,
9498 FL("CountryCode 00 is being set while unloading driver"));
Agarwal Ashish5e414792014-06-08 15:25:23 +05309499 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9500 }
9501
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 //Do all the cleanup before deregistering the driver
9503 hdd_wlan_exit(pHddCtx);
9504 }
9505
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 vos_preClose( &pVosContext );
9507
9508#ifdef TIMER_MANAGER
9509 vos_timer_exit();
9510#endif
9511#ifdef MEMORY_DEBUG
9512 vos_mem_exit();
9513#endif
9514
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309515#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9516 wlan_logging_sock_deinit_svc();
9517#endif
9518
Jeff Johnson295189b2012-06-20 16:38:30 -07009519done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009520#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009522#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309523
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9525}
9526
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009527/**---------------------------------------------------------------------------
9528
9529 \brief hdd_module_exit() - Exit function
9530
9531 This is the driver exit point (invoked when module is unloaded using rmmod)
9532
9533 \param - None
9534
9535 \return - None
9536
9537 --------------------------------------------------------------------------*/
9538static void __exit hdd_module_exit(void)
9539{
9540 hdd_driver_exit();
9541}
9542
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009543#ifdef MODULE
9544static int fwpath_changed_handler(const char *kmessage,
9545 struct kernel_param *kp)
9546{
Jeff Johnson76052702013-04-16 13:55:05 -07009547 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009548}
9549
9550static int con_mode_handler(const char *kmessage,
9551 struct kernel_param *kp)
9552{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009553 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009554}
9555#else /* #ifdef MODULE */
9556/**---------------------------------------------------------------------------
9557
Jeff Johnson76052702013-04-16 13:55:05 -07009558 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009559
Jeff Johnson76052702013-04-16 13:55:05 -07009560 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009561 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009562 - invoked when module parameter fwpath is modified from userspace to signal
9563 initializing the WLAN driver or when con_mode is modified from userspace
9564 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009565
9566 \return - 0 for success, non zero for failure
9567
9568 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009569static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009570{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009571 int ret_status;
9572
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009573 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009574 ret_status = hdd_driver_init();
9575 wlan_hdd_inited = ret_status ? 0 : 1;
9576 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009577 }
9578
9579 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009580
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009581 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009582
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009583 ret_status = hdd_driver_init();
9584 wlan_hdd_inited = ret_status ? 0 : 1;
9585 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009586}
9587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588/**---------------------------------------------------------------------------
9589
Jeff Johnson76052702013-04-16 13:55:05 -07009590 \brief fwpath_changed_handler() - Handler Function
9591
9592 Handle changes to the fwpath parameter
9593
9594 \return - 0 for success, non zero for failure
9595
9596 --------------------------------------------------------------------------*/
9597static int fwpath_changed_handler(const char *kmessage,
9598 struct kernel_param *kp)
9599{
9600 int ret;
9601
9602 ret = param_set_copystring(kmessage, kp);
9603 if (0 == ret)
9604 ret = kickstart_driver();
9605 return ret;
9606}
9607
9608/**---------------------------------------------------------------------------
9609
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009610 \brief con_mode_handler() -
9611
9612 Handler function for module param con_mode when it is changed by userspace
9613 Dynamically linked - do nothing
9614 Statically linked - exit and init driver, as in rmmod and insmod
9615
Jeff Johnson76052702013-04-16 13:55:05 -07009616 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009617
Jeff Johnson76052702013-04-16 13:55:05 -07009618 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009619
9620 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009621static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009622{
Jeff Johnson76052702013-04-16 13:55:05 -07009623 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009624
Jeff Johnson76052702013-04-16 13:55:05 -07009625 ret = param_set_int(kmessage, kp);
9626 if (0 == ret)
9627 ret = kickstart_driver();
9628 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009629}
9630#endif /* #ifdef MODULE */
9631
9632/**---------------------------------------------------------------------------
9633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 \brief hdd_get_conparam() -
9635
9636 This is the driver exit point (invoked when module is unloaded using rmmod)
9637
9638 \param - None
9639
9640 \return - tVOS_CON_MODE
9641
9642 --------------------------------------------------------------------------*/
9643tVOS_CON_MODE hdd_get_conparam ( void )
9644{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009645#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009647#else
9648 return (tVOS_CON_MODE)curr_con_mode;
9649#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009650}
9651void hdd_set_conparam ( v_UINT_t newParam )
9652{
9653 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009654#ifndef MODULE
9655 curr_con_mode = con_mode;
9656#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009657}
9658/**---------------------------------------------------------------------------
9659
9660 \brief hdd_softap_sta_deauth() - function
9661
9662 This to take counter measure to handle deauth req from HDD
9663
9664 \param - pAdapter - Pointer to the HDD
9665
9666 \param - enable - boolean value
9667
9668 \return - None
9669
9670 --------------------------------------------------------------------------*/
9671
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009672VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009673{
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009675 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009676
9677 ENTER();
9678
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009679 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9680 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
9682 //Ignore request to deauth bcmc station
9683 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009684 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009685
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009686 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009687
9688 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009689 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009690}
9691
9692/**---------------------------------------------------------------------------
9693
9694 \brief hdd_softap_sta_disassoc() - function
9695
9696 This to take counter measure to handle deauth req from HDD
9697
9698 \param - pAdapter - Pointer to the HDD
9699
9700 \param - enable - boolean value
9701
9702 \return - None
9703
9704 --------------------------------------------------------------------------*/
9705
9706void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9707{
9708 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9709
9710 ENTER();
9711
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309712 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009713
9714 //Ignore request to disassoc bcmc station
9715 if( pDestMacAddress[0] & 0x1 )
9716 return;
9717
9718 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9719}
9720
9721void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9722{
9723 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9724
9725 ENTER();
9726
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309727 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009728
9729 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9730}
9731
Jeff Johnson295189b2012-06-20 16:38:30 -07009732/**---------------------------------------------------------------------------
9733 *
9734 * \brief hdd_get__concurrency_mode() -
9735 *
9736 *
9737 * \param - None
9738 *
9739 * \return - CONCURRENCY MODE
9740 *
9741 * --------------------------------------------------------------------------*/
9742tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9743{
9744 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9745 hdd_context_t *pHddCtx;
9746
9747 if (NULL != pVosContext)
9748 {
9749 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9750 if (NULL != pHddCtx)
9751 {
9752 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9753 }
9754 }
9755
9756 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009757 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 return VOS_STA;
9759}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309760v_BOOL_t
9761wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
9762{
9763 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009764
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309765 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
9766 if (pAdapter == NULL)
9767 {
9768 hddLog(VOS_TRACE_LEVEL_INFO,
9769 FL("GO doesn't exist"));
9770 return TRUE;
9771 }
9772 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9773 {
9774 hddLog(VOS_TRACE_LEVEL_INFO,
9775 FL("GO started"));
9776 return TRUE;
9777 }
9778 else
9779 /* wait till GO changes its interface to p2p device */
9780 hddLog(VOS_TRACE_LEVEL_INFO,
9781 FL("Del_bss called, avoid apps suspend"));
9782 return FALSE;
9783
9784}
Jeff Johnson295189b2012-06-20 16:38:30 -07009785/* Decide whether to allow/not the apps power collapse.
9786 * Allow apps power collapse if we are in connected state.
9787 * if not, allow only if we are in IMPS */
9788v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9789{
9790 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009791 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009792 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9794 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9795 hdd_adapter_t *pAdapter = NULL;
9796 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009797 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009798
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9800 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009801
Yathish9f22e662012-12-10 14:21:35 -08009802 concurrent_state = hdd_get_concurrency_mode();
9803
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309804 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
9805 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
9806 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -08009807#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309808
Yathish9f22e662012-12-10 14:21:35 -08009809 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309810 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -08009811 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9812 return TRUE;
9813#endif
9814
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 /*loop through all adapters. TBD fix for Concurrency */
9816 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9817 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9818 {
9819 pAdapter = pAdapterNode->pAdapter;
9820 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9821 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9822 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009823 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309824 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009825 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009826 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9827 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009829 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009830 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9831 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009832 return FALSE;
9833 }
9834 }
9835 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9836 pAdapterNode = pNext;
9837 }
9838 return TRUE;
9839}
9840
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009841/* Decides whether to send suspend notification to Riva
9842 * if any adapter is in BMPS; then it is required */
9843v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9844{
9845 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9846 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9847
9848 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9849 {
9850 return TRUE;
9851 }
9852 return FALSE;
9853}
9854
Jeff Johnson295189b2012-06-20 16:38:30 -07009855void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9856{
9857 switch(mode)
9858 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009859 case VOS_STA_MODE:
9860 case VOS_P2P_CLIENT_MODE:
9861 case VOS_P2P_GO_MODE:
9862 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009863 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309864 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 break;
9866 default:
9867 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309869 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9870 "Number of open sessions for mode %d = %d"),
9871 pHddCtx->concurrency_mode, mode,
9872 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009873}
9874
9875
9876void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9877{
9878 switch(mode)
9879 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009880 case VOS_STA_MODE:
9881 case VOS_P2P_CLIENT_MODE:
9882 case VOS_P2P_GO_MODE:
9883 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +05309884 pHddCtx->no_of_open_sessions[mode]--;
9885 if (!(pHddCtx->no_of_open_sessions[mode]))
9886 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 break;
9888 default:
9889 break;
9890 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309891 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9892 "Number of open sessions for mode %d = %d"),
9893 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
9894
9895}
9896/**---------------------------------------------------------------------------
9897 *
9898 * \brief wlan_hdd_incr_active_session()
9899 *
9900 * This function increments the number of active sessions
9901 * maintained per device mode
9902 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
9903 * Incase of SAP/P2P GO upon bss start it is incremented
9904 *
9905 * \param pHddCtx - HDD Context
9906 * \param mode - device mode
9907 *
9908 * \return - None
9909 *
9910 * --------------------------------------------------------------------------*/
9911void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9912{
9913 switch (mode) {
9914 case VOS_STA_MODE:
9915 case VOS_P2P_CLIENT_MODE:
9916 case VOS_P2P_GO_MODE:
9917 case VOS_STA_SAP_MODE:
9918 pHddCtx->no_of_active_sessions[mode]++;
9919 break;
9920 default:
9921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9922 break;
9923 }
9924 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9925 mode,
9926 pHddCtx->no_of_active_sessions[mode]);
9927}
9928
9929/**---------------------------------------------------------------------------
9930 *
9931 * \brief wlan_hdd_decr_active_session()
9932 *
9933 * This function decrements the number of active sessions
9934 * maintained per device mode
9935 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
9936 * Incase of SAP/P2P GO upon bss stop it is decremented
9937 *
9938 * \param pHddCtx - HDD Context
9939 * \param mode - device mode
9940 *
9941 * \return - None
9942 *
9943 * --------------------------------------------------------------------------*/
9944void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9945{
9946 switch (mode) {
9947 case VOS_STA_MODE:
9948 case VOS_P2P_CLIENT_MODE:
9949 case VOS_P2P_GO_MODE:
9950 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +05309951 if (pHddCtx->no_of_active_sessions[mode] > 0)
9952 pHddCtx->no_of_active_sessions[mode]--;
9953 else
9954 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
9955 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +05309956 break;
9957 default:
9958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9959 break;
9960 }
9961 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9962 mode,
9963 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009964}
9965
Jeff Johnsone7245742012-09-05 17:12:55 -07009966/**---------------------------------------------------------------------------
9967 *
9968 * \brief wlan_hdd_restart_init
9969 *
9970 * This function initalizes restart timer/flag. An internal function.
9971 *
9972 * \param - pHddCtx
9973 *
9974 * \return - None
9975 *
9976 * --------------------------------------------------------------------------*/
9977
9978static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9979{
9980 /* Initialize */
9981 pHddCtx->hdd_restart_retries = 0;
9982 atomic_set(&pHddCtx->isRestartInProgress, 0);
9983 vos_timer_init(&pHddCtx->hdd_restart_timer,
9984 VOS_TIMER_TYPE_SW,
9985 wlan_hdd_restart_timer_cb,
9986 pHddCtx);
9987}
9988/**---------------------------------------------------------------------------
9989 *
9990 * \brief wlan_hdd_restart_deinit
9991 *
9992 * This function cleans up the resources used. An internal function.
9993 *
9994 * \param - pHddCtx
9995 *
9996 * \return - None
9997 *
9998 * --------------------------------------------------------------------------*/
9999
10000static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10001{
10002
10003 VOS_STATUS vos_status;
10004 /* Block any further calls */
10005 atomic_set(&pHddCtx->isRestartInProgress, 1);
10006 /* Cleanup */
10007 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10008 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010009 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010010 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10011 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010012 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010013
10014}
10015
10016/**---------------------------------------------------------------------------
10017 *
10018 * \brief wlan_hdd_framework_restart
10019 *
10020 * This function uses a cfg80211 API to start a framework initiated WLAN
10021 * driver module unload/load.
10022 *
10023 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10024 *
10025 *
10026 * \param - pHddCtx
10027 *
10028 * \return - VOS_STATUS_SUCCESS: Success
10029 * VOS_STATUS_E_EMPTY: Adapter is Empty
10030 * VOS_STATUS_E_NOMEM: No memory
10031
10032 * --------------------------------------------------------------------------*/
10033
10034static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10035{
10036 VOS_STATUS status = VOS_STATUS_SUCCESS;
10037 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010038 int len = (sizeof (struct ieee80211_mgmt));
10039 struct ieee80211_mgmt *mgmt = NULL;
10040
10041 /* Prepare the DEAUTH managment frame with reason code */
10042 mgmt = kzalloc(len, GFP_KERNEL);
10043 if(mgmt == NULL)
10044 {
10045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10046 "%s: memory allocation failed (%d bytes)", __func__, len);
10047 return VOS_STATUS_E_NOMEM;
10048 }
10049 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010050
10051 /* Iterate over all adapters/devices */
10052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10053 do
10054 {
10055 if( (status == VOS_STATUS_SUCCESS) &&
10056 pAdapterNode &&
10057 pAdapterNode->pAdapter)
10058 {
10059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10060 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10061 pAdapterNode->pAdapter->dev->name,
10062 pAdapterNode->pAdapter->device_mode,
10063 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010064 /*
10065 * CFG80211 event to restart the driver
10066 *
10067 * 'cfg80211_send_unprot_deauth' sends a
10068 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10069 * of SME(Linux Kernel) state machine.
10070 *
10071 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10072 * the driver.
10073 *
10074 */
10075
10076 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010077 }
10078 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10079 pAdapterNode = pNext;
10080 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10081
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010082
10083 /* Free the allocated management frame */
10084 kfree(mgmt);
10085
Jeff Johnsone7245742012-09-05 17:12:55 -070010086 /* Retry until we unload or reach max count */
10087 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10088 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10089
10090 return status;
10091
10092}
10093/**---------------------------------------------------------------------------
10094 *
10095 * \brief wlan_hdd_restart_timer_cb
10096 *
10097 * Restart timer callback. An internal function.
10098 *
10099 * \param - User data:
10100 *
10101 * \return - None
10102 *
10103 * --------------------------------------------------------------------------*/
10104
10105void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10106{
10107 hdd_context_t *pHddCtx = usrDataForCallback;
10108 wlan_hdd_framework_restart(pHddCtx);
10109 return;
10110
10111}
10112
10113
10114/**---------------------------------------------------------------------------
10115 *
10116 * \brief wlan_hdd_restart_driver
10117 *
10118 * This function sends an event to supplicant to restart the WLAN driver.
10119 *
10120 * This function is called from vos_wlanRestart.
10121 *
10122 * \param - pHddCtx
10123 *
10124 * \return - VOS_STATUS_SUCCESS: Success
10125 * VOS_STATUS_E_EMPTY: Adapter is Empty
10126 * VOS_STATUS_E_ALREADY: Request already in progress
10127
10128 * --------------------------------------------------------------------------*/
10129VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10130{
10131 VOS_STATUS status = VOS_STATUS_SUCCESS;
10132
10133 /* A tight check to make sure reentrancy */
10134 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10135 {
Mihir Shetefd528652014-06-23 19:07:50 +053010136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010137 "%s: WLAN restart is already in progress", __func__);
10138
10139 return VOS_STATUS_E_ALREADY;
10140 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010141 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010142#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010143 wcnss_reset_intr();
10144#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010145
Jeff Johnsone7245742012-09-05 17:12:55 -070010146 return status;
10147}
10148
Mihir Shetee1093ba2014-01-21 20:13:32 +053010149/**---------------------------------------------------------------------------
10150 *
10151 * \brief wlan_hdd_init_channels
10152 *
10153 * This function is used to initialize the channel list in CSR
10154 *
10155 * This function is called from hdd_wlan_startup
10156 *
10157 * \param - pHddCtx: HDD context
10158 *
10159 * \return - VOS_STATUS_SUCCESS: Success
10160 * VOS_STATUS_E_FAULT: Failure reported by SME
10161
10162 * --------------------------------------------------------------------------*/
10163static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10164{
10165 eHalStatus status;
10166
10167 status = sme_InitChannels(pHddCtx->hHal);
10168 if (HAL_STATUS_SUCCESS(status))
10169 {
10170 return VOS_STATUS_SUCCESS;
10171 }
10172 else
10173 {
10174 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10175 __func__, status);
10176 return VOS_STATUS_E_FAULT;
10177 }
10178}
10179
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010180static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10181{
10182 eHalStatus status;
10183
10184 status = sme_InitChannelsForCC(pHddCtx->hHal);
10185 if (HAL_STATUS_SUCCESS(status))
10186 {
10187 return VOS_STATUS_SUCCESS;
10188 }
10189 else
10190 {
10191 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10192 __func__, status);
10193 return VOS_STATUS_E_FAULT;
10194 }
10195}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010196/*
10197 * API to find if there is any STA or P2P-Client is connected
10198 */
10199VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10200{
10201 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10202}
Jeff Johnsone7245742012-09-05 17:12:55 -070010203
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010204int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10205{
10206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10207 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010208 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010209
10210 pScanInfo = &pHddCtx->scan_info;
10211 if (pScanInfo->mScanPending)
10212 {
10213 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10214 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10215 eCSR_SCAN_ABORT_DEFAULT);
10216
10217 status = wait_for_completion_interruptible_timeout(
10218 &pScanInfo->abortscan_event_var,
10219 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010220 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010221 {
10222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010223 "%s: Timeout or Interrupt occurred while waiting for abort"
10224 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010225 return -ETIMEDOUT;
10226 }
10227 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010228 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010229}
10230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231//Register the module init/exit functions
10232module_init(hdd_module_init);
10233module_exit(hdd_module_exit);
10234
10235MODULE_LICENSE("Dual BSD/GPL");
10236MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10237MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10238
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010239module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10240 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010241
Jeff Johnson76052702013-04-16 13:55:05 -070010242module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010243 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010244
10245module_param(enable_dfs_chan_scan, int,
10246 S_IRUSR | S_IRGRP | S_IROTH);
10247
10248module_param(enable_11d, int,
10249 S_IRUSR | S_IRGRP | S_IROTH);
10250
10251module_param(country_code, charp,
10252 S_IRUSR | S_IRGRP | S_IROTH);