blob: caa0a2fd4f00ebbd7f4ee7c161c07ea85c200057 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
37 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
38
39 Qualcomm Confidential and Proprietary.
40
41 ========================================================================*/
42
43/**=========================================================================
44
45 EDIT HISTORY FOR FILE
46
47
48 This section contains comments describing changes made to the module.
49 Notice that changes are listed in reverse chronological order.
50
51
52 $Header:$ $DateTime: $ $Author: $
53
54
55 when who what, where, why
56 -------- --- --------------------------------------------------------
57 04/5/09 Shailender Created module.
58 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
59 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
60 ==========================================================================*/
61
62/*--------------------------------------------------------------------------
63 Include Files
64 ------------------------------------------------------------------------*/
65//#include <wlan_qct_driver.h>
66#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <vos_api.h>
68#include <vos_sched.h>
69#include <vos_power.h>
70#include <linux/etherdevice.h>
71#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070072#ifdef ANI_BUS_TYPE_PLATFORM
73#include <linux/wcnss_wlan.h>
74#endif //ANI_BUS_TYPE_PLATFORM
75#ifdef ANI_BUS_TYPE_PCI
76#include "wcnss_wlan.h"
77#endif /* ANI_BUS_TYPE_PCI */
78#include <wlan_hdd_tx_rx.h>
79#include <palTimer.h>
80#include <wniApi.h>
81#include <wlan_nlink_srv.h>
82#include <wlan_btc_svc.h>
83#include <wlan_hdd_cfg.h>
84#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053085#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070086#include <wlan_hdd_wowl.h>
87#include <wlan_hdd_misc.h>
88#include <wlan_hdd_wext.h>
89#ifdef WLAN_BTAMP_FEATURE
90#include <bap_hdd_main.h>
91#include <bapInternal.h>
92#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053093#include "wlan_hdd_trace.h"
94#include "vos_types.h"
95#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include <linux/wireless.h>
97#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053098#include <linux/inetdevice.h>
99#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "wlan_hdd_cfg80211.h"
101#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700103int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include "sapApi.h"
105#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700106#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
108#include <soc/qcom/subsystem_restart.h>
109#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530111#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include <wlan_hdd_hostapd.h>
113#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_hdd_dev_pwr.h"
116#ifdef WLAN_BTAMP_FEATURE
117#include "bap_hdd_misc.h"
118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700120#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800121#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530122#ifdef FEATURE_WLAN_TDLS
123#include "wlan_hdd_tdls.h"
124#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700125#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700126
127#ifdef MODULE
128#define WLAN_MODULE_NAME module_name(THIS_MODULE)
129#else
130#define WLAN_MODULE_NAME "wlan"
131#endif
132
133#ifdef TIMER_MANAGER
134#define TIMER_MANAGER_STR " +TIMER_MANAGER"
135#else
136#define TIMER_MANAGER_STR ""
137#endif
138
139#ifdef MEMORY_DEBUG
140#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
141#else
142#define MEMORY_DEBUG_STR ""
143#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530144#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700145/* the Android framework expects this param even though we don't use it */
146#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700147static char fwpath_buffer[BUF_LEN];
148static struct kparam_string fwpath = {
149 .string = fwpath_buffer,
150 .maxlen = BUF_LEN,
151};
Arif Hussain66559122013-11-21 10:11:40 -0800152
153static char *country_code;
154static int enable_11d = -1;
155static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530156static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800157
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700159static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161
Jeff Johnsone7245742012-09-05 17:12:55 -0700162/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800163 * spinlock for synchronizing asynchronous request/response
164 * (full description of use in wlan_hdd_main.h)
165 */
166DEFINE_SPINLOCK(hdd_context_lock);
167
168/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700169 * The rate at which the driver sends RESTART event to supplicant
170 * once the function 'vos_wlanRestart()' is called
171 *
172 */
173#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
174#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700175
176/*
177 * Size of Driver command strings from upper layer
178 */
179#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
180#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
181
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800182#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700183#define TID_MIN_VALUE 0
184#define TID_MAX_VALUE 15
185static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
186 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800187static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
188 tCsrEseBeaconReq *pEseBcnReq);
189#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530191static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530192/*
193 * Maximum buffer size used for returning the data back to user space
194 */
195#define WLAN_MAX_BUF_SIZE 1024
196#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700197
c_hpothu92367912014-05-01 15:18:17 +0530198//wait time for beacon miss rate.
199#define BCN_MISS_RATE_TIME 500
200
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800201#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700202static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700205static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700206
207//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700208static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
209static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
210static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
211void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800212void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700213
Jeff Johnson295189b2012-06-20 16:38:30 -0700214v_U16_t hdd_select_queue(struct net_device *dev,
215 struct sk_buff *skb);
216
217#ifdef WLAN_FEATURE_PACKET_FILTERING
218static void hdd_set_multicast_list(struct net_device *dev);
219#endif
220
221void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
222
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800223#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800224void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
225static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700226static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
228 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700229static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
230 tANI_U8 *pTargetApBssid,
231 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800232#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Jeff Johnson295189b2012-06-20 16:38:30 -0700255static int hdd_netdev_notifier_call(struct notifier_block * nb,
256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
356struct notifier_block hdd_netdev_notifier = {
357 .notifier_call = hdd_netdev_notifier_call,
358};
359
360/*---------------------------------------------------------------------------
361 * Function definitions
362 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700363void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
364void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700366static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700367#ifndef MODULE
368/* current con_mode - used only for statically linked driver
369 * con_mode is changed by userspace to indicate a mode change which will
370 * result in calling the module exit and init functions. The module
371 * exit function will clean up based on the value of con_mode prior to it
372 * being changed by userspace. So curr_con_mode records the current con_mode
373 * for exit when con_mode becomes the next mode for init
374 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700375static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700376#endif
377
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800378/**---------------------------------------------------------------------------
379
380 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
381
382 Called immediately after the cfg.ini is read in order to configure
383 the desired trace levels.
384
385 \param - moduleId - module whose trace level is being configured
386 \param - bitmask - bitmask of log levels to be enabled
387
388 \return - void
389
390 --------------------------------------------------------------------------*/
391static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
392{
393 wpt_tracelevel level;
394
395 /* if the bitmask is the default value, then a bitmask was not
396 specified in cfg.ini, so leave the logging level alone (it
397 will remain at the "compiled in" default value) */
398 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
399 {
400 return;
401 }
402
403 /* a mask was specified. start by disabling all logging */
404 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
405
406 /* now cycle through the bitmask until all "set" bits are serviced */
407 level = VOS_TRACE_LEVEL_FATAL;
408 while (0 != bitmask)
409 {
410 if (bitmask & 1)
411 {
412 vos_trace_setValue(moduleId, level, 1);
413 }
414 level++;
415 bitmask >>= 1;
416 }
417}
418
419
Jeff Johnson295189b2012-06-20 16:38:30 -0700420/**---------------------------------------------------------------------------
421
422 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
423
424 Called immediately after the cfg.ini is read in order to configure
425 the desired trace levels in the WDI.
426
427 \param - moduleId - module whose trace level is being configured
428 \param - bitmask - bitmask of log levels to be enabled
429
430 \return - void
431
432 --------------------------------------------------------------------------*/
433static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
434{
435 wpt_tracelevel level;
436
437 /* if the bitmask is the default value, then a bitmask was not
438 specified in cfg.ini, so leave the logging level alone (it
439 will remain at the "compiled in" default value) */
440 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
441 {
442 return;
443 }
444
445 /* a mask was specified. start by disabling all logging */
446 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
447
448 /* now cycle through the bitmask until all "set" bits are serviced */
449 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
450 while (0 != bitmask)
451 {
452 if (bitmask & 1)
453 {
454 wpalTraceSetLevel(moduleId, level, 1);
455 }
456 level++;
457 bitmask >>= 1;
458 }
459}
Jeff Johnson295189b2012-06-20 16:38:30 -0700460
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530461/*
462 * FUNCTION: wlan_hdd_validate_context
463 * This function is used to check the HDD context
464 */
465int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
466{
467 ENTER();
468
469 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
470 {
471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
472 "%s: HDD context is Null", __func__);
473 return -ENODEV;
474 }
475
476 if (pHddCtx->isLogpInProgress)
477 {
478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
479 "%s: LOGP in Progress. Ignore!!!", __func__);
480 return -EAGAIN;
481 }
482
Mihir Shete18156292014-03-11 15:38:30 +0530483 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530484 {
485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
486 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
487 return -EAGAIN;
488 }
489 return 0;
490}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700491#ifdef CONFIG_ENABLE_LINUX_REG
492void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
493{
494 hdd_adapter_t *pAdapter = NULL;
495 hdd_station_ctx_t *pHddStaCtx = NULL;
496 eCsrPhyMode phyMode;
497 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700499 if (NULL == pHddCtx)
500 {
501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
502 "HDD Context is null !!");
503 return ;
504 }
505
506 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
507 if (NULL == pAdapter)
508 {
509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
510 "pAdapter is null !!");
511 return ;
512 }
513
514 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
515 if (NULL == pHddStaCtx)
516 {
517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
518 "pHddStaCtx is null !!");
519 return ;
520 }
521
522 cfg_param = pHddCtx->cfg_ini;
523 if (NULL == cfg_param)
524 {
525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
526 "cfg_params not available !!");
527 return ;
528 }
529
530 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
531
532 if (!pHddCtx->isVHT80Allowed)
533 {
534 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
535 (eCSR_DOT11_MODE_11ac == phyMode) ||
536 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
537 {
538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
539 "Setting phymode to 11n!!");
540 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
541 }
542 }
543 else
544 {
545 /*New country Supports 11ac as well resetting value back from .ini*/
546 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
547 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
548 return ;
549 }
550
551 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
552 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
553 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
554 {
555 VOS_STATUS vosStatus;
556
557 // need to issue a disconnect to CSR.
558 INIT_COMPLETION(pAdapter->disconnect_comp_var);
559 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
560 pAdapter->sessionId,
561 eCSR_DISCONNECT_REASON_UNSPECIFIED );
562
563 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530564 {
565 long ret;
566
567 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700568 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530569 if (0 >= ret)
570 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
571 ret);
572 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700573
574 }
575}
576#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530577void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
578{
579 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
580 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
581 hdd_config_t *cfg_param;
582 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530583 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530584
585 if (NULL == pHddCtx)
586 {
587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
588 "HDD Context is null !!");
589 return ;
590 }
591
592 cfg_param = pHddCtx->cfg_ini;
593
594 if (NULL == cfg_param)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
597 "cfg_params not available !!");
598 return ;
599 }
600
601 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
602
603 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
604 {
605 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
606 (eCSR_DOT11_MODE_11ac == phyMode) ||
607 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
610 "Setting phymode to 11n!!");
611 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
612 }
613 }
614 else
615 {
616 /*New country Supports 11ac as well resetting value back from .ini*/
617 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
618 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
619 return ;
620 }
621
622 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
623 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
624 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
625 {
626 VOS_STATUS vosStatus;
627
628 // need to issue a disconnect to CSR.
629 INIT_COMPLETION(pAdapter->disconnect_comp_var);
630 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
631 pAdapter->sessionId,
632 eCSR_DISCONNECT_REASON_UNSPECIFIED );
633
634 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530635 {
636 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530637 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530638 if (ret <= 0)
639 {
640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
641 "wait on disconnect_comp_var is failed %ld", ret);
642 }
643 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530644
645 }
646}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700647#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530648
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700649void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
650{
651 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
652 hdd_config_t *cfg_param;
653
654 if (NULL == pHddCtx)
655 {
656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
657 "HDD Context is null !!");
658 return ;
659 }
660
661 cfg_param = pHddCtx->cfg_ini;
662
663 if (NULL == cfg_param)
664 {
665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
666 "cfg_params not available !!");
667 return ;
668 }
669
Agarwal Ashish738843c2014-09-25 12:27:56 +0530670 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
671 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700672 {
673 /*New country doesn't support DFS */
674 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
675 }
676 else
677 {
678 /*New country Supports DFS as well resetting value back from .ini*/
679 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
680 }
681
682}
683
Rajeev79dbe4c2013-10-05 11:03:42 +0530684#ifdef FEATURE_WLAN_BATCH_SCAN
685
686/**---------------------------------------------------------------------------
687
688 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
689 input string
690
691 This function extracts assigned integer from string in below format:
692 "STRING=10" : extracts integer 10 from this string
693
694 \param - pInPtr Pointer to input string
695 \param - base Base for string to int conversion(10 for decimal 16 for hex)
696 \param - pOutPtr Pointer to variable in which extracted integer needs to be
697 assigned
698 \param - pLastArg to tell whether it is last arguement in input string or
699 not
700
701 \return - NULL for failure cases
702 pointer to next arguement in input string for success cases
703 --------------------------------------------------------------------------*/
704static tANI_U8 *
705hdd_extract_assigned_int_from_str
706(
707 tANI_U8 *pInPtr,
708 tANI_U8 base,
709 tANI_U32 *pOutPtr,
710 tANI_U8 *pLastArg
711)
712{
713 int tempInt;
714 int v = 0;
715 char buf[32];
716 int val = 0;
717 *pLastArg = FALSE;
718
719 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
720 if (NULL == pInPtr)
721 {
722 return NULL;
723 }
724
725 pInPtr++;
726
727 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
728
729 val = sscanf(pInPtr, "%32s ", buf);
730 if (val < 0 && val > strlen(pInPtr))
731 {
732 return NULL;
733 }
734 pInPtr += val;
735 v = kstrtos32(buf, base, &tempInt);
736 if (v < 0)
737 {
738 return NULL;
739 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800740 if (tempInt < 0)
741 {
742 tempInt = 0;
743 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530744 *pOutPtr = tempInt;
745
746 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
747 if (NULL == pInPtr)
748 {
749 *pLastArg = TRUE;
750 return NULL;
751 }
752 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
753
754 return pInPtr;
755}
756
757/**---------------------------------------------------------------------------
758
759 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
760 input string
761
762 This function extracts assigned character from string in below format:
763 "STRING=A" : extracts char 'A' from this string
764
765 \param - pInPtr Pointer to input string
766 \param - pOutPtr Pointer to variable in which extracted char needs to be
767 assigned
768 \param - pLastArg to tell whether it is last arguement in input string or
769 not
770
771 \return - NULL for failure cases
772 pointer to next arguement in input string for success cases
773 --------------------------------------------------------------------------*/
774static tANI_U8 *
775hdd_extract_assigned_char_from_str
776(
777 tANI_U8 *pInPtr,
778 tANI_U8 *pOutPtr,
779 tANI_U8 *pLastArg
780)
781{
782 *pLastArg = FALSE;
783
784 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
785 if (NULL == pInPtr)
786 {
787 return NULL;
788 }
789
790 pInPtr++;
791
792 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
793
794 *pOutPtr = *pInPtr;
795
796 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
797 if (NULL == pInPtr)
798 {
799 *pLastArg = TRUE;
800 return NULL;
801 }
802 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
803
804 return pInPtr;
805}
806
807
808/**---------------------------------------------------------------------------
809
810 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
811
812 This function parses set batch scan command in below format:
813 WLS_BATCHING_SET <space> followed by below arguements
814 "SCANFREQ=XX" : Optional defaults to 30 sec
815 "MSCAN=XX" : Required number of scans to attempt to batch
816 "BESTN=XX" : Best Network (RSSI) defaults to 16
817 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
818 A. implies only 5 GHz , B. implies only 2.4GHz
819 "RTT=X" : optional defaults to 0
820 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
821 error
822
823 For example input commands:
824 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
825 translated into set batch scan with following parameters:
826 a) Frequence 60 seconds
827 b) Batch 10 scans together
828 c) Best RSSI to be 20
829 d) 5GHz band only
830 e) RTT is equal to 0
831
832 \param - pValue Pointer to input channel list
833 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
834
835 \return - 0 for success non-zero for failure
836
837 --------------------------------------------------------------------------*/
838static int
839hdd_parse_set_batchscan_command
840(
841 tANI_U8 *pValue,
842 tSirSetBatchScanReq *pHddSetBatchScanReq
843)
844{
845 tANI_U8 *inPtr = pValue;
846 tANI_U8 val = 0;
847 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800848 tANI_U32 nScanFreq;
849 tANI_U32 nMscan;
850 tANI_U32 nBestN;
851 tANI_U8 ucRfBand;
852 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800853 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530854
855 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800856 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
857 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
858 nRtt = 0;
859 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530860
861 /*go to space after WLS_BATCHING_SET command*/
862 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
863 /*no argument after the command*/
864 if (NULL == inPtr)
865 {
866 return -EINVAL;
867 }
868
869 /*no space after the command*/
870 else if (SPACE_ASCII_VALUE != *inPtr)
871 {
872 return -EINVAL;
873 }
874
875 /*removing empty spaces*/
876 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
877
878 /*no argument followed by spaces*/
879 if ('\0' == *inPtr)
880 {
881 return -EINVAL;
882 }
883
884 /*check and parse SCANFREQ*/
885 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
886 {
887 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800888 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800889
Rajeev Kumarc933d982013-11-18 20:04:20 -0800890 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800891 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800892 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800893 }
894
Rajeev79dbe4c2013-10-05 11:03:42 +0530895 if ( (NULL == inPtr) || (TRUE == lastArg))
896 {
897 return -EINVAL;
898 }
899 }
900
901 /*check and parse MSCAN*/
902 if ((strncmp(inPtr, "MSCAN", 5) == 0))
903 {
904 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800905 &nMscan, &lastArg);
906
907 if (0 == nMscan)
908 {
909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
910 "invalid MSCAN=%d", nMscan);
911 return -EINVAL;
912 }
913
Rajeev79dbe4c2013-10-05 11:03:42 +0530914 if (TRUE == lastArg)
915 {
916 goto done;
917 }
918 else if (NULL == inPtr)
919 {
920 return -EINVAL;
921 }
922 }
923 else
924 {
925 return -EINVAL;
926 }
927
928 /*check and parse BESTN*/
929 if ((strncmp(inPtr, "BESTN", 5) == 0))
930 {
931 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800932 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800933
Rajeev Kumarc933d982013-11-18 20:04:20 -0800934 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800935 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800936 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800937 }
938
Rajeev79dbe4c2013-10-05 11:03:42 +0530939 if (TRUE == lastArg)
940 {
941 goto done;
942 }
943 else if (NULL == inPtr)
944 {
945 return -EINVAL;
946 }
947 }
948
949 /*check and parse CHANNEL*/
950 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
951 {
952 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800953
Rajeev79dbe4c2013-10-05 11:03:42 +0530954 if (('A' == val) || ('a' == val))
955 {
c_hpothuebf89732014-02-25 13:00:24 +0530956 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530957 }
958 else if (('B' == val) || ('b' == val))
959 {
c_hpothuebf89732014-02-25 13:00:24 +0530960 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530961 }
962 else
963 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800964 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
965 }
966
967 if (TRUE == lastArg)
968 {
969 goto done;
970 }
971 else if (NULL == inPtr)
972 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 return -EINVAL;
974 }
975 }
976
977 /*check and parse RTT*/
978 if ((strncmp(inPtr, "RTT", 3) == 0))
979 {
980 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800981 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530982 if (TRUE == lastArg)
983 {
984 goto done;
985 }
986 if (NULL == inPtr)
987 {
988 return -EINVAL;
989 }
990 }
991
992
993done:
994
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800995 pHddSetBatchScanReq->scanFrequency = nScanFreq;
996 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
997 pHddSetBatchScanReq->bestNetwork = nBestN;
998 pHddSetBatchScanReq->rfBand = ucRfBand;
999 pHddSetBatchScanReq->rtt = nRtt;
1000
Rajeev79dbe4c2013-10-05 11:03:42 +05301001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1002 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1003 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1004 pHddSetBatchScanReq->scanFrequency,
1005 pHddSetBatchScanReq->numberOfScansToBatch,
1006 pHddSetBatchScanReq->bestNetwork,
1007 pHddSetBatchScanReq->rfBand,
1008 pHddSetBatchScanReq->rtt);
1009
1010 return 0;
1011}/*End of hdd_parse_set_batchscan_command*/
1012
1013/**---------------------------------------------------------------------------
1014
1015 \brief hdd_set_batch_scan_req_callback () - This function is called after
1016 receiving set batch scan response from FW and it saves set batch scan
1017 response data FW to HDD context and sets the completion event on
1018 which hdd_ioctl is waiting
1019
1020 \param - callbackContext Pointer to HDD adapter
1021 \param - pRsp Pointer to set batch scan response data received from FW
1022
1023 \return - nothing
1024
1025 --------------------------------------------------------------------------*/
1026static void hdd_set_batch_scan_req_callback
1027(
1028 void *callbackContext,
1029 tSirSetBatchScanRsp *pRsp
1030)
1031{
1032 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1033 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1034
1035 /*sanity check*/
1036 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1037 {
1038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1039 "%s: Invalid pAdapter magic", __func__);
1040 VOS_ASSERT(0);
1041 return;
1042 }
1043 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1044
1045 /*save set batch scan response*/
1046 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1047
1048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1049 "Received set batch scan rsp from FW with nScansToBatch=%d",
1050 pHddSetBatchScanRsp->nScansToBatch);
1051
1052 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1053 complete(&pAdapter->hdd_set_batch_scan_req_var);
1054
1055 return;
1056}/*End of hdd_set_batch_scan_req_callback*/
1057
1058
1059/**---------------------------------------------------------------------------
1060
1061 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1062 info in hdd batch scan response queue
1063
1064 \param - pAdapter Pointer to hdd adapter
1065 \param - pAPMetaInfo Pointer to access point meta info
1066 \param - scanId scan ID of batch scan response
1067 \param - isLastAp tells whether AP is last AP in batch scan response or not
1068
1069 \return - nothing
1070
1071 --------------------------------------------------------------------------*/
1072static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1073 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1074{
1075 tHddBatchScanRsp *pHead;
1076 tHddBatchScanRsp *pNode;
1077 tHddBatchScanRsp *pPrev;
1078 tHddBatchScanRsp *pTemp;
1079 tANI_U8 ssidLen;
1080
1081 /*head of hdd batch scan response queue*/
1082 pHead = pAdapter->pBatchScanRsp;
1083
1084 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1085 if (NULL == pNode)
1086 {
1087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1088 "%s: Could not allocate memory", __func__);
1089 VOS_ASSERT(0);
1090 return;
1091 }
1092
1093 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1094 sizeof(pNode->ApInfo.bssid));
1095 ssidLen = strlen(pApMetaInfo->ssid);
1096 if (SIR_MAX_SSID_SIZE < ssidLen)
1097 {
1098 /*invalid scan result*/
1099 vos_mem_free(pNode);
1100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1101 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1102 return;
1103 }
1104 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1105 /*null terminate ssid*/
1106 pNode->ApInfo.ssid[ssidLen] = '\0';
1107 pNode->ApInfo.ch = pApMetaInfo->ch;
1108 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1109 pNode->ApInfo.age = pApMetaInfo->timestamp;
1110 pNode->ApInfo.batchId = scanId;
1111 pNode->ApInfo.isLastAp = isLastAp;
1112
1113 pNode->pNext = NULL;
1114 if (NULL == pHead)
1115 {
1116 pAdapter->pBatchScanRsp = pNode;
1117 }
1118 else
1119 {
1120 pTemp = pHead;
1121 while (NULL != pTemp)
1122 {
1123 pPrev = pTemp;
1124 pTemp = pTemp->pNext;
1125 }
1126 pPrev->pNext = pNode;
1127 }
1128
1129 return;
1130}/*End of hdd_populate_batch_scan_rsp_queue*/
1131
1132/**---------------------------------------------------------------------------
1133
1134 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1135 receiving batch scan response indication from FW. It saves get batch scan
1136 response data in HDD batch scan response queue. This callback sets the
1137 completion event on which hdd_ioctl is waiting only after getting complete
1138 batch scan response data from FW
1139
1140 \param - callbackContext Pointer to HDD adapter
1141 \param - pRsp Pointer to get batch scan response data received from FW
1142
1143 \return - nothing
1144
1145 --------------------------------------------------------------------------*/
1146static void hdd_batch_scan_result_ind_callback
1147(
1148 void *callbackContext,
1149 void *pRsp
1150)
1151{
1152 v_BOOL_t isLastAp;
1153 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001154 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301155 tANI_U32 numberScanList;
1156 tANI_U32 nextScanListOffset;
1157 tANI_U32 nextApMetaInfoOffset;
1158 hdd_adapter_t* pAdapter;
1159 tpSirBatchScanList pScanList;
1160 tpSirBatchScanNetworkInfo pApMetaInfo;
1161 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1162 tSirSetBatchScanReq *pReq;
1163
1164 pAdapter = (hdd_adapter_t *)callbackContext;
1165 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001166 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301167 {
1168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1169 "%s: Invalid pAdapter magic", __func__);
1170 VOS_ASSERT(0);
1171 return;
1172 }
1173
1174 /*initialize locals*/
1175 pReq = &pAdapter->hddSetBatchScanReq;
1176 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1177 isLastAp = FALSE;
1178 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001179 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301180 numberScanList = 0;
1181 nextScanListOffset = 0;
1182 nextApMetaInfoOffset = 0;
1183 pScanList = NULL;
1184 pApMetaInfo = NULL;
1185
1186 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1187 {
1188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1189 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1190 isLastAp = TRUE;
1191 goto done;
1192 }
1193
1194 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1196 "Batch scan rsp: numberScalList %d", numberScanList);
1197
1198 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: numberScanList %d", __func__, numberScanList);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
1206 while (numberScanList)
1207 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001208 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301209 nextScanListOffset);
1210 if (NULL == pScanList)
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1213 "%s: pScanList is %p", __func__, pScanList);
1214 isLastAp = TRUE;
1215 goto done;
1216 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001217 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001219 "Batch scan rsp: numApMetaInfo %d scanId %d",
1220 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301221
1222 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
1229
Rajeev Kumarce651e42013-10-21 18:57:15 -07001230 /*Initialize next AP meta info offset for next scan list*/
1231 nextApMetaInfoOffset = 0;
1232
Rajeev79dbe4c2013-10-05 11:03:42 +05301233 while (numApMetaInfo)
1234 {
1235 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1236 nextApMetaInfoOffset);
1237 if (NULL == pApMetaInfo)
1238 {
1239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1240 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1241 isLastAp = TRUE;
1242 goto done;
1243 }
1244 /*calculate AP age*/
1245 pApMetaInfo->timestamp =
1246 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1247
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001249 "%s: bssId "MAC_ADDRESS_STR
1250 " ch %d rssi %d timestamp %d", __func__,
1251 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1252 pApMetaInfo->ch, pApMetaInfo->rssi,
1253 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301254
1255 /*mark last AP in batch scan response*/
1256 if ((TRUE == pBatchScanRsp->isLastResult) &&
1257 (1 == numberScanList) && (1 == numApMetaInfo))
1258 {
1259 isLastAp = TRUE;
1260 }
1261
1262 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1263 /*store batch scan repsonse in hdd queue*/
1264 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1265 pScanList->scanId, isLastAp);
1266 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1267
1268 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1269 numApMetaInfo--;
1270 }
1271
Rajeev Kumarce651e42013-10-21 18:57:15 -07001272 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1273 + (sizeof(tSirBatchScanNetworkInfo)
1274 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301275 numberScanList--;
1276 }
1277
1278done:
1279
1280 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1281 requested from hdd_ioctl*/
1282 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1283 (TRUE == isLastAp))
1284 {
1285 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1286 complete(&pAdapter->hdd_get_batch_scan_req_var);
1287 }
1288
1289 return;
1290}/*End of hdd_batch_scan_result_ind_callback*/
1291
1292/**---------------------------------------------------------------------------
1293
1294 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1295 response as per batch scan FR request format by putting proper markers
1296
1297 \param - pDest pointer to destination buffer
1298 \param - cur_len current length
1299 \param - tot_len total remaining size which can be written to user space
1300 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1301 \param - pAdapter Pointer to HDD adapter
1302
1303 \return - ret no of characters written
1304
1305 --------------------------------------------------------------------------*/
1306static tANI_U32
1307hdd_format_batch_scan_rsp
1308(
1309 tANI_U8 *pDest,
1310 tANI_U32 cur_len,
1311 tANI_U32 tot_len,
1312 tHddBatchScanRsp *pApMetaInfo,
1313 hdd_adapter_t* pAdapter
1314)
1315{
1316 tANI_U32 ret = 0;
1317 tANI_U32 rem_len = 0;
1318 tANI_U8 temp_len = 0;
1319 tANI_U8 temp_total_len = 0;
1320 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1321 tANI_U8 *pTemp = temp;
1322
1323 /*Batch scan reponse needs to be returned to user space in
1324 following format:
1325 "scancount=X\n" where X is the number of scans in current batch
1326 batch
1327 "trunc\n" optional present if current scan truncated
1328 "bssid=XX:XX:XX:XX:XX:XX\n"
1329 "ssid=XXXX\n"
1330 "freq=X\n" frequency in Mhz
1331 "level=XX\n"
1332 "age=X\n" ms
1333 "dist=X\n" cm (-1 if not available)
1334 "errror=X\n" (-1if not available)
1335 "====\n" (end of ap marker)
1336 "####\n" (end of scan marker)
1337 "----\n" (end of results)*/
1338 /*send scan result in above format to user space based on
1339 available length*/
1340 /*The GET response may have more data than the driver can return in its
1341 buffer. In that case the buffer should be filled to the nearest complete
1342 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1343 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1344 The final buffer should end with "----\n"*/
1345
1346 /*sanity*/
1347 if (cur_len > tot_len)
1348 {
1349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1350 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1351 return 0;
1352 }
1353 else
1354 {
1355 rem_len = (tot_len - cur_len);
1356 }
1357
1358 /*end scan marker*/
1359 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1360 {
1361 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1362 pTemp += temp_len;
1363 temp_total_len += temp_len;
1364 }
1365
1366 /*bssid*/
1367 temp_len = snprintf(pTemp, sizeof(temp),
1368 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1369 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1370 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1371 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1372 pTemp += temp_len;
1373 temp_total_len += temp_len;
1374
1375 /*ssid*/
1376 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1377 pApMetaInfo->ApInfo.ssid);
1378 pTemp += temp_len;
1379 temp_total_len += temp_len;
1380
1381 /*freq*/
1382 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001383 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*level*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1389 pApMetaInfo->ApInfo.rssi);
1390 pTemp += temp_len;
1391 temp_total_len += temp_len;
1392
1393 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301395 pApMetaInfo->ApInfo.age);
1396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*dist*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1401 pTemp += temp_len;
1402 temp_total_len += temp_len;
1403
1404 /*error*/
1405 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1406 pTemp += temp_len;
1407 temp_total_len += temp_len;
1408
1409 /*end AP marker*/
1410 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1411 pTemp += temp_len;
1412 temp_total_len += temp_len;
1413
1414 /*last AP in batch scan response*/
1415 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1416 {
1417 /*end scan marker*/
1418 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1419 pTemp += temp_len;
1420 temp_total_len += temp_len;
1421
1422 /*end batch scan result marker*/
1423 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1424 pTemp += temp_len;
1425 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001426
Rajeev79dbe4c2013-10-05 11:03:42 +05301427 }
1428
1429 if (temp_total_len < rem_len)
1430 {
1431 ret = temp_total_len + 1;
1432 strlcpy(pDest, temp, ret);
1433 pAdapter->isTruncated = FALSE;
1434 }
1435 else
1436 {
1437 pAdapter->isTruncated = TRUE;
1438 if (rem_len >= strlen("%%%%"))
1439 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001440 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301441 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001442 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301443 {
1444 ret = 0;
1445 }
1446 }
1447
1448 return ret;
1449
1450}/*End of hdd_format_batch_scan_rsp*/
1451
1452/**---------------------------------------------------------------------------
1453
1454 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1455 buffer starting with head of hdd batch scan response queue
1456
1457 \param - pAdapter Pointer to HDD adapter
1458 \param - pDest Pointer to user data buffer
1459 \param - cur_len current offset in user buffer
1460 \param - rem_len remaining no of bytes in user buffer
1461
1462 \return - number of bytes written in user buffer
1463
1464 --------------------------------------------------------------------------*/
1465
1466tANI_U32 hdd_populate_user_batch_scan_rsp
1467(
1468 hdd_adapter_t* pAdapter,
1469 tANI_U8 *pDest,
1470 tANI_U32 cur_len,
1471 tANI_U32 rem_len
1472)
1473{
1474 tHddBatchScanRsp *pHead;
1475 tHddBatchScanRsp *pPrev;
1476 tANI_U32 len;
1477
Rajeev79dbe4c2013-10-05 11:03:42 +05301478 pAdapter->isTruncated = FALSE;
1479
1480 /*head of hdd batch scan response queue*/
1481 pHead = pAdapter->pBatchScanRsp;
1482 while (pHead)
1483 {
1484 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1485 pAdapter);
1486 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001487 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301488 cur_len += len;
1489 if(TRUE == pAdapter->isTruncated)
1490 {
1491 /*result is truncated return rest of scan rsp in next req*/
1492 cur_len = rem_len;
1493 break;
1494 }
1495 pPrev = pHead;
1496 pHead = pHead->pNext;
1497 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001498 if (TRUE == pPrev->ApInfo.isLastAp)
1499 {
1500 pAdapter->prev_batch_id = 0;
1501 }
1502 else
1503 {
1504 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1505 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301506 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001507 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301508 }
1509
1510 return cur_len;
1511}/*End of hdd_populate_user_batch_scan_rsp*/
1512
1513/**---------------------------------------------------------------------------
1514
1515 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1516 scan response data from HDD queue to user space
1517 It does following in detail:
1518 a) if HDD has enough data in its queue then it 1st copies data to user
1519 space and then send get batch scan indication message to FW. In this
1520 case it does not wait on any event and batch scan response data will
1521 be populated in HDD response queue in MC thread context after receiving
1522 indication from FW
1523 b) else send get batch scan indication message to FW and wait on an event
1524 which will be set once HDD receives complete batch scan response from
1525 FW and then this function returns batch scan response to user space
1526
1527 \param - pAdapter Pointer to HDD adapter
1528 \param - pPrivData Pointer to priv_data
1529
1530 \return - 0 for success -EFAULT for failure
1531
1532 --------------------------------------------------------------------------*/
1533
1534int hdd_return_batch_scan_rsp_to_user
1535(
1536 hdd_adapter_t* pAdapter,
1537 hdd_priv_data_t *pPrivData,
1538 tANI_U8 *command
1539)
1540{
1541 tANI_U8 *pDest;
1542 tANI_U32 count = 0;
1543 tANI_U32 len = 0;
1544 tANI_U32 cur_len = 0;
1545 tANI_U32 rem_len = 0;
1546 eHalStatus halStatus;
1547 unsigned long rc;
1548 tSirTriggerBatchScanResultInd *pReq;
1549
1550 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1551 pReq->param = 0;/*batch scan client*/
1552 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1553 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1554
1555 cur_len = pPrivData->used_len;
1556 if (pPrivData->total_len > pPrivData->used_len)
1557 {
1558 rem_len = pPrivData->total_len - pPrivData->used_len;
1559 }
1560 else
1561 {
1562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1563 "%s: Invalid user data buffer total_len %d used_len %d",
1564 __func__, pPrivData->total_len, pPrivData->used_len);
1565 return -EFAULT;
1566 }
1567
1568 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1569 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1570 cur_len, rem_len);
1571 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1572
1573 /*enough scan result available in cache to return to user space or
1574 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001575 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301576 {
1577 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1578 halStatus = sme_TriggerBatchScanResultInd(
1579 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1580 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1581 pAdapter);
1582 if ( eHAL_STATUS_SUCCESS == halStatus )
1583 {
1584 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1585 {
1586 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1587 rc = wait_for_completion_timeout(
1588 &pAdapter->hdd_get_batch_scan_req_var,
1589 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1590 if (0 == rc)
1591 {
1592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1593 "%s: Timeout waiting to fetch batch scan rsp from fw",
1594 __func__);
1595 return -EFAULT;
1596 }
1597 }
1598
1599 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001600 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301601 pDest += len;
1602 cur_len += len;
1603
1604 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1605 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1606 cur_len, rem_len);
1607 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1608
1609 count = 0;
1610 len = (len - pPrivData->used_len);
1611 pDest = (command + pPrivData->used_len);
1612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001613 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301614 while(count < len)
1615 {
1616 printk("%c", *(pDest + count));
1617 count++;
1618 }
1619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1620 "%s: copy %d data to user buffer", __func__, len);
1621 if (copy_to_user(pPrivData->buf, pDest, len))
1622 {
1623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1624 "%s: failed to copy data to user buffer", __func__);
1625 return -EFAULT;
1626 }
1627 }
1628 else
1629 {
1630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1631 "sme_GetBatchScanScan returned failure halStatus %d",
1632 halStatus);
1633 return -EINVAL;
1634 }
1635 }
1636 else
1637 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301638 count = 0;
1639 len = (len - pPrivData->used_len);
1640 pDest = (command + pPrivData->used_len);
1641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001642 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301643 while(count < len)
1644 {
1645 printk("%c", *(pDest + count));
1646 count++;
1647 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1649 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301650 if (copy_to_user(pPrivData->buf, pDest, len))
1651 {
1652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: failed to copy data to user buffer", __func__);
1654 return -EFAULT;
1655 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301656 }
1657
1658 return 0;
1659} /*End of hdd_return_batch_scan_rsp_to_user*/
1660
Rajeev Kumar8b373292014-01-08 20:36:55 -08001661
1662/**---------------------------------------------------------------------------
1663
1664 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1665 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1666 WLS_BATCHING VERSION
1667 WLS_BATCHING SET
1668 WLS_BATCHING GET
1669 WLS_BATCHING STOP
1670
1671 \param - pAdapter Pointer to HDD adapter
1672 \param - pPrivdata Pointer to priv_data
1673 \param - command Pointer to command
1674
1675 \return - 0 for success -EFAULT for failure
1676
1677 --------------------------------------------------------------------------*/
1678
1679int hdd_handle_batch_scan_ioctl
1680(
1681 hdd_adapter_t *pAdapter,
1682 hdd_priv_data_t *pPrivdata,
1683 tANI_U8 *command
1684)
1685{
1686 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001687 hdd_context_t *pHddCtx;
1688
1689 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1690 ret = wlan_hdd_validate_context(pHddCtx);
1691 if (ret)
1692 {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1694 "%s: HDD context is not valid!", __func__);
1695 goto exit;
1696 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001697
1698 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1699 {
1700 char extra[32];
1701 tANI_U8 len = 0;
1702 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1703
1704 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1705 {
1706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1707 "%s: Batch scan feature is not supported by FW", __func__);
1708 ret = -EINVAL;
1709 goto exit;
1710 }
1711
1712 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1713 version);
1714 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1715 {
1716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1717 "%s: failed to copy data to user buffer", __func__);
1718 ret = -EFAULT;
1719 goto exit;
1720 }
1721 ret = HDD_BATCH_SCAN_VERSION;
1722 }
1723 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1724 {
1725 int status;
1726 tANI_U8 *value = (command + 16);
1727 eHalStatus halStatus;
1728 unsigned long rc;
1729 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1730 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1731
1732 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1733 {
1734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1735 "%s: Batch scan feature is not supported by FW", __func__);
1736 ret = -EINVAL;
1737 goto exit;
1738 }
1739
1740 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1741 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1742 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1743 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1744 {
1745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301746 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001747 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301748 hdd_device_modetoString(pAdapter->device_mode),
1749 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001750 ret = -EINVAL;
1751 goto exit;
1752 }
1753
1754 status = hdd_parse_set_batchscan_command(value, pReq);
1755 if (status)
1756 {
1757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1758 "Invalid WLS_BATCHING SET command");
1759 ret = -EINVAL;
1760 goto exit;
1761 }
1762
1763
1764 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1765 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1766 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1767 pAdapter);
1768
1769 if ( eHAL_STATUS_SUCCESS == halStatus )
1770 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301771 char extra[32];
1772 tANI_U8 len = 0;
1773 tANI_U8 mScan = 0;
1774
Rajeev Kumar8b373292014-01-08 20:36:55 -08001775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1776 "sme_SetBatchScanReq returned success halStatus %d",
1777 halStatus);
1778 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1779 {
1780 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1781 rc = wait_for_completion_timeout(
1782 &pAdapter->hdd_set_batch_scan_req_var,
1783 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1784 if (0 == rc)
1785 {
1786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1787 "%s: Timeout waiting for set batch scan to complete",
1788 __func__);
1789 ret = -EINVAL;
1790 goto exit;
1791 }
1792 }
1793 if ( !pRsp->nScansToBatch )
1794 {
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 "%s: Received set batch scan failure response from FW",
1797 __func__);
1798 ret = -EINVAL;
1799 goto exit;
1800 }
1801 /*As per the Batch Scan Framework API we should return the MIN of
1802 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301803 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001804
1805 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1806
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1808 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301809 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1810 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1811 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1812 {
1813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1814 "%s: failed to copy MSCAN value to user buffer", __func__);
1815 ret = -EFAULT;
1816 goto exit;
1817 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001818 }
1819 else
1820 {
1821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1822 "sme_SetBatchScanReq returned failure halStatus %d",
1823 halStatus);
1824 ret = -EINVAL;
1825 goto exit;
1826 }
1827 }
1828 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1829 {
1830 eHalStatus halStatus;
1831 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1832 pInd->param = 0;
1833
1834 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1835 {
1836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1837 "%s: Batch scan feature is not supported by FW", __func__);
1838 ret = -EINVAL;
1839 goto exit;
1840 }
1841
1842 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1843 {
1844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1845 "Batch scan is not yet enabled batch scan state %d",
1846 pAdapter->batchScanState);
1847 ret = -EINVAL;
1848 goto exit;
1849 }
1850
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001851 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1852 hdd_deinit_batch_scan(pAdapter);
1853 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1854
Rajeev Kumar8b373292014-01-08 20:36:55 -08001855 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1856
1857 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1858 pAdapter->sessionId);
1859 if ( eHAL_STATUS_SUCCESS == halStatus )
1860 {
1861 ret = 0;
1862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1863 "sme_StopBatchScanInd returned success halStatus %d",
1864 halStatus);
1865 }
1866 else
1867 {
1868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1869 "sme_StopBatchScanInd returned failure halStatus %d",
1870 halStatus);
1871 ret = -EINVAL;
1872 goto exit;
1873 }
1874 }
1875 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1876 {
1877 tANI_U32 remain_len;
1878
1879 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1880 {
1881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1882 "%s: Batch scan feature is not supported by FW", __func__);
1883 ret = -EINVAL;
1884 goto exit;
1885 }
1886
1887 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1888 {
1889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1890 "Batch scan is not yet enabled could not return results"
1891 "Batch Scan state %d",
1892 pAdapter->batchScanState);
1893 ret = -EINVAL;
1894 goto exit;
1895 }
1896
1897 pPrivdata->used_len = 16;
1898 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1899 if (remain_len < pPrivdata->total_len)
1900 {
1901 /*Clear previous batch scan response data if any*/
1902 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1903 }
1904 else
1905 {
1906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1907 "Invalid total length from user space can't fetch batch"
1908 " scan response total_len %d used_len %d remain len %d",
1909 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1910 ret = -EINVAL;
1911 goto exit;
1912 }
1913 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1914 }
1915
1916exit:
1917
1918 return ret;
1919}
1920
1921
Rajeev79dbe4c2013-10-05 11:03:42 +05301922#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1923
c_hpothu92367912014-05-01 15:18:17 +05301924static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1925{
c_hpothu39eb1e32014-06-26 16:31:50 +05301926 bcnMissRateContext_t *pCBCtx;
1927
1928 if (NULL == data)
1929 {
1930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1931 return;
1932 }
c_hpothu92367912014-05-01 15:18:17 +05301933
1934 /* there is a race condition that exists between this callback
1935 function and the caller since the caller could time out either
1936 before or while this code is executing. we use a spinlock to
1937 serialize these actions */
1938 spin_lock(&hdd_context_lock);
1939
c_hpothu39eb1e32014-06-26 16:31:50 +05301940 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301941 gbcnMissRate = -1;
1942
c_hpothu39eb1e32014-06-26 16:31:50 +05301943 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301944 {
1945 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301946 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301947 spin_unlock(&hdd_context_lock);
1948 return ;
1949 }
1950
1951 if (VOS_STATUS_SUCCESS == status)
1952 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301953 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301954 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301955 else
1956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1958 }
1959
c_hpothu92367912014-05-01 15:18:17 +05301960 complete(&(pCBCtx->completion));
1961 spin_unlock(&hdd_context_lock);
1962
1963 return;
1964}
1965
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301966static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1967{
1968 int ret = 0;
1969
1970 if (!pCfg || !command || !extra || !len)
1971 {
1972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1973 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1974 ret = -EINVAL;
1975 return ret;
1976 }
1977
1978 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1979 {
1980 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1981 (int)pCfg->nActiveMaxChnTime);
1982 return ret;
1983 }
1984 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1985 {
1986 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1987 (int)pCfg->nActiveMinChnTime);
1988 return ret;
1989 }
1990 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1991 {
1992 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1993 (int)pCfg->nPassiveMaxChnTime);
1994 return ret;
1995 }
1996 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
1997 {
1998 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
1999 (int)pCfg->nPassiveMinChnTime);
2000 return ret;
2001 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302002 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2003 {
2004 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2005 (int)pCfg->nActiveMaxChnTime);
2006 return ret;
2007 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302008 else
2009 {
2010 ret = -EINVAL;
2011 }
2012
2013 return ret;
2014}
2015
2016static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2017{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302018 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302019 hdd_config_t *pCfg;
2020 tANI_U8 *value = command;
2021 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302022 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302023
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302024 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2025 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302026 {
2027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2028 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2029 ret = -EINVAL;
2030 return ret;
2031 }
2032
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302033 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2034 sme_GetConfigParam(hHal, &smeConfig);
2035
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302036 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2037 {
2038 value = value + 24;
2039 temp = kstrtou32(value, 10, &val);
2040 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2041 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2042 {
2043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2044 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2045 ret = -EFAULT;
2046 return ret;
2047 }
2048 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302049 smeConfig.csrConfig.nActiveMaxChnTime = val;
2050 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302051 }
2052 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2053 {
2054 value = value + 24;
2055 temp = kstrtou32(value, 10, &val);
2056 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2057 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2058 {
2059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2060 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2061 ret = -EFAULT;
2062 return ret;
2063 }
2064 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302065 smeConfig.csrConfig.nActiveMinChnTime = val;
2066 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302067 }
2068 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2069 {
2070 value = value + 25;
2071 temp = kstrtou32(value, 10, &val);
2072 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2073 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2074 {
2075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2076 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2077 ret = -EFAULT;
2078 return ret;
2079 }
2080 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302081 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2082 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302083 }
2084 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2085 {
2086 value = value + 25;
2087 temp = kstrtou32(value, 10, &val);
2088 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2089 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2090 {
2091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2092 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2093 ret = -EFAULT;
2094 return ret;
2095 }
2096 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302097 smeConfig.csrConfig.nPassiveMinChnTime = val;
2098 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302099 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302100 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2101 {
2102 value = value + 13;
2103 temp = kstrtou32(value, 10, &val);
2104 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2105 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2106 {
2107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2108 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2109 ret = -EFAULT;
2110 return ret;
2111 }
2112 pCfg->nActiveMaxChnTime = val;
2113 smeConfig.csrConfig.nActiveMaxChnTime = val;
2114 sme_UpdateConfig(hHal, &smeConfig);
2115 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302116 else
2117 {
2118 ret = -EINVAL;
2119 }
2120
2121 return ret;
2122}
2123
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002124static int hdd_driver_command(hdd_adapter_t *pAdapter,
2125 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002126{
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 hdd_priv_data_t priv_data;
2128 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002129 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002130
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002131 /*
2132 * Note that valid pointers are provided by caller
2133 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002135 /* copy to local struct to avoid numerous changes to legacy code */
2136 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002137
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002138 if (priv_data.total_len <= 0 ||
2139 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002140 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002141 hddLog(VOS_TRACE_LEVEL_WARN,
2142 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2143 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002144 ret = -EINVAL;
2145 goto exit;
2146 }
2147
2148 /* Allocate +1 for '\0' */
2149 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 if (!command)
2151 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002152 hddLog(VOS_TRACE_LEVEL_ERROR,
2153 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002154 ret = -ENOMEM;
2155 goto exit;
2156 }
2157
2158 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2159 {
2160 ret = -EFAULT;
2161 goto exit;
2162 }
2163
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002164 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002165 command[priv_data.total_len] = '\0';
2166
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002167 /* at one time the following block of code was conditional. braces
2168 * have been retained to avoid re-indenting the legacy code
2169 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 {
2171 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2172
2173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002174 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002175
2176 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2177 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302178 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2179 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2180 pAdapter->sessionId, (unsigned)
2181 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2182 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2183 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2184 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002185 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2186 sizeof(tSirMacAddr)))
2187 {
2188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002189 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 ret = -EFAULT;
2191 }
2192 }
Amar Singhal0974e402013-02-12 14:27:46 -08002193 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002194 {
Amar Singhal0974e402013-02-12 14:27:46 -08002195 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002196
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002198
2199 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002202 "%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 -07002203 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002204 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302205 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302206 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002207 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002208 }
Kiet Lamf040f472013-11-20 21:15:23 +05302209 else if(strncmp(command, "SETWMMPS", 8) == 0)
2210 {
2211 tANI_U8 *ptr = command;
2212 ret = hdd_wmmps_helper(pAdapter, ptr);
2213 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002214 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2215 {
2216 char *country_code;
2217
2218 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002219
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002220 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002221 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002222#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302223 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002224#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002225 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2226 (void *)(tSmeChangeCountryCallback)
2227 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302228 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002229 if (eHAL_STATUS_SUCCESS == ret)
2230 {
2231 ret = wait_for_completion_interruptible_timeout(
2232 &pAdapter->change_country_code,
2233 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2234 if (0 >= ret)
2235 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302237 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002238 }
2239 }
2240 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002241 {
2242 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002243 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002244 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002245 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002246
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002247 }
2248 /*
2249 command should be a string having format
2250 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2251 */
Amar Singhal0974e402013-02-12 14:27:46 -08002252 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002253 {
Amar Singhal0974e402013-02-12 14:27:46 -08002254 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002255
2256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002257 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002258
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002259 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002260 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002261 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2262 {
2263 int suspend = 0;
2264 tANI_U8 *ptr = (tANI_U8*)command + 15;
2265
2266 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302267 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2268 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2269 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002270 hdd_set_wlan_suspend_mode(suspend);
2271 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002272#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2273 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2274 {
2275 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002276 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002277 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2278 eHalStatus status = eHAL_STATUS_SUCCESS;
2279
2280 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2281 value = value + 15;
2282
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002283 /* Convert the value from ascii to integer */
2284 ret = kstrtos8(value, 10, &rssi);
2285 if (ret < 0)
2286 {
2287 /* If the input value is greater than max value of datatype, then also
2288 kstrtou8 fails */
2289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2290 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002291 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002292 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2293 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2294 ret = -EINVAL;
2295 goto exit;
2296 }
2297
Srinivas Girigowdade697412013-02-14 16:31:48 -08002298 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002299
Srinivas Girigowdade697412013-02-14 16:31:48 -08002300 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2301 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2302 {
2303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2304 "Neighbor lookup threshold value %d is out of range"
2305 " (Min: %d Max: %d)", lookUpThreshold,
2306 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2307 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2308 ret = -EINVAL;
2309 goto exit;
2310 }
2311
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302312 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2313 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2314 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2316 "%s: Received Command to Set Roam trigger"
2317 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2318
2319 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2320 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2321 if (eHAL_STATUS_SUCCESS != status)
2322 {
2323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2324 "%s: Failed to set roam trigger, try again", __func__);
2325 ret = -EPERM;
2326 goto exit;
2327 }
2328
2329 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302330 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002331 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2332 }
2333 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2334 {
2335 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2336 int rssi = (-1) * lookUpThreshold;
2337 char extra[32];
2338 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302339 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2340 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2341 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002342 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002343 if (copy_to_user(priv_data.buf, &extra, len + 1))
2344 {
2345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2346 "%s: failed to copy data to user buffer", __func__);
2347 ret = -EFAULT;
2348 goto exit;
2349 }
2350 }
2351 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2352 {
2353 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002354 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002355 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002356
Srinivas Girigowdade697412013-02-14 16:31:48 -08002357 /* input refresh period is in terms of seconds */
2358 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2359 value = value + 18;
2360 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002361 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002362 if (ret < 0)
2363 {
2364 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002365 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002367 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002368 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002369 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2370 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002371 ret = -EINVAL;
2372 goto exit;
2373 }
2374
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002375 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2376 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002377 {
2378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002379 "Roam scan period value %d is out of range"
2380 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002381 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2382 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002383 ret = -EINVAL;
2384 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302385 }
2386 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2387 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2388 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002389 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002390
2391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2392 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002393 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002394
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002395 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2396 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397 }
2398 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2399 {
2400 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2401 char extra[32];
2402 tANI_U8 len = 0;
2403
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302404 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2405 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2406 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002407 len = scnprintf(extra, sizeof(extra), "%s %d",
2408 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002409 /* Returned value is in units of seconds */
2410 if (copy_to_user(priv_data.buf, &extra, len + 1))
2411 {
2412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: failed to copy data to user buffer", __func__);
2414 ret = -EFAULT;
2415 goto exit;
2416 }
2417 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002418 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2419 {
2420 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002421 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002422 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002423
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002424 /* input refresh period is in terms of seconds */
2425 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2426 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002427
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002428 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002429 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002430 if (ret < 0)
2431 {
2432 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002433 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002435 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002436 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002437 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2438 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2439 ret = -EINVAL;
2440 goto exit;
2441 }
2442
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002443 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2444 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2445 {
2446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2447 "Neighbor scan results refresh period value %d is out of range"
2448 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2449 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2450 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2451 ret = -EINVAL;
2452 goto exit;
2453 }
2454 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2455
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2457 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002458 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002459
2460 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2461 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2462 }
2463 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2464 {
2465 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2466 char extra[32];
2467 tANI_U8 len = 0;
2468
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002469 len = scnprintf(extra, sizeof(extra), "%s %d",
2470 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002471 /* Returned value is in units of seconds */
2472 if (copy_to_user(priv_data.buf, &extra, len + 1))
2473 {
2474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2475 "%s: failed to copy data to user buffer", __func__);
2476 ret = -EFAULT;
2477 goto exit;
2478 }
2479 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002480#ifdef FEATURE_WLAN_LFR
2481 /* SETROAMMODE */
2482 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2483 {
2484 tANI_U8 *value = command;
2485 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2486
2487 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2488 value = value + SIZE_OF_SETROAMMODE + 1;
2489
2490 /* Convert the value from ascii to integer */
2491 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2492 if (ret < 0)
2493 {
2494 /* If the input value is greater than max value of datatype, then also
2495 kstrtou8 fails */
2496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2497 "%s: kstrtou8 failed range [%d - %d]", __func__,
2498 CFG_LFR_FEATURE_ENABLED_MIN,
2499 CFG_LFR_FEATURE_ENABLED_MAX);
2500 ret = -EINVAL;
2501 goto exit;
2502 }
2503 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2504 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2505 {
2506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2507 "Roam Mode value %d is out of range"
2508 " (Min: %d Max: %d)", roamMode,
2509 CFG_LFR_FEATURE_ENABLED_MIN,
2510 CFG_LFR_FEATURE_ENABLED_MAX);
2511 ret = -EINVAL;
2512 goto exit;
2513 }
2514
2515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2516 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2517 /*
2518 * Note that
2519 * SETROAMMODE 0 is to enable LFR while
2520 * SETROAMMODE 1 is to disable LFR, but
2521 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2522 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2523 */
2524 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2525 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2526 else
2527 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2528
2529 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2530 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2531 }
2532 /* GETROAMMODE */
2533 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2534 {
2535 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2536 char extra[32];
2537 tANI_U8 len = 0;
2538
2539 /*
2540 * roamMode value shall be inverted because the sementics is different.
2541 */
2542 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2543 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2544 else
2545 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2546
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002547 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002548 if (copy_to_user(priv_data.buf, &extra, len + 1))
2549 {
2550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2551 "%s: failed to copy data to user buffer", __func__);
2552 ret = -EFAULT;
2553 goto exit;
2554 }
2555 }
2556#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002557#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002558#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002559 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2560 {
2561 tANI_U8 *value = command;
2562 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2563
2564 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2565 value = value + 13;
2566 /* Convert the value from ascii to integer */
2567 ret = kstrtou8(value, 10, &roamRssiDiff);
2568 if (ret < 0)
2569 {
2570 /* If the input value is greater than max value of datatype, then also
2571 kstrtou8 fails */
2572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2573 "%s: kstrtou8 failed range [%d - %d]", __func__,
2574 CFG_ROAM_RSSI_DIFF_MIN,
2575 CFG_ROAM_RSSI_DIFF_MAX);
2576 ret = -EINVAL;
2577 goto exit;
2578 }
2579
2580 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2581 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2582 {
2583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2584 "Roam rssi diff value %d is out of range"
2585 " (Min: %d Max: %d)", roamRssiDiff,
2586 CFG_ROAM_RSSI_DIFF_MIN,
2587 CFG_ROAM_RSSI_DIFF_MAX);
2588 ret = -EINVAL;
2589 goto exit;
2590 }
2591
2592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2593 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2594
2595 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2596 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2597 }
2598 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2599 {
2600 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2601 char extra[32];
2602 tANI_U8 len = 0;
2603
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302604 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2605 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2606 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002607 len = scnprintf(extra, sizeof(extra), "%s %d",
2608 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002609 if (copy_to_user(priv_data.buf, &extra, len + 1))
2610 {
2611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2612 "%s: failed to copy data to user buffer", __func__);
2613 ret = -EFAULT;
2614 goto exit;
2615 }
2616 }
2617#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002618#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002619 else if (strncmp(command, "GETBAND", 7) == 0)
2620 {
2621 int band = -1;
2622 char extra[32];
2623 tANI_U8 len = 0;
2624 hdd_getBand_helper(pHddCtx, &band);
2625
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302626 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2627 TRACE_CODE_HDD_GETBAND_IOCTL,
2628 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002629 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002630 if (copy_to_user(priv_data.buf, &extra, len + 1))
2631 {
2632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2633 "%s: failed to copy data to user buffer", __func__);
2634 ret = -EFAULT;
2635 goto exit;
2636 }
2637 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002638 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2639 {
2640 tANI_U8 *value = command;
2641 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2642 tANI_U8 numChannels = 0;
2643 eHalStatus status = eHAL_STATUS_SUCCESS;
2644
2645 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2646 if (eHAL_STATUS_SUCCESS != status)
2647 {
2648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2649 "%s: Failed to parse channel list information", __func__);
2650 ret = -EINVAL;
2651 goto exit;
2652 }
2653
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2655 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2656 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002657 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2658 {
2659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2660 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2661 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2662 ret = -EINVAL;
2663 goto exit;
2664 }
2665 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2666 numChannels);
2667 if (eHAL_STATUS_SUCCESS != status)
2668 {
2669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2670 "%s: Failed to update channel list information", __func__);
2671 ret = -EINVAL;
2672 goto exit;
2673 }
2674 }
2675 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2676 {
2677 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2678 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002679 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002681 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002682
2683 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2684 ChannelList, &numChannels ))
2685 {
2686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2687 "%s: failed to get roam scan channel list", __func__);
2688 ret = -EFAULT;
2689 goto exit;
2690 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302691 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2692 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2693 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002694 /* output channel list is of the format
2695 [Number of roam scan channels][Channel1][Channel2]... */
2696 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002697 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002698 for (j = 0; (j < numChannels); j++)
2699 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002700 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2701 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002702 }
2703
2704 if (copy_to_user(priv_data.buf, &extra, len + 1))
2705 {
2706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2707 "%s: failed to copy data to user buffer", __func__);
2708 ret = -EFAULT;
2709 goto exit;
2710 }
2711 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002712 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2713 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002714 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002715 char extra[32];
2716 tANI_U8 len = 0;
2717
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002718 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002719 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002720 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002721 hdd_is_okc_mode_enabled(pHddCtx) &&
2722 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2723 {
2724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002725 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002726 " hence this operation is not permitted!", __func__);
2727 ret = -EPERM;
2728 goto exit;
2729 }
2730
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002731 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002732 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002733 if (copy_to_user(priv_data.buf, &extra, len + 1))
2734 {
2735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2736 "%s: failed to copy data to user buffer", __func__);
2737 ret = -EFAULT;
2738 goto exit;
2739 }
2740 }
2741 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2742 {
2743 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2744 char extra[32];
2745 tANI_U8 len = 0;
2746
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002747 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002748 then this operation is not permitted (return FAILURE) */
2749 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002750 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002751 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002754 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002755 " hence this operation is not permitted!", __func__);
2756 ret = -EPERM;
2757 goto exit;
2758 }
2759
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002760 len = scnprintf(extra, sizeof(extra), "%s %d",
2761 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002762 if (copy_to_user(priv_data.buf, &extra, len + 1))
2763 {
2764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2765 "%s: failed to copy data to user buffer", __func__);
2766 ret = -EFAULT;
2767 goto exit;
2768 }
2769 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002770 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002771 {
2772 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2773 char extra[32];
2774 tANI_U8 len = 0;
2775
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002776 len = scnprintf(extra, sizeof(extra), "%s %d",
2777 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002778 if (copy_to_user(priv_data.buf, &extra, len + 1))
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: failed to copy data to user buffer", __func__);
2782 ret = -EFAULT;
2783 goto exit;
2784 }
2785 }
2786 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2787 {
2788 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2789 char extra[32];
2790 tANI_U8 len = 0;
2791
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002792 len = scnprintf(extra, sizeof(extra), "%s %d",
2793 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002794 if (copy_to_user(priv_data.buf, &extra, len + 1))
2795 {
2796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2797 "%s: failed to copy data to user buffer", __func__);
2798 ret = -EFAULT;
2799 goto exit;
2800 }
2801 }
2802 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2803 {
2804 tANI_U8 *value = command;
2805 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2806
2807 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2808 value = value + 26;
2809 /* Convert the value from ascii to integer */
2810 ret = kstrtou8(value, 10, &minTime);
2811 if (ret < 0)
2812 {
2813 /* If the input value is greater than max value of datatype, then also
2814 kstrtou8 fails */
2815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2816 "%s: kstrtou8 failed range [%d - %d]", __func__,
2817 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2818 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2819 ret = -EINVAL;
2820 goto exit;
2821 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002822 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2823 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2824 {
2825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2826 "scan min channel time value %d is out of range"
2827 " (Min: %d Max: %d)", minTime,
2828 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2829 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2830 ret = -EINVAL;
2831 goto exit;
2832 }
2833
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302834 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2835 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2836 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2838 "%s: Received Command to change channel min time = %d", __func__, minTime);
2839
2840 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2841 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2842 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002843 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2844 {
2845 tANI_U8 *value = command;
2846 tANI_U8 channel = 0;
2847 tANI_U8 dwellTime = 0;
2848 tANI_U8 bufLen = 0;
2849 tANI_U8 *buf = NULL;
2850 tSirMacAddr targetApBssid;
2851 eHalStatus status = eHAL_STATUS_SUCCESS;
2852 struct ieee80211_channel chan;
2853 tANI_U8 finalLen = 0;
2854 tANI_U8 *finalBuf = NULL;
2855 tANI_U8 temp = 0;
2856 u64 cookie;
2857 hdd_station_ctx_t *pHddStaCtx = NULL;
2858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2859
2860 /* if not associated, no need to send action frame */
2861 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2862 {
2863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2864 ret = -EINVAL;
2865 goto exit;
2866 }
2867
2868 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2869 &dwellTime, &buf, &bufLen);
2870 if (eHAL_STATUS_SUCCESS != status)
2871 {
2872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2873 "%s: Failed to parse send action frame data", __func__);
2874 ret = -EINVAL;
2875 goto exit;
2876 }
2877
2878 /* if the target bssid is different from currently associated AP,
2879 then no need to send action frame */
2880 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2881 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2882 {
2883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2884 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002885 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002886 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002887 goto exit;
2888 }
2889
2890 /* if the channel number is different from operating channel then
2891 no need to send action frame */
2892 if (channel != pHddStaCtx->conn_info.operationChannel)
2893 {
2894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2895 "%s: channel(%d) is different from operating channel(%d)",
2896 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2897 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002898 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002899 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002900 goto exit;
2901 }
2902 chan.center_freq = sme_ChnToFreq(channel);
2903
2904 finalLen = bufLen + 24;
2905 finalBuf = vos_mem_malloc(finalLen);
2906 if (NULL == finalBuf)
2907 {
2908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2909 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002910 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002911 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002912 goto exit;
2913 }
2914 vos_mem_zero(finalBuf, finalLen);
2915
2916 /* Fill subtype */
2917 temp = SIR_MAC_MGMT_ACTION << 4;
2918 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2919
2920 /* Fill type */
2921 temp = SIR_MAC_MGMT_FRAME;
2922 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2923
2924 /* Fill destination address (bssid of the AP) */
2925 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2926
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002927 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002928 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2929
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002930 /* Fill BSSID (AP mac address) */
2931 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002932
2933 /* Fill received buffer from 24th address */
2934 vos_mem_copy(finalBuf + 24, buf, bufLen);
2935
Jeff Johnson11c33152013-04-16 17:52:40 -07002936 /* done with the parsed buffer */
2937 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002938 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002939
DARAM SUDHA39eede62014-02-12 11:16:40 +05302940 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2942 &(pAdapter->wdev),
2943#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002944 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002945#endif
2946 &chan, 0,
2947#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2948 NL80211_CHAN_HT20, 1,
2949#endif
2950 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002951 1, &cookie );
2952 vos_mem_free(finalBuf);
2953 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002954 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2955 {
2956 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2957 char extra[32];
2958 tANI_U8 len = 0;
2959
2960 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002961 len = scnprintf(extra, sizeof(extra), "%s %d",
2962 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302963 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2964 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2965 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002966 if (copy_to_user(priv_data.buf, &extra, len + 1))
2967 {
2968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2969 "%s: failed to copy data to user buffer", __func__);
2970 ret = -EFAULT;
2971 goto exit;
2972 }
2973 }
2974 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2975 {
2976 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002977 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002978
2979 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2980 value = value + 19;
2981 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002982 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002983 if (ret < 0)
2984 {
2985 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002986 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002988 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002989 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2990 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2991 ret = -EINVAL;
2992 goto exit;
2993 }
2994
2995 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2996 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2997 {
2998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "lfr mode value %d is out of range"
3000 " (Min: %d Max: %d)", maxTime,
3001 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3002 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3003 ret = -EINVAL;
3004 goto exit;
3005 }
3006
3007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3008 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3009
3010 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3011 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3012 }
3013 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3014 {
3015 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3016 char extra[32];
3017 tANI_U8 len = 0;
3018
3019 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003020 len = scnprintf(extra, sizeof(extra), "%s %d",
3021 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003022 if (copy_to_user(priv_data.buf, &extra, len + 1))
3023 {
3024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3025 "%s: failed to copy data to user buffer", __func__);
3026 ret = -EFAULT;
3027 goto exit;
3028 }
3029 }
3030 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3031 {
3032 tANI_U8 *value = command;
3033 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3034
3035 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3036 value = value + 16;
3037 /* Convert the value from ascii to integer */
3038 ret = kstrtou16(value, 10, &val);
3039 if (ret < 0)
3040 {
3041 /* If the input value is greater than max value of datatype, then also
3042 kstrtou16 fails */
3043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3044 "%s: kstrtou16 failed range [%d - %d]", __func__,
3045 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3046 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3047 ret = -EINVAL;
3048 goto exit;
3049 }
3050
3051 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3052 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3053 {
3054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3055 "scan home time value %d is out of range"
3056 " (Min: %d Max: %d)", val,
3057 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3058 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3059 ret = -EINVAL;
3060 goto exit;
3061 }
3062
3063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3064 "%s: Received Command to change scan home time = %d", __func__, val);
3065
3066 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3067 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3068 }
3069 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3070 {
3071 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3072 char extra[32];
3073 tANI_U8 len = 0;
3074
3075 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003076 len = scnprintf(extra, sizeof(extra), "%s %d",
3077 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003078 if (copy_to_user(priv_data.buf, &extra, len + 1))
3079 {
3080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3081 "%s: failed to copy data to user buffer", __func__);
3082 ret = -EFAULT;
3083 goto exit;
3084 }
3085 }
3086 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3087 {
3088 tANI_U8 *value = command;
3089 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3090
3091 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3092 value = value + 17;
3093 /* Convert the value from ascii to integer */
3094 ret = kstrtou8(value, 10, &val);
3095 if (ret < 0)
3096 {
3097 /* If the input value is greater than max value of datatype, then also
3098 kstrtou8 fails */
3099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3100 "%s: kstrtou8 failed range [%d - %d]", __func__,
3101 CFG_ROAM_INTRA_BAND_MIN,
3102 CFG_ROAM_INTRA_BAND_MAX);
3103 ret = -EINVAL;
3104 goto exit;
3105 }
3106
3107 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3108 (val > CFG_ROAM_INTRA_BAND_MAX))
3109 {
3110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3111 "intra band mode value %d is out of range"
3112 " (Min: %d Max: %d)", val,
3113 CFG_ROAM_INTRA_BAND_MIN,
3114 CFG_ROAM_INTRA_BAND_MAX);
3115 ret = -EINVAL;
3116 goto exit;
3117 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3119 "%s: Received Command to change intra band = %d", __func__, val);
3120
3121 pHddCtx->cfg_ini->nRoamIntraBand = val;
3122 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3123 }
3124 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3125 {
3126 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3127 char extra[32];
3128 tANI_U8 len = 0;
3129
3130 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003131 len = scnprintf(extra, sizeof(extra), "%s %d",
3132 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003133 if (copy_to_user(priv_data.buf, &extra, len + 1))
3134 {
3135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3136 "%s: failed to copy data to user buffer", __func__);
3137 ret = -EFAULT;
3138 goto exit;
3139 }
3140 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003141 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3142 {
3143 tANI_U8 *value = command;
3144 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3145
3146 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3147 value = value + 15;
3148 /* Convert the value from ascii to integer */
3149 ret = kstrtou8(value, 10, &nProbes);
3150 if (ret < 0)
3151 {
3152 /* If the input value is greater than max value of datatype, then also
3153 kstrtou8 fails */
3154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3155 "%s: kstrtou8 failed range [%d - %d]", __func__,
3156 CFG_ROAM_SCAN_N_PROBES_MIN,
3157 CFG_ROAM_SCAN_N_PROBES_MAX);
3158 ret = -EINVAL;
3159 goto exit;
3160 }
3161
3162 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3163 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3164 {
3165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3166 "NProbes value %d is out of range"
3167 " (Min: %d Max: %d)", nProbes,
3168 CFG_ROAM_SCAN_N_PROBES_MIN,
3169 CFG_ROAM_SCAN_N_PROBES_MAX);
3170 ret = -EINVAL;
3171 goto exit;
3172 }
3173
3174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3175 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3176
3177 pHddCtx->cfg_ini->nProbes = nProbes;
3178 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3179 }
3180 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3181 {
3182 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3183 char extra[32];
3184 tANI_U8 len = 0;
3185
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003186 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003187 if (copy_to_user(priv_data.buf, &extra, len + 1))
3188 {
3189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3190 "%s: failed to copy data to user buffer", __func__);
3191 ret = -EFAULT;
3192 goto exit;
3193 }
3194 }
3195 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3196 {
3197 tANI_U8 *value = command;
3198 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3199
3200 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3201 /* input value is in units of msec */
3202 value = value + 20;
3203 /* Convert the value from ascii to integer */
3204 ret = kstrtou16(value, 10, &homeAwayTime);
3205 if (ret < 0)
3206 {
3207 /* If the input value is greater than max value of datatype, then also
3208 kstrtou8 fails */
3209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3210 "%s: kstrtou8 failed range [%d - %d]", __func__,
3211 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3212 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3213 ret = -EINVAL;
3214 goto exit;
3215 }
3216
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003217 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3218 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3219 {
3220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3221 "homeAwayTime value %d is out of range"
3222 " (Min: %d Max: %d)", homeAwayTime,
3223 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3224 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3225 ret = -EINVAL;
3226 goto exit;
3227 }
3228
3229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3230 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003231 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3232 {
3233 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3234 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3235 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003236 }
3237 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3238 {
3239 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3240 char extra[32];
3241 tANI_U8 len = 0;
3242
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003243 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003244 if (copy_to_user(priv_data.buf, &extra, len + 1))
3245 {
3246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3247 "%s: failed to copy data to user buffer", __func__);
3248 ret = -EFAULT;
3249 goto exit;
3250 }
3251 }
3252 else if (strncmp(command, "REASSOC", 7) == 0)
3253 {
3254 tANI_U8 *value = command;
3255 tANI_U8 channel = 0;
3256 tSirMacAddr targetApBssid;
3257 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003258#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3259 tCsrHandoffRequest handoffInfo;
3260#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003261 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003262 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3263
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003264 /* if not associated, no need to proceed with reassoc */
3265 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3266 {
3267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3268 ret = -EINVAL;
3269 goto exit;
3270 }
3271
3272 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3273 if (eHAL_STATUS_SUCCESS != status)
3274 {
3275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3276 "%s: Failed to parse reassoc command data", __func__);
3277 ret = -EINVAL;
3278 goto exit;
3279 }
3280
3281 /* if the target bssid is same as currently associated AP,
3282 then no need to proceed with reassoc */
3283 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3284 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3285 {
3286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3287 ret = -EINVAL;
3288 goto exit;
3289 }
3290
3291 /* Check channel number is a valid channel number */
3292 if(VOS_STATUS_SUCCESS !=
3293 wlan_hdd_validate_operation_channel(pAdapter, channel))
3294 {
3295 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003296 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003297 return -EINVAL;
3298 }
3299
3300 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003301#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3302 handoffInfo.channel = channel;
3303 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3304 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3305#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003306 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003307 else if (strncmp(command, "SETWESMODE", 10) == 0)
3308 {
3309 tANI_U8 *value = command;
3310 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3311
3312 /* Move pointer to ahead of SETWESMODE<delimiter> */
3313 value = value + 11;
3314 /* Convert the value from ascii to integer */
3315 ret = kstrtou8(value, 10, &wesMode);
3316 if (ret < 0)
3317 {
3318 /* If the input value is greater than max value of datatype, then also
3319 kstrtou8 fails */
3320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3321 "%s: kstrtou8 failed range [%d - %d]", __func__,
3322 CFG_ENABLE_WES_MODE_NAME_MIN,
3323 CFG_ENABLE_WES_MODE_NAME_MAX);
3324 ret = -EINVAL;
3325 goto exit;
3326 }
3327
3328 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3329 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3330 {
3331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3332 "WES Mode value %d is out of range"
3333 " (Min: %d Max: %d)", wesMode,
3334 CFG_ENABLE_WES_MODE_NAME_MIN,
3335 CFG_ENABLE_WES_MODE_NAME_MAX);
3336 ret = -EINVAL;
3337 goto exit;
3338 }
3339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3340 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3341
3342 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3343 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3344 }
3345 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3346 {
3347 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3348 char extra[32];
3349 tANI_U8 len = 0;
3350
Arif Hussain826d9412013-11-12 16:44:54 -08003351 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003352 if (copy_to_user(priv_data.buf, &extra, len + 1))
3353 {
3354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3355 "%s: failed to copy data to user buffer", __func__);
3356 ret = -EFAULT;
3357 goto exit;
3358 }
3359 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003360#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003361#ifdef FEATURE_WLAN_LFR
3362 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3363 {
3364 tANI_U8 *value = command;
3365 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3366
3367 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3368 value = value + 12;
3369 /* Convert the value from ascii to integer */
3370 ret = kstrtou8(value, 10, &lfrMode);
3371 if (ret < 0)
3372 {
3373 /* If the input value is greater than max value of datatype, then also
3374 kstrtou8 fails */
3375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3376 "%s: kstrtou8 failed range [%d - %d]", __func__,
3377 CFG_LFR_FEATURE_ENABLED_MIN,
3378 CFG_LFR_FEATURE_ENABLED_MAX);
3379 ret = -EINVAL;
3380 goto exit;
3381 }
3382
3383 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3384 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3385 {
3386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3387 "lfr mode value %d is out of range"
3388 " (Min: %d Max: %d)", lfrMode,
3389 CFG_LFR_FEATURE_ENABLED_MIN,
3390 CFG_LFR_FEATURE_ENABLED_MAX);
3391 ret = -EINVAL;
3392 goto exit;
3393 }
3394
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3396 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3397
3398 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3399 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3400 }
3401#endif
3402#ifdef WLAN_FEATURE_VOWIFI_11R
3403 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3404 {
3405 tANI_U8 *value = command;
3406 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3407
3408 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3409 value = value + 18;
3410 /* Convert the value from ascii to integer */
3411 ret = kstrtou8(value, 10, &ft);
3412 if (ret < 0)
3413 {
3414 /* If the input value is greater than max value of datatype, then also
3415 kstrtou8 fails */
3416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3417 "%s: kstrtou8 failed range [%d - %d]", __func__,
3418 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3419 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3420 ret = -EINVAL;
3421 goto exit;
3422 }
3423
3424 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3425 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3426 {
3427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3428 "ft mode value %d is out of range"
3429 " (Min: %d Max: %d)", ft,
3430 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3431 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3432 ret = -EINVAL;
3433 goto exit;
3434 }
3435
3436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3437 "%s: Received Command to change ft mode = %d", __func__, ft);
3438
3439 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3440 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3441 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303442
3443 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3444 {
3445 tANI_U8 *value = command;
3446 tSirMacAddr targetApBssid;
3447 tANI_U8 trigger = 0;
3448 eHalStatus status = eHAL_STATUS_SUCCESS;
3449 hdd_station_ctx_t *pHddStaCtx = NULL;
3450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3451
3452 /* if not associated, no need to proceed with reassoc */
3453 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3454 {
3455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3456 ret = -EINVAL;
3457 goto exit;
3458 }
3459
3460 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3461 if (eHAL_STATUS_SUCCESS != status)
3462 {
3463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3464 "%s: Failed to parse reassoc command data", __func__);
3465 ret = -EINVAL;
3466 goto exit;
3467 }
3468
3469 /* if the target bssid is same as currently associated AP,
3470 then no need to proceed with reassoc */
3471 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3472 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3473 {
3474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3475 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3476 __func__);
3477 ret = -EINVAL;
3478 goto exit;
3479 }
3480
3481 /* Proceed with scan/roam */
3482 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3483 &targetApBssid[0],
3484 (tSmeFastRoamTrigger)(trigger));
3485 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003486#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003487#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003488 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3489 {
3490 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003491 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003492
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003493 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003494 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003495 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003496 hdd_is_okc_mode_enabled(pHddCtx) &&
3497 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3498 {
3499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003500 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003501 " hence this operation is not permitted!", __func__);
3502 ret = -EPERM;
3503 goto exit;
3504 }
3505
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003506 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3507 value = value + 11;
3508 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003509 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003510 if (ret < 0)
3511 {
3512 /* If the input value is greater than max value of datatype, then also
3513 kstrtou8 fails */
3514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3515 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003516 CFG_ESE_FEATURE_ENABLED_MIN,
3517 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003518 ret = -EINVAL;
3519 goto exit;
3520 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003521 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3522 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003523 {
3524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003525 "Ese mode value %d is out of range"
3526 " (Min: %d Max: %d)", eseMode,
3527 CFG_ESE_FEATURE_ENABLED_MIN,
3528 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003529 ret = -EINVAL;
3530 goto exit;
3531 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003533 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003534
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003535 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3536 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003537 }
3538#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003539 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3540 {
3541 tANI_U8 *value = command;
3542 tANI_BOOLEAN roamScanControl = 0;
3543
3544 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3545 value = value + 19;
3546 /* Convert the value from ascii to integer */
3547 ret = kstrtou8(value, 10, &roamScanControl);
3548 if (ret < 0)
3549 {
3550 /* If the input value is greater than max value of datatype, then also
3551 kstrtou8 fails */
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "%s: kstrtou8 failed ", __func__);
3554 ret = -EINVAL;
3555 goto exit;
3556 }
3557
3558 if (0 != roamScanControl)
3559 {
3560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3561 "roam scan control invalid value = %d",
3562 roamScanControl);
3563 ret = -EINVAL;
3564 goto exit;
3565 }
3566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3567 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3568
3569 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3570 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003571#ifdef FEATURE_WLAN_OKC
3572 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3573 {
3574 tANI_U8 *value = command;
3575 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3576
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003577 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003578 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003579 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003580 hdd_is_okc_mode_enabled(pHddCtx) &&
3581 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3582 {
3583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003584 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003585 " hence this operation is not permitted!", __func__);
3586 ret = -EPERM;
3587 goto exit;
3588 }
3589
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003590 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3591 value = value + 11;
3592 /* Convert the value from ascii to integer */
3593 ret = kstrtou8(value, 10, &okcMode);
3594 if (ret < 0)
3595 {
3596 /* If the input value is greater than max value of datatype, then also
3597 kstrtou8 fails */
3598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3599 "%s: kstrtou8 failed range [%d - %d]", __func__,
3600 CFG_OKC_FEATURE_ENABLED_MIN,
3601 CFG_OKC_FEATURE_ENABLED_MAX);
3602 ret = -EINVAL;
3603 goto exit;
3604 }
3605
3606 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3607 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3608 {
3609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3610 "Okc mode value %d is out of range"
3611 " (Min: %d Max: %d)", okcMode,
3612 CFG_OKC_FEATURE_ENABLED_MIN,
3613 CFG_OKC_FEATURE_ENABLED_MAX);
3614 ret = -EINVAL;
3615 goto exit;
3616 }
3617
3618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3619 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3620
3621 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3622 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003623#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003624 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3625 {
3626 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3627 char extra[32];
3628 tANI_U8 len = 0;
3629
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003630 len = scnprintf(extra, sizeof(extra), "%s %d",
3631 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003632 if (copy_to_user(priv_data.buf, &extra, len + 1))
3633 {
3634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3635 "%s: failed to copy data to user buffer", __func__);
3636 ret = -EFAULT;
3637 goto exit;
3638 }
3639 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303640#ifdef WLAN_FEATURE_PACKET_FILTERING
3641 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3642 {
3643 tANI_U8 filterType = 0;
3644 tANI_U8 *value = command;
3645
3646 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3647 value = value + 22;
3648
3649 /* Convert the value from ascii to integer */
3650 ret = kstrtou8(value, 10, &filterType);
3651 if (ret < 0)
3652 {
3653 /* If the input value is greater than max value of datatype,
3654 * then also kstrtou8 fails
3655 */
3656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3657 "%s: kstrtou8 failed range ", __func__);
3658 ret = -EINVAL;
3659 goto exit;
3660 }
3661
3662 if (filterType != 0 && filterType != 1)
3663 {
3664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3665 "%s: Accepted Values are 0 and 1 ", __func__);
3666 ret = -EINVAL;
3667 goto exit;
3668 }
3669 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3670 pAdapter->sessionId);
3671 }
3672#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303673 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3674 {
Kiet Lamad161252014-07-22 11:23:32 -07003675 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303676 int ret;
3677
Kiet Lamad161252014-07-22 11:23:32 -07003678 dhcpPhase = command + 11;
3679 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303680 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003682 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303683
3684 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003685
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303686 ret = wlan_hdd_scan_abort(pAdapter);
3687 if (ret < 0)
3688 {
3689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3690 FL("failed to abort existing scan %d"), ret);
3691 }
3692
Kiet Lamad161252014-07-22 11:23:32 -07003693 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3694 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303695 }
Kiet Lamad161252014-07-22 11:23:32 -07003696 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303697 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003699 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303700
3701 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003702
3703 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3704 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303705 }
3706 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003707 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3708 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3710 FL("making default scan to ACTIVE"));
3711 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003712 }
3713 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3714 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3716 FL("making default scan to PASSIVE"));
3717 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003718 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303719 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3720 {
3721 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3722 char extra[32];
3723 tANI_U8 len = 0;
3724
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303725 memset(extra, 0, sizeof(extra));
3726 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3727 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303728 {
3729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3730 "%s: failed to copy data to user buffer", __func__);
3731 ret = -EFAULT;
3732 goto exit;
3733 }
3734 ret = len;
3735 }
3736 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3737 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303738 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303739 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003740 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3741 {
3742 tANI_U8 filterType = 0;
3743 tANI_U8 *value;
3744 value = command + 9;
3745
3746 /* Convert the value from ascii to integer */
3747 ret = kstrtou8(value, 10, &filterType);
3748 if (ret < 0)
3749 {
3750 /* If the input value is greater than max value of datatype,
3751 * then also kstrtou8 fails
3752 */
3753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3754 "%s: kstrtou8 failed range ", __func__);
3755 ret = -EINVAL;
3756 goto exit;
3757 }
3758 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3759 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3760 {
3761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3762 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3763 " 2-Sink ", __func__);
3764 ret = -EINVAL;
3765 goto exit;
3766 }
3767 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3768 pHddCtx->drvr_miracast = filterType;
3769 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303770 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003771 }
Leo Chang614d2072013-08-22 14:59:44 -07003772 else if (strncmp(command, "SETMCRATE", 9) == 0)
3773 {
Leo Chang614d2072013-08-22 14:59:44 -07003774 tANI_U8 *value = command;
3775 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003776 tSirRateUpdateInd *rateUpdate;
3777 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003778
3779 /* Only valid for SAP mode */
3780 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3781 {
3782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3783 "%s: SAP mode is not running", __func__);
3784 ret = -EFAULT;
3785 goto exit;
3786 }
3787
3788 /* Move pointer to ahead of SETMCRATE<delimiter> */
3789 /* input value is in units of hundred kbps */
3790 value = value + 10;
3791 /* Convert the value from ascii to integer, decimal base */
3792 ret = kstrtouint(value, 10, &targetRate);
3793
Leo Chang1f98cbd2013-10-17 15:03:52 -07003794 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3795 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003796 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003797 hddLog(VOS_TRACE_LEVEL_ERROR,
3798 "%s: SETMCRATE indication alloc fail", __func__);
3799 ret = -EFAULT;
3800 goto exit;
3801 }
3802 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3803
3804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3805 "MC Target rate %d", targetRate);
3806 /* Ignore unicast */
3807 rateUpdate->ucastDataRate = -1;
3808 rateUpdate->mcastDataRate24GHz = targetRate;
3809 rateUpdate->mcastDataRate5GHz = targetRate;
3810 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3811 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3812 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3813 if (eHAL_STATUS_SUCCESS != status)
3814 {
3815 hddLog(VOS_TRACE_LEVEL_ERROR,
3816 "%s: SET_MC_RATE failed", __func__);
3817 vos_mem_free(rateUpdate);
3818 ret = -EFAULT;
3819 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003820 }
3821 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303822#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003823 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303824 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003825 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303826 }
3827#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003828#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003829 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3830 {
3831 tANI_U8 *value = command;
3832 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3833 tANI_U8 numChannels = 0;
3834 eHalStatus status = eHAL_STATUS_SUCCESS;
3835
3836 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3837 if (eHAL_STATUS_SUCCESS != status)
3838 {
3839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3840 "%s: Failed to parse channel list information", __func__);
3841 ret = -EINVAL;
3842 goto exit;
3843 }
3844
3845 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3846 {
3847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3848 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3849 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3850 ret = -EINVAL;
3851 goto exit;
3852 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003853 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003854 ChannelList,
3855 numChannels);
3856 if (eHAL_STATUS_SUCCESS != status)
3857 {
3858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3859 "%s: Failed to update channel list information", __func__);
3860 ret = -EINVAL;
3861 goto exit;
3862 }
3863 }
3864 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3865 {
3866 tANI_U8 *value = command;
3867 char extra[128] = {0};
3868 int len = 0;
3869 tANI_U8 tid = 0;
3870 hdd_station_ctx_t *pHddStaCtx = NULL;
3871 tAniTrafStrmMetrics tsmMetrics;
3872 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3873
3874 /* if not associated, return error */
3875 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3876 {
3877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3878 ret = -EINVAL;
3879 goto exit;
3880 }
3881
3882 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3883 value = value + 12;
3884 /* Convert the value from ascii to integer */
3885 ret = kstrtou8(value, 10, &tid);
3886 if (ret < 0)
3887 {
3888 /* If the input value is greater than max value of datatype, then also
3889 kstrtou8 fails */
3890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3891 "%s: kstrtou8 failed range [%d - %d]", __func__,
3892 TID_MIN_VALUE,
3893 TID_MAX_VALUE);
3894 ret = -EINVAL;
3895 goto exit;
3896 }
3897
3898 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3899 {
3900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3901 "tid value %d is out of range"
3902 " (Min: %d Max: %d)", tid,
3903 TID_MIN_VALUE,
3904 TID_MAX_VALUE);
3905 ret = -EINVAL;
3906 goto exit;
3907 }
3908
3909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3910 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3911
3912 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3913 {
3914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3915 "%s: failed to get tsm stats", __func__);
3916 ret = -EFAULT;
3917 goto exit;
3918 }
3919
3920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3921 "UplinkPktQueueDly(%d)\n"
3922 "UplinkPktQueueDlyHist[0](%d)\n"
3923 "UplinkPktQueueDlyHist[1](%d)\n"
3924 "UplinkPktQueueDlyHist[2](%d)\n"
3925 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303926 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003927 "UplinkPktLoss(%d)\n"
3928 "UplinkPktCount(%d)\n"
3929 "RoamingCount(%d)\n"
3930 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3931 tsmMetrics.UplinkPktQueueDlyHist[0],
3932 tsmMetrics.UplinkPktQueueDlyHist[1],
3933 tsmMetrics.UplinkPktQueueDlyHist[2],
3934 tsmMetrics.UplinkPktQueueDlyHist[3],
3935 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3936 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3937
3938 /* Output TSM stats is of the format
3939 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3940 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003941 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003942 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3943 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3944 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3945 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3946 tsmMetrics.RoamingDly);
3947
3948 if (copy_to_user(priv_data.buf, &extra, len + 1))
3949 {
3950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3951 "%s: failed to copy data to user buffer", __func__);
3952 ret = -EFAULT;
3953 goto exit;
3954 }
3955 }
3956 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3957 {
3958 tANI_U8 *value = command;
3959 tANI_U8 *cckmIe = NULL;
3960 tANI_U8 cckmIeLen = 0;
3961 eHalStatus status = eHAL_STATUS_SUCCESS;
3962
3963 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3964 if (eHAL_STATUS_SUCCESS != status)
3965 {
3966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3967 "%s: Failed to parse cckm ie data", __func__);
3968 ret = -EINVAL;
3969 goto exit;
3970 }
3971
3972 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3973 {
3974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3975 "%s: CCKM Ie input length is more than max[%d]", __func__,
3976 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003977 vos_mem_free(cckmIe);
3978 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003979 ret = -EINVAL;
3980 goto exit;
3981 }
3982 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003983 vos_mem_free(cckmIe);
3984 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003985 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003986 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3987 {
3988 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003989 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003990 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003991
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003992 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003993 if (eHAL_STATUS_SUCCESS != status)
3994 {
3995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003996 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003997 ret = -EINVAL;
3998 goto exit;
3999 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004000 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4001 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4002 hdd_indicateEseBcnReportNoResults (pAdapter,
4003 eseBcnReq.bcnReq[0].measurementToken,
4004 0x02, //BIT(1) set for measurement done
4005 0); // no BSS
4006 goto exit;
4007 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004008
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004009 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4010 if (eHAL_STATUS_SUCCESS != status)
4011 {
4012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4013 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4014 ret = -EINVAL;
4015 goto exit;
4016 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004017 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004018#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304019 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4020 {
4021 eHalStatus status;
4022 char buf[32], len;
4023 long waitRet;
4024 bcnMissRateContext_t getBcnMissRateCtx;
4025
4026 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4027
4028 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4029 {
4030 hddLog(VOS_TRACE_LEVEL_WARN,
4031 FL("GETBCNMISSRATE: STA is not in connected state"));
4032 ret = -1;
4033 goto exit;
4034 }
4035
4036 init_completion(&(getBcnMissRateCtx.completion));
4037 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4038
4039 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4040 pAdapter->sessionId,
4041 (void *)getBcnMissRateCB,
4042 (void *)(&getBcnMissRateCtx));
4043 if( eHAL_STATUS_SUCCESS != status)
4044 {
4045 hddLog(VOS_TRACE_LEVEL_INFO,
4046 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4047 ret = -EINVAL;
4048 goto exit;
4049 }
4050
4051 waitRet = wait_for_completion_interruptible_timeout
4052 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4053 if(waitRet <= 0)
4054 {
4055 hddLog(VOS_TRACE_LEVEL_ERROR,
4056 FL("failed to wait on bcnMissRateComp %d"), ret);
4057
4058 //Make magic number to zero so that callback is not called.
4059 spin_lock(&hdd_context_lock);
4060 getBcnMissRateCtx.magic = 0x0;
4061 spin_unlock(&hdd_context_lock);
4062 ret = -EINVAL;
4063 goto exit;
4064 }
4065
4066 hddLog(VOS_TRACE_LEVEL_INFO,
4067 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4068
4069 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4070 if (copy_to_user(priv_data.buf, &buf, len + 1))
4071 {
4072 hddLog(VOS_TRACE_LEVEL_ERROR,
4073 "%s: failed to copy data to user buffer", __func__);
4074 ret = -EFAULT;
4075 goto exit;
4076 }
4077 ret = len;
4078 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004079 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4081 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4082 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004083 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4084 __func__, command);
4085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004086 }
4087exit:
4088 if (command)
4089 {
4090 kfree(command);
4091 }
4092 return ret;
4093}
4094
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004095#ifdef CONFIG_COMPAT
4096static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4097{
4098 struct {
4099 compat_uptr_t buf;
4100 int used_len;
4101 int total_len;
4102 } compat_priv_data;
4103 hdd_priv_data_t priv_data;
4104 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004105
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004106 /*
4107 * Note that pAdapter and ifr have already been verified by caller,
4108 * and HDD context has also been validated
4109 */
4110 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4111 sizeof(compat_priv_data))) {
4112 ret = -EFAULT;
4113 goto exit;
4114 }
4115 priv_data.buf = compat_ptr(compat_priv_data.buf);
4116 priv_data.used_len = compat_priv_data.used_len;
4117 priv_data.total_len = compat_priv_data.total_len;
4118 ret = hdd_driver_command(pAdapter, &priv_data);
4119 exit:
4120 return ret;
4121}
4122#else /* CONFIG_COMPAT */
4123static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4124{
4125 /* will never be invoked */
4126 return 0;
4127}
4128#endif /* CONFIG_COMPAT */
4129
4130static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4131{
4132 hdd_priv_data_t priv_data;
4133 int ret = 0;
4134
4135 /*
4136 * Note that pAdapter and ifr have already been verified by caller,
4137 * and HDD context has also been validated
4138 */
4139 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4140 ret = -EFAULT;
4141 } else {
4142 ret = hdd_driver_command(pAdapter, &priv_data);
4143 }
4144 return ret;
4145}
4146
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304147int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004148{
4149 hdd_adapter_t *pAdapter;
4150 hdd_context_t *pHddCtx;
4151 int ret;
4152
4153 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4154 if (NULL == pAdapter) {
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4156 "%s: HDD adapter context is Null", __func__);
4157 ret = -ENODEV;
4158 goto exit;
4159 }
4160 if (dev != pAdapter->dev) {
4161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4162 "%s: HDD adapter/dev inconsistency", __func__);
4163 ret = -ENODEV;
4164 goto exit;
4165 }
4166
4167 if ((!ifr) || (!ifr->ifr_data)) {
4168 ret = -EINVAL;
4169 goto exit;
4170 }
4171
4172 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4173 ret = wlan_hdd_validate_context(pHddCtx);
4174 if (ret) {
4175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4176 "%s: invalid context", __func__);
4177 ret = -EBUSY;
4178 goto exit;
4179 }
4180
4181 switch (cmd) {
4182 case (SIOCDEVPRIVATE + 1):
4183 if (is_compat_task())
4184 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4185 else
4186 ret = hdd_driver_ioctl(pAdapter, ifr);
4187 break;
4188 default:
4189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4190 __func__, cmd);
4191 ret = -EINVAL;
4192 break;
4193 }
4194 exit:
4195 return ret;
4196}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004197
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304198int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4199{
4200 int ret;
4201
4202 vos_ssr_protect(__func__);
4203 ret = __hdd_ioctl(dev, ifr, cmd);
4204 vos_ssr_unprotect(__func__);
4205
4206 return ret;
4207}
4208
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004209#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004210/**---------------------------------------------------------------------------
4211
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004212 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004213
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004214 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004215 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4216 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4217 <space>Scan Mode N<space>Meas Duration N
4218 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4219 then take N.
4220 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4221 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4222 This function does not take care of removing duplicate channels from the list
4223
4224 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004225 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004226
4227 \return - 0 for success non-zero for failure
4228
4229 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004230static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4231 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004232{
4233 tANI_U8 *inPtr = pValue;
4234 int tempInt = 0;
4235 int j = 0, i = 0, v = 0;
4236 char buf[32];
4237
4238 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4239 /*no argument after the command*/
4240 if (NULL == inPtr)
4241 {
4242 return -EINVAL;
4243 }
4244 /*no space after the command*/
4245 else if (SPACE_ASCII_VALUE != *inPtr)
4246 {
4247 return -EINVAL;
4248 }
4249
4250 /*removing empty spaces*/
4251 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4252
4253 /*no argument followed by spaces*/
4254 if ('\0' == *inPtr) return -EINVAL;
4255
4256 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004257 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004258 if (1 != v) return -EINVAL;
4259
4260 v = kstrtos32(buf, 10, &tempInt);
4261 if ( v < 0) return -EINVAL;
4262
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004263 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004264
4265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004266 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004267
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004268 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004269 {
4270 for (i = 0; i < 4; i++)
4271 {
4272 /*inPtr pointing to the beginning of first space after number of ie fields*/
4273 inPtr = strpbrk( inPtr, " " );
4274 /*no ie data after the number of ie fields argument*/
4275 if (NULL == inPtr) return -EINVAL;
4276
4277 /*removing empty space*/
4278 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4279
4280 /*no ie data after the number of ie fields argument and spaces*/
4281 if ( '\0' == *inPtr ) return -EINVAL;
4282
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004283 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004284 if (1 != v) return -EINVAL;
4285
4286 v = kstrtos32(buf, 10, &tempInt);
4287 if (v < 0) return -EINVAL;
4288
4289 switch (i)
4290 {
4291 case 0: /* Measurement token */
4292 if (tempInt <= 0)
4293 {
4294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4295 "Invalid Measurement Token(%d)", tempInt);
4296 return -EINVAL;
4297 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004298 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004299 break;
4300
4301 case 1: /* Channel number */
4302 if ((tempInt <= 0) ||
4303 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4304 {
4305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4306 "Invalid Channel Number(%d)", tempInt);
4307 return -EINVAL;
4308 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004309 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004310 break;
4311
4312 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004313 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004314 {
4315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4316 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4317 return -EINVAL;
4318 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004319 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004320 break;
4321
4322 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004323 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4324 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004325 {
4326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4327 "Invalid Measurement Duration(%d)", tempInt);
4328 return -EINVAL;
4329 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004330 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004331 break;
4332 }
4333 }
4334 }
4335
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004336 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004337 {
4338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304339 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004340 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004341 pEseBcnReq->bcnReq[j].measurementToken,
4342 pEseBcnReq->bcnReq[j].channel,
4343 pEseBcnReq->bcnReq[j].scanMode,
4344 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004345 }
4346
4347 return VOS_STATUS_SUCCESS;
4348}
4349
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004350static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4351{
4352 struct statsContext *pStatsContext = NULL;
4353 hdd_adapter_t *pAdapter = NULL;
4354
4355 if (NULL == pContext)
4356 {
4357 hddLog(VOS_TRACE_LEVEL_ERROR,
4358 "%s: Bad param, pContext [%p]",
4359 __func__, pContext);
4360 return;
4361 }
4362
Jeff Johnson72a40512013-12-19 10:14:15 -08004363 /* there is a race condition that exists between this callback
4364 function and the caller since the caller could time out either
4365 before or while this code is executing. we use a spinlock to
4366 serialize these actions */
4367 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004368
4369 pStatsContext = pContext;
4370 pAdapter = pStatsContext->pAdapter;
4371 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4372 {
4373 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004374 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004375 hddLog(VOS_TRACE_LEVEL_WARN,
4376 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4377 __func__, pAdapter, pStatsContext->magic);
4378 return;
4379 }
4380
Jeff Johnson72a40512013-12-19 10:14:15 -08004381 /* context is valid so caller is still waiting */
4382
4383 /* paranoia: invalidate the magic */
4384 pStatsContext->magic = 0;
4385
4386 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004387 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4388 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4389 tsmMetrics.UplinkPktQueueDlyHist,
4390 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4391 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4392 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4393 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4394 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4395 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4396 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4397
Jeff Johnson72a40512013-12-19 10:14:15 -08004398 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004399 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004400
4401 /* serialization is complete */
4402 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004403}
4404
4405
4406
4407static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4408 tAniTrafStrmMetrics* pTsmMetrics)
4409{
4410 hdd_station_ctx_t *pHddStaCtx = NULL;
4411 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004412 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004413 long lrc;
4414 struct statsContext context;
4415 hdd_context_t *pHddCtx = NULL;
4416
4417 if (NULL == pAdapter)
4418 {
4419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4420 return VOS_STATUS_E_FAULT;
4421 }
4422
4423 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4424 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4425
4426 /* we are connected prepare our callback context */
4427 init_completion(&context.completion);
4428 context.pAdapter = pAdapter;
4429 context.magic = STATS_CONTEXT_MAGIC;
4430
4431 /* query tsm stats */
4432 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4433 pHddStaCtx->conn_info.staId[ 0 ],
4434 pHddStaCtx->conn_info.bssId,
4435 &context, pHddCtx->pvosContext, tid);
4436
4437 if (eHAL_STATUS_SUCCESS != hstatus)
4438 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004439 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4440 __func__);
4441 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004442 }
4443 else
4444 {
4445 /* request was sent -- wait for the response */
4446 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4447 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004448 if (lrc <= 0)
4449 {
4450 hddLog(VOS_TRACE_LEVEL_ERROR,
4451 "%s: SME %s while retrieving statistics",
4452 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004453 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004454 }
4455 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004456
Jeff Johnson72a40512013-12-19 10:14:15 -08004457 /* either we never sent a request, we sent a request and received a
4458 response or we sent a request and timed out. if we never sent a
4459 request or if we sent a request and got a response, we want to
4460 clear the magic out of paranoia. if we timed out there is a
4461 race condition such that the callback function could be
4462 executing at the same time we are. of primary concern is if the
4463 callback function had already verified the "magic" but had not
4464 yet set the completion variable when a timeout occurred. we
4465 serialize these activities by invalidating the magic while
4466 holding a shared spinlock which will cause us to block if the
4467 callback is currently executing */
4468 spin_lock(&hdd_context_lock);
4469 context.magic = 0;
4470 spin_unlock(&hdd_context_lock);
4471
4472 if (VOS_STATUS_SUCCESS == vstatus)
4473 {
4474 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4475 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4476 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4477 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4478 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4479 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4480 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4481 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4482 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4483 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4484 }
4485 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004486}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004487#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004488
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004489#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004490void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4491{
4492 eCsrBand band = -1;
4493 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4494 switch (band)
4495 {
4496 case eCSR_BAND_ALL:
4497 *pBand = WLAN_HDD_UI_BAND_AUTO;
4498 break;
4499
4500 case eCSR_BAND_24:
4501 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4502 break;
4503
4504 case eCSR_BAND_5G:
4505 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4506 break;
4507
4508 default:
4509 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4510 *pBand = -1;
4511 break;
4512 }
4513}
4514
4515/**---------------------------------------------------------------------------
4516
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004517 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4518
4519 This function parses the send action frame data passed in the format
4520 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4521
Srinivas Girigowda56076852013-08-20 14:00:50 -07004522 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004523 \param - pTargetApBssid Pointer to target Ap bssid
4524 \param - pChannel Pointer to the Target AP channel
4525 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4526 \param - pBuf Pointer to data
4527 \param - pBufLen Pointer to data length
4528
4529 \return - 0 for success non-zero for failure
4530
4531 --------------------------------------------------------------------------*/
4532VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4533 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4534{
4535 tANI_U8 *inPtr = pValue;
4536 tANI_U8 *dataEnd;
4537 int tempInt;
4538 int j = 0;
4539 int i = 0;
4540 int v = 0;
4541 tANI_U8 tempBuf[32];
4542 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004543 /* 12 hexa decimal digits, 5 ':' and '\0' */
4544 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004545
4546 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4547 /*no argument after the command*/
4548 if (NULL == inPtr)
4549 {
4550 return -EINVAL;
4551 }
4552
4553 /*no space after the command*/
4554 else if (SPACE_ASCII_VALUE != *inPtr)
4555 {
4556 return -EINVAL;
4557 }
4558
4559 /*removing empty spaces*/
4560 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4561
4562 /*no argument followed by spaces*/
4563 if ('\0' == *inPtr)
4564 {
4565 return -EINVAL;
4566 }
4567
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004568 v = sscanf(inPtr, "%17s", macAddress);
4569 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004570 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4572 "Invalid MAC address or All hex inputs are not read (%d)", v);
4573 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004574 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004575
4576 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4577 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4578 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4579 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4580 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4581 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004582
4583 /* point to the next argument */
4584 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4585 /*no argument after the command*/
4586 if (NULL == inPtr) return -EINVAL;
4587
4588 /*removing empty spaces*/
4589 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4590
4591 /*no argument followed by spaces*/
4592 if ('\0' == *inPtr)
4593 {
4594 return -EINVAL;
4595 }
4596
4597 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004598 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004599 if (1 != v) return -EINVAL;
4600
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004601 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304602 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304603 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004604
4605 *pChannel = tempInt;
4606
4607 /* point to the next argument */
4608 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4609 /*no argument after the command*/
4610 if (NULL == inPtr) return -EINVAL;
4611 /*removing empty spaces*/
4612 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4613
4614 /*no argument followed by spaces*/
4615 if ('\0' == *inPtr)
4616 {
4617 return -EINVAL;
4618 }
4619
4620 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004621 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004622 if (1 != v) return -EINVAL;
4623
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004624 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004625 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004626
4627 *pDwellTime = tempInt;
4628
4629 /* point to the next argument */
4630 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4631 /*no argument after the command*/
4632 if (NULL == inPtr) return -EINVAL;
4633 /*removing empty spaces*/
4634 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4635
4636 /*no argument followed by spaces*/
4637 if ('\0' == *inPtr)
4638 {
4639 return -EINVAL;
4640 }
4641
4642 /* find the length of data */
4643 dataEnd = inPtr;
4644 while(('\0' != *dataEnd) )
4645 {
4646 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004647 }
Kiet Lambe150c22013-11-21 16:30:32 +05304648 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004649 if ( *pBufLen <= 0) return -EINVAL;
4650
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004651 /* Allocate the number of bytes based on the number of input characters
4652 whether it is even or odd.
4653 if the number of input characters are even, then we need N/2 byte.
4654 if the number of input characters are odd, then we need do (N+1)/2 to
4655 compensate rounding off.
4656 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4657 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4658 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004659 if (NULL == *pBuf)
4660 {
4661 hddLog(VOS_TRACE_LEVEL_FATAL,
4662 "%s: vos_mem_alloc failed ", __func__);
4663 return -EINVAL;
4664 }
4665
4666 /* the buffer received from the upper layer is character buffer,
4667 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4668 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4669 and f0 in 3rd location */
4670 for (i = 0, j = 0; j < *pBufLen; j += 2)
4671 {
Kiet Lambe150c22013-11-21 16:30:32 +05304672 if( j+1 == *pBufLen)
4673 {
4674 tempByte = hdd_parse_hex(inPtr[j]);
4675 }
4676 else
4677 {
4678 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4679 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004680 (*pBuf)[i++] = tempByte;
4681 }
4682 *pBufLen = i;
4683 return VOS_STATUS_SUCCESS;
4684}
4685
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004686/**---------------------------------------------------------------------------
4687
Srinivas Girigowdade697412013-02-14 16:31:48 -08004688 \brief hdd_parse_channellist() - HDD Parse channel list
4689
4690 This function parses the channel list passed in the format
4691 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004692 if the Number of channels (N) does not match with the actual number of channels passed
4693 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4694 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4695 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4696 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004697
4698 \param - pValue Pointer to input channel list
4699 \param - ChannelList Pointer to local output array to record channel list
4700 \param - pNumChannels Pointer to number of roam scan channels
4701
4702 \return - 0 for success non-zero for failure
4703
4704 --------------------------------------------------------------------------*/
4705VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4706{
4707 tANI_U8 *inPtr = pValue;
4708 int tempInt;
4709 int j = 0;
4710 int v = 0;
4711 char buf[32];
4712
4713 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4714 /*no argument after the command*/
4715 if (NULL == inPtr)
4716 {
4717 return -EINVAL;
4718 }
4719
4720 /*no space after the command*/
4721 else if (SPACE_ASCII_VALUE != *inPtr)
4722 {
4723 return -EINVAL;
4724 }
4725
4726 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004727 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004728
4729 /*no argument followed by spaces*/
4730 if ('\0' == *inPtr)
4731 {
4732 return -EINVAL;
4733 }
4734
4735 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004736 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004737 if (1 != v) return -EINVAL;
4738
Srinivas Girigowdade697412013-02-14 16:31:48 -08004739 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004740 if ((v < 0) ||
4741 (tempInt <= 0) ||
4742 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4743 {
4744 return -EINVAL;
4745 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004746
4747 *pNumChannels = tempInt;
4748
4749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4750 "Number of channels are: %d", *pNumChannels);
4751
4752 for (j = 0; j < (*pNumChannels); j++)
4753 {
4754 /*inPtr pointing to the beginning of first space after number of channels*/
4755 inPtr = strpbrk( inPtr, " " );
4756 /*no channel list after the number of channels argument*/
4757 if (NULL == inPtr)
4758 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004759 if (0 != j)
4760 {
4761 *pNumChannels = j;
4762 return VOS_STATUS_SUCCESS;
4763 }
4764 else
4765 {
4766 return -EINVAL;
4767 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004768 }
4769
4770 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004771 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004772
4773 /*no channel list after the number of channels argument and spaces*/
4774 if ( '\0' == *inPtr )
4775 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004776 if (0 != j)
4777 {
4778 *pNumChannels = j;
4779 return VOS_STATUS_SUCCESS;
4780 }
4781 else
4782 {
4783 return -EINVAL;
4784 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004785 }
4786
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004787 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004788 if (1 != v) return -EINVAL;
4789
Srinivas Girigowdade697412013-02-14 16:31:48 -08004790 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004791 if ((v < 0) ||
4792 (tempInt <= 0) ||
4793 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4794 {
4795 return -EINVAL;
4796 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004797 pChannelList[j] = tempInt;
4798
4799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4800 "Channel %d added to preferred channel list",
4801 pChannelList[j] );
4802 }
4803
Srinivas Girigowdade697412013-02-14 16:31:48 -08004804 return VOS_STATUS_SUCCESS;
4805}
4806
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004807
4808/**---------------------------------------------------------------------------
4809
4810 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4811
4812 This function parses the reasoc command data passed in the format
4813 REASSOC<space><bssid><space><channel>
4814
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004815 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004816 \param - pTargetApBssid Pointer to target Ap bssid
4817 \param - pChannel Pointer to the Target AP channel
4818
4819 \return - 0 for success non-zero for failure
4820
4821 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004822VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4823 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004824{
4825 tANI_U8 *inPtr = pValue;
4826 int tempInt;
4827 int v = 0;
4828 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004829 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004830 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004831
4832 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4833 /*no argument after the command*/
4834 if (NULL == inPtr)
4835 {
4836 return -EINVAL;
4837 }
4838
4839 /*no space after the command*/
4840 else if (SPACE_ASCII_VALUE != *inPtr)
4841 {
4842 return -EINVAL;
4843 }
4844
4845 /*removing empty spaces*/
4846 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4847
4848 /*no argument followed by spaces*/
4849 if ('\0' == *inPtr)
4850 {
4851 return -EINVAL;
4852 }
4853
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004854 v = sscanf(inPtr, "%17s", macAddress);
4855 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004856 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4858 "Invalid MAC address or All hex inputs are not read (%d)", v);
4859 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004860 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004861
4862 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4863 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4864 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4865 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4866 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4867 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004868
4869 /* point to the next argument */
4870 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4871 /*no argument after the command*/
4872 if (NULL == inPtr) return -EINVAL;
4873
4874 /*removing empty spaces*/
4875 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4876
4877 /*no argument followed by spaces*/
4878 if ('\0' == *inPtr)
4879 {
4880 return -EINVAL;
4881 }
4882
4883 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004884 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004885 if (1 != v) return -EINVAL;
4886
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004887 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004888 if ((v < 0) ||
4889 (tempInt <= 0) ||
4890 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4891 {
4892 return -EINVAL;
4893 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004894
4895 *pChannel = tempInt;
4896 return VOS_STATUS_SUCCESS;
4897}
4898
4899#endif
4900
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004901#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004902/**---------------------------------------------------------------------------
4903
4904 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4905
4906 This function parses the SETCCKM IE command
4907 SETCCKMIE<space><ie data>
4908
4909 \param - pValue Pointer to input data
4910 \param - pCckmIe Pointer to output cckm Ie
4911 \param - pCckmIeLen Pointer to output cckm ie length
4912
4913 \return - 0 for success non-zero for failure
4914
4915 --------------------------------------------------------------------------*/
4916VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4917 tANI_U8 *pCckmIeLen)
4918{
4919 tANI_U8 *inPtr = pValue;
4920 tANI_U8 *dataEnd;
4921 int j = 0;
4922 int i = 0;
4923 tANI_U8 tempByte = 0;
4924
4925 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4926 /*no argument after the command*/
4927 if (NULL == inPtr)
4928 {
4929 return -EINVAL;
4930 }
4931
4932 /*no space after the command*/
4933 else if (SPACE_ASCII_VALUE != *inPtr)
4934 {
4935 return -EINVAL;
4936 }
4937
4938 /*removing empty spaces*/
4939 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4940
4941 /*no argument followed by spaces*/
4942 if ('\0' == *inPtr)
4943 {
4944 return -EINVAL;
4945 }
4946
4947 /* find the length of data */
4948 dataEnd = inPtr;
4949 while(('\0' != *dataEnd) )
4950 {
4951 dataEnd++;
4952 ++(*pCckmIeLen);
4953 }
4954 if ( *pCckmIeLen <= 0) return -EINVAL;
4955
4956 /* Allocate the number of bytes based on the number of input characters
4957 whether it is even or odd.
4958 if the number of input characters are even, then we need N/2 byte.
4959 if the number of input characters are odd, then we need do (N+1)/2 to
4960 compensate rounding off.
4961 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4962 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4963 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4964 if (NULL == *pCckmIe)
4965 {
4966 hddLog(VOS_TRACE_LEVEL_FATAL,
4967 "%s: vos_mem_alloc failed ", __func__);
4968 return -EINVAL;
4969 }
4970 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4971 /* the buffer received from the upper layer is character buffer,
4972 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4973 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4974 and f0 in 3rd location */
4975 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4976 {
4977 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4978 (*pCckmIe)[i++] = tempByte;
4979 }
4980 *pCckmIeLen = i;
4981
4982 return VOS_STATUS_SUCCESS;
4983}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004984#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004985
Jeff Johnson295189b2012-06-20 16:38:30 -07004986/**---------------------------------------------------------------------------
4987
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004988 \brief hdd_is_valid_mac_address() - Validate MAC address
4989
4990 This function validates whether the given MAC address is valid or not
4991 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4992 where X is the hexa decimal digit character and separated by ':'
4993 This algorithm works even if MAC address is not separated by ':'
4994
4995 This code checks given input string mac contains exactly 12 hexadecimal digits.
4996 and a separator colon : appears in the input string only after
4997 an even number of hex digits.
4998
4999 \param - pMacAddr pointer to the input MAC address
5000 \return - 1 for valid and 0 for invalid
5001
5002 --------------------------------------------------------------------------*/
5003
5004v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5005{
5006 int xdigit = 0;
5007 int separator = 0;
5008 while (*pMacAddr)
5009 {
5010 if (isxdigit(*pMacAddr))
5011 {
5012 xdigit++;
5013 }
5014 else if (':' == *pMacAddr)
5015 {
5016 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5017 break;
5018
5019 ++separator;
5020 }
5021 else
5022 {
5023 separator = -1;
5024 /* Invalid MAC found */
5025 return 0;
5026 }
5027 ++pMacAddr;
5028 }
5029 return (xdigit == 12 && (separator == 5 || separator == 0));
5030}
5031
5032/**---------------------------------------------------------------------------
5033
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305034 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005035
5036 \param - dev Pointer to net_device structure
5037
5038 \return - 0 for success non-zero for failure
5039
5040 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305041int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005042{
5043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5044 hdd_context_t *pHddCtx;
5045 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5046 VOS_STATUS status;
5047 v_BOOL_t in_standby = TRUE;
5048
5049 if (NULL == pAdapter)
5050 {
5051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305052 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005053 return -ENODEV;
5054 }
5055
5056 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305057 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5058 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 if (NULL == pHddCtx)
5060 {
5061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005062 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 return -ENODEV;
5064 }
5065
5066 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5067 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5068 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005069 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5070 {
5071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305072 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005073 in_standby = FALSE;
5074 break;
5075 }
5076 else
5077 {
5078 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5079 pAdapterNode = pNext;
5080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005081 }
5082
5083 if (TRUE == in_standby)
5084 {
5085 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5086 {
5087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5088 "wlan out of power save", __func__);
5089 return -EINVAL;
5090 }
5091 }
5092
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005093 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005094 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5095 {
5096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005097 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005098 /* Enable TX queues only when we are connected */
5099 netif_tx_start_all_queues(dev);
5100 }
5101
5102 return 0;
5103}
5104
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305105/**---------------------------------------------------------------------------
5106
5107 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5108
5109 This is called in response to ifconfig up
5110
5111 \param - dev Pointer to net_device structure
5112
5113 \return - 0 for success non-zero for failure
5114
5115 --------------------------------------------------------------------------*/
5116int hdd_open(struct net_device *dev)
5117{
5118 int ret;
5119
5120 vos_ssr_protect(__func__);
5121 ret = __hdd_open(dev);
5122 vos_ssr_unprotect(__func__);
5123
5124 return ret;
5125}
5126
Jeff Johnson295189b2012-06-20 16:38:30 -07005127int hdd_mon_open (struct net_device *dev)
5128{
5129 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5130
5131 if(pAdapter == NULL) {
5132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005133 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005134 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005135 }
5136
5137 netif_start_queue(dev);
5138
5139 return 0;
5140}
5141/**---------------------------------------------------------------------------
5142
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305143 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005144
5145 \param - dev Pointer to net_device structure
5146
5147 \return - 0 for success non-zero for failure
5148
5149 --------------------------------------------------------------------------*/
5150
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305151int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005152{
5153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5154 hdd_context_t *pHddCtx;
5155 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5156 VOS_STATUS status;
5157 v_BOOL_t enter_standby = TRUE;
5158
5159 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 if (NULL == pAdapter)
5161 {
5162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305163 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 return -ENODEV;
5165 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305166 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5167 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005168 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5169 if (NULL == pHddCtx)
5170 {
5171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005172 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005173 return -ENODEV;
5174 }
5175
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305176 /* Nothing to be done if the interface is not opened */
5177 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5178 {
5179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5180 "%s: NETDEV Interface is not OPENED", __func__);
5181 return -ENODEV;
5182 }
5183
5184 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005185 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005186 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305187
5188 /* Disable TX on the interface, after this hard_start_xmit() will not
5189 * be called on that interface
5190 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005191 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305192
5193 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005194 netif_carrier_off(pAdapter->dev);
5195
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305196 /* The interface is marked as down for outside world (aka kernel)
5197 * But the driver is pretty much alive inside. The driver needs to
5198 * tear down the existing connection on the netdev (session)
5199 * cleanup the data pipes and wait until the control plane is stabilized
5200 * for this interface. The call also needs to wait until the above
5201 * mentioned actions are completed before returning to the caller.
5202 * Notice that the hdd_stop_adapter is requested not to close the session
5203 * That is intentional to be able to scan if it is a STA/P2P interface
5204 */
5205 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005206
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305207 /* DeInit the adapter. This ensures datapath cleanup as well */
5208 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 /* SoftAP ifaces should never go in power save mode
5210 making sure same here. */
5211 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5212 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 )
5215 {
5216 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5218 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 EXIT();
5220 return 0;
5221 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305222 /* Find if any iface is up. If any iface is up then can't put device to
5223 * sleep/power save mode
5224 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005225 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5226 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5227 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005228 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5229 {
5230 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305231 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005232 enter_standby = FALSE;
5233 break;
5234 }
5235 else
5236 {
5237 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5238 pAdapterNode = pNext;
5239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005240 }
5241
5242 if (TRUE == enter_standby)
5243 {
5244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5245 "entering standby", __func__);
5246 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5247 {
5248 /*log and return success*/
5249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5250 "wlan in power save", __func__);
5251 }
5252 }
5253
5254 EXIT();
5255 return 0;
5256}
5257
5258/**---------------------------------------------------------------------------
5259
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305260 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005261
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305262 This is called in response to ifconfig down
5263
5264 \param - dev Pointer to net_device structure
5265
5266 \return - 0 for success non-zero for failure
5267-----------------------------------------------------------------------------*/
5268int hdd_stop (struct net_device *dev)
5269{
5270 int ret;
5271
5272 vos_ssr_protect(__func__);
5273 ret = __hdd_stop(dev);
5274 vos_ssr_unprotect(__func__);
5275
5276 return ret;
5277}
5278
5279/**---------------------------------------------------------------------------
5280
5281 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005282
5283 \param - dev Pointer to net_device structure
5284
5285 \return - void
5286
5287 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305288static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005289{
5290 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5291
5292 ENTER();
5293
5294 do
5295 {
5296 if (NULL == pAdapter)
5297 {
5298 hddLog(VOS_TRACE_LEVEL_FATAL,
5299 "%s: NULL pAdapter", __func__);
5300 break;
5301 }
5302
5303 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5304 {
5305 hddLog(VOS_TRACE_LEVEL_FATAL,
5306 "%s: Invalid magic", __func__);
5307 break;
5308 }
5309
5310 if (NULL == pAdapter->pHddCtx)
5311 {
5312 hddLog(VOS_TRACE_LEVEL_FATAL,
5313 "%s: NULL pHddCtx", __func__);
5314 break;
5315 }
5316
5317 if (dev != pAdapter->dev)
5318 {
5319 hddLog(VOS_TRACE_LEVEL_FATAL,
5320 "%s: Invalid device reference", __func__);
5321 /* we haven't validated all cases so let this go for now */
5322 }
5323
5324 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5325
5326 /* after uninit our adapter structure will no longer be valid */
5327 pAdapter->dev = NULL;
5328 pAdapter->magic = 0;
5329 } while (0);
5330
5331 EXIT();
5332}
5333
5334/**---------------------------------------------------------------------------
5335
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305336 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5337
5338 This is called during the netdev unregister to uninitialize all data
5339associated with the device
5340
5341 \param - dev Pointer to net_device structure
5342
5343 \return - void
5344
5345 --------------------------------------------------------------------------*/
5346static void hdd_uninit (struct net_device *dev)
5347{
5348 vos_ssr_protect(__func__);
5349 __hdd_uninit(dev);
5350 vos_ssr_unprotect(__func__);
5351}
5352
5353/**---------------------------------------------------------------------------
5354
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 \brief hdd_release_firmware() -
5356
5357 This function calls the release firmware API to free the firmware buffer.
5358
5359 \param - pFileName Pointer to the File Name.
5360 pCtx - Pointer to the adapter .
5361
5362
5363 \return - 0 for success, non zero for failure
5364
5365 --------------------------------------------------------------------------*/
5366
5367VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5368{
5369 VOS_STATUS status = VOS_STATUS_SUCCESS;
5370 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5371 ENTER();
5372
5373
5374 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5375
5376 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5377
5378 if(pHddCtx->fw) {
5379 release_firmware(pHddCtx->fw);
5380 pHddCtx->fw = NULL;
5381 }
5382 else
5383 status = VOS_STATUS_E_FAILURE;
5384 }
5385 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5386 if(pHddCtx->nv) {
5387 release_firmware(pHddCtx->nv);
5388 pHddCtx->nv = NULL;
5389 }
5390 else
5391 status = VOS_STATUS_E_FAILURE;
5392
5393 }
5394
5395 EXIT();
5396 return status;
5397}
5398
5399/**---------------------------------------------------------------------------
5400
5401 \brief hdd_request_firmware() -
5402
5403 This function reads the firmware file using the request firmware
5404 API and returns the the firmware data and the firmware file size.
5405
5406 \param - pfileName - Pointer to the file name.
5407 - pCtx - Pointer to the adapter .
5408 - ppfw_data - Pointer to the pointer of the firmware data.
5409 - pSize - Pointer to the file size.
5410
5411 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5412
5413 --------------------------------------------------------------------------*/
5414
5415
5416VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5417{
5418 int status;
5419 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5420 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5421 ENTER();
5422
5423 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5424
5425 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5426
5427 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5428 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5429 __func__, pfileName);
5430 retval = VOS_STATUS_E_FAILURE;
5431 }
5432
5433 else {
5434 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5435 *pSize = pHddCtx->fw->size;
5436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5437 __func__, *pSize);
5438 }
5439 }
5440 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5441
5442 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5443
5444 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5445 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5446 __func__, pfileName);
5447 retval = VOS_STATUS_E_FAILURE;
5448 }
5449
5450 else {
5451 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5452 *pSize = pHddCtx->nv->size;
5453 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5454 __func__, *pSize);
5455 }
5456 }
5457
5458 EXIT();
5459 return retval;
5460}
5461/**---------------------------------------------------------------------------
5462 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5463
5464 This is the function invoked by SME to inform the result of a full power
5465 request issued by HDD
5466
5467 \param - callbackcontext - Pointer to cookie
5468 status - result of request
5469
5470 \return - None
5471
5472--------------------------------------------------------------------------*/
5473void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5474{
5475 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5476
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005477 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 if(&pHddCtx->full_pwr_comp_var)
5479 {
5480 complete(&pHddCtx->full_pwr_comp_var);
5481 }
5482}
5483
5484/**---------------------------------------------------------------------------
5485
5486 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5487
5488 This is the function invoked by SME to inform the result of BMPS
5489 request issued by HDD
5490
5491 \param - callbackcontext - Pointer to cookie
5492 status - result of request
5493
5494 \return - None
5495
5496--------------------------------------------------------------------------*/
5497void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5498{
5499
5500 struct completion *completion_var = (struct completion*) callbackContext;
5501
Arif Hussain6d2a3322013-11-17 19:50:10 -08005502 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 if(completion_var != NULL)
5504 {
5505 complete(completion_var);
5506 }
5507}
5508
5509/**---------------------------------------------------------------------------
5510
5511 \brief hdd_get_cfg_file_size() -
5512
5513 This function reads the configuration file using the request firmware
5514 API and returns the configuration file size.
5515
5516 \param - pCtx - Pointer to the adapter .
5517 - pFileName - Pointer to the file name.
5518 - pBufSize - Pointer to the buffer size.
5519
5520 \return - 0 for success, non zero for failure
5521
5522 --------------------------------------------------------------------------*/
5523
5524VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5525{
5526 int status;
5527 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5528
5529 ENTER();
5530
5531 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5532
5533 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5534 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5535 status = VOS_STATUS_E_FAILURE;
5536 }
5537 else {
5538 *pBufSize = pHddCtx->fw->size;
5539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5540 release_firmware(pHddCtx->fw);
5541 pHddCtx->fw = NULL;
5542 }
5543
5544 EXIT();
5545 return VOS_STATUS_SUCCESS;
5546}
5547
5548/**---------------------------------------------------------------------------
5549
5550 \brief hdd_read_cfg_file() -
5551
5552 This function reads the configuration file using the request firmware
5553 API and returns the cfg data and the buffer size of the configuration file.
5554
5555 \param - pCtx - Pointer to the adapter .
5556 - pFileName - Pointer to the file name.
5557 - pBuffer - Pointer to the data buffer.
5558 - pBufSize - Pointer to the buffer size.
5559
5560 \return - 0 for success, non zero for failure
5561
5562 --------------------------------------------------------------------------*/
5563
5564VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5565 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5566{
5567 int status;
5568 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5569
5570 ENTER();
5571
5572 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5573
5574 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5575 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5576 return VOS_STATUS_E_FAILURE;
5577 }
5578 else {
5579 if(*pBufSize != pHddCtx->fw->size) {
5580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5581 "file size", __func__);
5582 release_firmware(pHddCtx->fw);
5583 pHddCtx->fw = NULL;
5584 return VOS_STATUS_E_FAILURE;
5585 }
5586 else {
5587 if(pBuffer) {
5588 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5589 }
5590 release_firmware(pHddCtx->fw);
5591 pHddCtx->fw = NULL;
5592 }
5593 }
5594
5595 EXIT();
5596
5597 return VOS_STATUS_SUCCESS;
5598}
5599
5600/**---------------------------------------------------------------------------
5601
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305602 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005603
5604 This function sets the user specified mac address using
5605 the command ifconfig wlanX hw ether <mac adress>.
5606
5607 \param - dev - Pointer to the net device.
5608 - addr - Pointer to the sockaddr.
5609 \return - 0 for success, non zero for failure
5610
5611 --------------------------------------------------------------------------*/
5612
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305613static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005614{
5615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5616 struct sockaddr *psta_mac_addr = addr;
5617 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5618
5619 ENTER();
5620
5621 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5623
5624 EXIT();
5625 return halStatus;
5626}
5627
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305628/**---------------------------------------------------------------------------
5629
5630 \brief hdd_set_mac_address() -
5631
5632 Wrapper function to protect __hdd_set_mac_address() function from ssr
5633
5634 \param - dev - Pointer to the net device.
5635 - addr - Pointer to the sockaddr.
5636 \return - 0 for success, non zero for failure
5637
5638 --------------------------------------------------------------------------*/
5639static int hdd_set_mac_address(struct net_device *dev, void *addr)
5640{
5641 int ret;
5642
5643 vos_ssr_protect(__func__);
5644 ret = __hdd_set_mac_address(dev, addr);
5645 vos_ssr_unprotect(__func__);
5646
5647 return ret;
5648}
5649
Jeff Johnson295189b2012-06-20 16:38:30 -07005650tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5651{
5652 int i;
5653 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5654 {
Abhishek Singheb183782014-02-06 13:37:21 +05305655 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 break;
5657 }
5658
5659 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5660 return NULL;
5661
5662 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5663 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5664}
5665
5666void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5667{
5668 int i;
5669 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5670 {
5671 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5672 {
5673 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5674 break;
5675 }
5676 }
5677 return;
5678}
5679
5680#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5681 static struct net_device_ops wlan_drv_ops = {
5682 .ndo_open = hdd_open,
5683 .ndo_stop = hdd_stop,
5684 .ndo_uninit = hdd_uninit,
5685 .ndo_start_xmit = hdd_hard_start_xmit,
5686 .ndo_tx_timeout = hdd_tx_timeout,
5687 .ndo_get_stats = hdd_stats,
5688 .ndo_do_ioctl = hdd_ioctl,
5689 .ndo_set_mac_address = hdd_set_mac_address,
5690 .ndo_select_queue = hdd_select_queue,
5691#ifdef WLAN_FEATURE_PACKET_FILTERING
5692#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5693 .ndo_set_rx_mode = hdd_set_multicast_list,
5694#else
5695 .ndo_set_multicast_list = hdd_set_multicast_list,
5696#endif //LINUX_VERSION_CODE
5697#endif
5698 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 static struct net_device_ops wlan_mon_drv_ops = {
5700 .ndo_open = hdd_mon_open,
5701 .ndo_stop = hdd_stop,
5702 .ndo_uninit = hdd_uninit,
5703 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5704 .ndo_tx_timeout = hdd_tx_timeout,
5705 .ndo_get_stats = hdd_stats,
5706 .ndo_do_ioctl = hdd_ioctl,
5707 .ndo_set_mac_address = hdd_set_mac_address,
5708 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005709
5710#endif
5711
5712void hdd_set_station_ops( struct net_device *pWlanDev )
5713{
5714#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005715 pWlanDev->netdev_ops = &wlan_drv_ops;
5716#else
5717 pWlanDev->open = hdd_open;
5718 pWlanDev->stop = hdd_stop;
5719 pWlanDev->uninit = hdd_uninit;
5720 pWlanDev->hard_start_xmit = NULL;
5721 pWlanDev->tx_timeout = hdd_tx_timeout;
5722 pWlanDev->get_stats = hdd_stats;
5723 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 pWlanDev->set_mac_address = hdd_set_mac_address;
5725#endif
5726}
5727
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005728static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005729{
5730 struct net_device *pWlanDev = NULL;
5731 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 /*
5733 * cfg80211 initialization and registration....
5734 */
5735 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5736
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 if(pWlanDev != NULL)
5738 {
5739
5740 //Save the pointer to the net_device in the HDD adapter
5741 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5742
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5744
5745 pAdapter->dev = pWlanDev;
5746 pAdapter->pHddCtx = pHddCtx;
5747 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05305748 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07005749
5750 init_completion(&pAdapter->session_open_comp_var);
5751 init_completion(&pAdapter->session_close_comp_var);
5752 init_completion(&pAdapter->disconnect_comp_var);
5753 init_completion(&pAdapter->linkup_event_var);
5754 init_completion(&pAdapter->cancel_rem_on_chan_var);
5755 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305756 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005757#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5758 init_completion(&pAdapter->offchannel_tx_event);
5759#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005761#ifdef FEATURE_WLAN_TDLS
5762 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005763 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005764 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305765 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 init_completion(&pHddCtx->mc_sus_event_var);
5768 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305769 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005770 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005771 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005772
Rajeev79dbe4c2013-10-05 11:03:42 +05305773#ifdef FEATURE_WLAN_BATCH_SCAN
5774 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5775 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5776 pAdapter->pBatchScanRsp = NULL;
5777 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005778 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005779 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305780 mutex_init(&pAdapter->hdd_batch_scan_lock);
5781#endif
5782
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 pAdapter->isLinkUpSvcNeeded = FALSE;
5784 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5785 //Init the net_device structure
5786 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5787
5788 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5789 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5790 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5791 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5792
5793 hdd_set_station_ops( pAdapter->dev );
5794
5795 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005796 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5797 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5798 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 /* set pWlanDev's parent to underlying device */
5800 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005801
5802 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 }
5804
5805 return pAdapter;
5806}
5807
5808VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5809{
5810 struct net_device *pWlanDev = pAdapter->dev;
5811 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5812 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5813 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5814
5815 if( rtnl_lock_held )
5816 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005817 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5819 {
5820 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5821 return VOS_STATUS_E_FAILURE;
5822 }
5823 }
5824 if (register_netdevice(pWlanDev))
5825 {
5826 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5827 return VOS_STATUS_E_FAILURE;
5828 }
5829 }
5830 else
5831 {
5832 if(register_netdev(pWlanDev))
5833 {
5834 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5835 return VOS_STATUS_E_FAILURE;
5836 }
5837 }
5838 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5839
5840 return VOS_STATUS_SUCCESS;
5841}
5842
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005843static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005844{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005845 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005846
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005847 if (NULL == pAdapter)
5848 {
5849 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5850 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005852
5853 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5854 {
5855 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5856 return eHAL_STATUS_NOT_INITIALIZED;
5857 }
5858
5859 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5860
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005861#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005862 /* need to make sure all of our scheduled work has completed.
5863 * This callback is called from MC thread context, so it is safe to
5864 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005865 *
5866 * Even though this is called from MC thread context, if there is a faulty
5867 * work item in the system, that can hang this call forever. So flushing
5868 * this global work queue is not safe; and now we make sure that
5869 * individual work queues are stopped correctly. But the cancel work queue
5870 * is a GPL only API, so the proprietary version of the driver would still
5871 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005872 */
5873 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005874#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005875
5876 /* We can be blocked while waiting for scheduled work to be
5877 * flushed, and the adapter structure can potentially be freed, in
5878 * which case the magic will have been reset. So make sure the
5879 * magic is still good, and hence the adapter structure is still
5880 * valid, before signaling completion */
5881 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5882 {
5883 complete(&pAdapter->session_close_comp_var);
5884 }
5885
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 return eHAL_STATUS_SUCCESS;
5887}
5888
5889VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5890{
5891 struct net_device *pWlanDev = pAdapter->dev;
5892 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5893 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5894 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5895 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305896 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005897
5898 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005899 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 //Open a SME session for future operation
5901 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005902 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5904 {
5905 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005906 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 halStatus, halStatus );
5908 status = VOS_STATUS_E_FAILURE;
5909 goto error_sme_open;
5910 }
5911
5912 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305913 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 &pAdapter->session_open_comp_var,
5915 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305916 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 {
5918 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305919 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 status = VOS_STATUS_E_FAILURE;
5921 goto error_sme_open;
5922 }
5923
5924 // Register wireless extensions
5925 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5926 {
5927 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005928 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 halStatus, halStatus );
5930 status = VOS_STATUS_E_FAILURE;
5931 goto error_register_wext;
5932 }
5933 //Safe to register the hard_start_xmit function again
5934#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5935 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5936#else
5937 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5938#endif
5939
5940 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305941 hddLog(VOS_TRACE_LEVEL_INFO,
5942 "%s: Set HDD connState to eConnectionState_NotConnected",
5943 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5945
5946 //Set the default operation channel
5947 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5948
5949 /* Make the default Auth Type as OPEN*/
5950 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5951
5952 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5953 {
5954 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005955 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 status, status );
5957 goto error_init_txrx;
5958 }
5959
5960 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5961
5962 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5963 {
5964 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005965 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 status, status );
5967 goto error_wmm_init;
5968 }
5969
5970 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5971
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005972#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305973 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005974 {
5975 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305976 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005977 goto error_tdls_init;
5978 }
5979 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5980#endif
5981
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 return VOS_STATUS_SUCCESS;
5983
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005984#ifdef FEATURE_WLAN_TDLS
5985error_tdls_init:
5986 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5987 hdd_wmm_adapter_close(pAdapter);
5988#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005989error_wmm_init:
5990 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5991 hdd_deinit_tx_rx(pAdapter);
5992error_init_txrx:
5993 hdd_UnregisterWext(pWlanDev);
5994error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005995 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 {
5997 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005998 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006000 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306002 unsigned long rc;
6003
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306005 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006007 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306008 if (rc <= 0)
6009 hddLog(VOS_TRACE_LEVEL_ERROR,
6010 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 }
6012}
6013error_sme_open:
6014 return status;
6015}
6016
Jeff Johnson295189b2012-06-20 16:38:30 -07006017void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6018{
6019 hdd_cfg80211_state_t *cfgState;
6020
6021 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6022
6023 if( NULL != cfgState->buf )
6024 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306025 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6027 rc = wait_for_completion_interruptible_timeout(
6028 &pAdapter->tx_action_cnf_event,
6029 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306030 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306033 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6034 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 }
6036 }
6037 return;
6038}
Jeff Johnson295189b2012-06-20 16:38:30 -07006039
6040void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6041{
6042 ENTER();
6043 switch ( pAdapter->device_mode )
6044 {
6045 case WLAN_HDD_INFRA_STATION:
6046 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006047 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 {
6049 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6050 {
6051 hdd_deinit_tx_rx( pAdapter );
6052 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6053 }
6054
6055 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6056 {
6057 hdd_wmm_adapter_close( pAdapter );
6058 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6059 }
6060
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006062#ifdef FEATURE_WLAN_TDLS
6063 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
6064 {
6065 wlan_hdd_tdls_exit(pAdapter);
6066 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6067 }
6068#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006069
6070 break;
6071 }
6072
6073 case WLAN_HDD_SOFTAP:
6074 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306076
6077 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6078 {
6079 hdd_wmm_adapter_close( pAdapter );
6080 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6081 }
6082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006084
6085 hdd_unregister_hostapd(pAdapter);
6086 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 break;
6089 }
6090
6091 case WLAN_HDD_MONITOR:
6092 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6095 {
6096 hdd_deinit_tx_rx( pAdapter );
6097 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 if(NULL != pAdapterforTx)
6100 {
6101 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6102 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 break;
6104 }
6105
6106
6107 default:
6108 break;
6109 }
6110
6111 EXIT();
6112}
6113
6114void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6115{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006116 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306117
6118 ENTER();
6119 if (NULL == pAdapter)
6120 {
6121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6122 "%s: HDD adapter is Null", __func__);
6123 return;
6124 }
6125
6126 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006127
Rajeev79dbe4c2013-10-05 11:03:42 +05306128#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306129 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6130 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006131 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306132 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6133 )
6134 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006135 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306136 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006137 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6138 {
6139 hdd_deinit_batch_scan(pAdapter);
6140 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306141 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006142 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306143#endif
6144
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6146 if( rtnl_held )
6147 {
6148 unregister_netdevice(pWlanDev);
6149 }
6150 else
6151 {
6152 unregister_netdev(pWlanDev);
6153 }
6154 // note that the pAdapter is no longer valid at this point
6155 // since the memory has been reclaimed
6156 }
6157
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306158 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006159}
6160
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006161void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6162{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306163 VOS_STATUS status;
6164 hdd_adapter_t *pAdapter = NULL;
6165 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006166
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306167 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006168
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306169 /*loop through all adapters.*/
6170 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006171 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306172 pAdapter = pAdapterNode->pAdapter;
6173 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6174 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006175
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306176 { // we skip this registration for modes other than STA and P2P client modes.
6177 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6178 pAdapterNode = pNext;
6179 continue;
6180 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006181
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306182 //Apply Dynamic DTIM For P2P
6183 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6184 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6185 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6186 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6187 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6188 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6189 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6190 (eConnectionState_Associated ==
6191 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6192 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6193 {
6194 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006195
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306196 powerRequest.uIgnoreDTIM = 1;
6197 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6198
6199 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6200 {
6201 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6202 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6203 }
6204 else
6205 {
6206 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6207 }
6208
6209 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6210 * specified during Enter/Exit BMPS when LCD off*/
6211 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6212 NULL, eANI_BOOLEAN_FALSE);
6213 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6214 NULL, eANI_BOOLEAN_FALSE);
6215
6216 /* switch to the DTIM specified in cfg.ini */
6217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6218 "Switch to DTIM %d", powerRequest.uListenInterval);
6219 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6220 break;
6221
6222 }
6223
6224 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6225 pAdapterNode = pNext;
6226 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006227}
6228
6229void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6230{
6231 /*Switch back to DTIM 1*/
6232 tSirSetPowerParamsReq powerRequest = { 0 };
6233
6234 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6235 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006236 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006237
6238 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6239 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6240 NULL, eANI_BOOLEAN_FALSE);
6241 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6242 NULL, eANI_BOOLEAN_FALSE);
6243
6244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6245 "Switch to DTIM%d",powerRequest.uListenInterval);
6246 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6247
6248}
6249
Jeff Johnson295189b2012-06-20 16:38:30 -07006250VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6251{
6252 VOS_STATUS status = VOS_STATUS_SUCCESS;
6253
6254 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6255 {
6256 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6257 }
6258
6259 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6260 {
6261 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6262 }
6263
6264 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6265 {
6266 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6267 }
6268
6269 return status;
6270}
6271
6272VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6273{
6274 hdd_adapter_t *pAdapter = NULL;
6275 eHalStatus halStatus;
6276 VOS_STATUS status = VOS_STATUS_E_INVAL;
6277 v_BOOL_t disableBmps = FALSE;
6278 v_BOOL_t disableImps = FALSE;
6279
6280 switch(session_type)
6281 {
6282 case WLAN_HDD_INFRA_STATION:
6283 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 case WLAN_HDD_P2P_CLIENT:
6285 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 //Exit BMPS -> Is Sta/P2P Client is already connected
6287 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6288 if((NULL != pAdapter)&&
6289 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6290 {
6291 disableBmps = TRUE;
6292 }
6293
6294 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6295 if((NULL != pAdapter)&&
6296 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6297 {
6298 disableBmps = TRUE;
6299 }
6300
6301 //Exit both Bmps and Imps incase of Go/SAP Mode
6302 if((WLAN_HDD_SOFTAP == session_type) ||
6303 (WLAN_HDD_P2P_GO == session_type))
6304 {
6305 disableBmps = TRUE;
6306 disableImps = TRUE;
6307 }
6308
6309 if(TRUE == disableImps)
6310 {
6311 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6312 {
6313 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6314 }
6315 }
6316
6317 if(TRUE == disableBmps)
6318 {
6319 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6320 {
6321 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6322
6323 if(eHAL_STATUS_SUCCESS != halStatus)
6324 {
6325 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006326 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 VOS_ASSERT(0);
6328 return status;
6329 }
6330 }
6331
6332 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6333 {
6334 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6335
6336 if(eHAL_STATUS_SUCCESS != halStatus)
6337 {
6338 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006339 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 VOS_ASSERT(0);
6341 return status;
6342 }
6343 }
6344 }
6345
6346 if((TRUE == disableBmps) ||
6347 (TRUE == disableImps))
6348 {
6349 /* Now, get the chip into Full Power now */
6350 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6351 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6352 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6353
6354 if(halStatus != eHAL_STATUS_SUCCESS)
6355 {
6356 if(halStatus == eHAL_STATUS_PMC_PENDING)
6357 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306358 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306360 ret = wait_for_completion_interruptible_timeout(
6361 &pHddCtx->full_pwr_comp_var,
6362 msecs_to_jiffies(1000));
6363 if (ret <= 0)
6364 {
6365 hddLog(VOS_TRACE_LEVEL_ERROR,
6366 "%s: wait on full_pwr_comp_var failed %ld",
6367 __func__, ret);
6368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 }
6370 else
6371 {
6372 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006373 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 VOS_ASSERT(0);
6375 return status;
6376 }
6377 }
6378
6379 status = VOS_STATUS_SUCCESS;
6380 }
6381
6382 break;
6383 }
6384 return status;
6385}
6386
6387hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006388 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 tANI_U8 rtnl_held )
6390{
6391 hdd_adapter_t *pAdapter = NULL;
6392 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6393 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6394 VOS_STATUS exitbmpsStatus;
6395
Arif Hussain6d2a3322013-11-17 19:50:10 -08006396 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006397
Nirav Shah436658f2014-02-28 17:05:45 +05306398 if(macAddr == NULL)
6399 {
6400 /* Not received valid macAddr */
6401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6402 "%s:Unable to add virtual intf: Not able to get"
6403 "valid mac address",__func__);
6404 return NULL;
6405 }
6406
Jeff Johnson295189b2012-06-20 16:38:30 -07006407 //Disable BMPS incase of Concurrency
6408 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6409
6410 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6411 {
6412 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306413 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 VOS_ASSERT(0);
6415 return NULL;
6416 }
6417
6418 switch(session_type)
6419 {
6420 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
6424 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6425
6426 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306427 {
6428 hddLog(VOS_TRACE_LEVEL_FATAL,
6429 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006432
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306433#ifdef FEATURE_WLAN_TDLS
6434 /* A Mutex Lock is introduced while changing/initializing the mode to
6435 * protect the concurrent access for the Adapters by TDLS module.
6436 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306437 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306438#endif
6439
Jeff Johnsone7245742012-09-05 17:12:55 -07006440 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6441 NL80211_IFTYPE_P2P_CLIENT:
6442 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006443
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306445#ifdef FEATURE_WLAN_TDLS
6446 mutex_unlock(&pHddCtx->tdls_lock);
6447#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306448
6449 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 if( VOS_STATUS_SUCCESS != status )
6451 goto err_free_netdev;
6452
6453 status = hdd_register_interface( pAdapter, rtnl_held );
6454 if( VOS_STATUS_SUCCESS != status )
6455 {
6456 hdd_deinit_adapter(pHddCtx, pAdapter);
6457 goto err_free_netdev;
6458 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306459
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306460 // Workqueue which gets scheduled in IPv4 notification callback.
6461 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6462
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306463#ifdef WLAN_NS_OFFLOAD
6464 // Workqueue which gets scheduled in IPv6 notification callback.
6465 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 //Stop the Interface TX queue.
6468 netif_tx_disable(pAdapter->dev);
6469 //netif_tx_disable(pWlanDev);
6470 netif_carrier_off(pAdapter->dev);
6471
6472 break;
6473 }
6474
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 case WLAN_HDD_SOFTAP:
6477 {
6478 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6479 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306480 {
6481 hddLog(VOS_TRACE_LEVEL_FATAL,
6482 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006485
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6487 NL80211_IFTYPE_AP:
6488 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 pAdapter->device_mode = session_type;
6490
6491 status = hdd_init_ap_mode(pAdapter);
6492 if( VOS_STATUS_SUCCESS != status )
6493 goto err_free_netdev;
6494
6495 status = hdd_register_hostapd( pAdapter, rtnl_held );
6496 if( VOS_STATUS_SUCCESS != status )
6497 {
6498 hdd_deinit_adapter(pHddCtx, pAdapter);
6499 goto err_free_netdev;
6500 }
6501
6502 netif_tx_disable(pAdapter->dev);
6503 netif_carrier_off(pAdapter->dev);
6504
6505 hdd_set_conparam( 1 );
6506 break;
6507 }
6508 case WLAN_HDD_MONITOR:
6509 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6511 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306512 {
6513 hddLog(VOS_TRACE_LEVEL_FATAL,
6514 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006517
6518 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6519 pAdapter->device_mode = session_type;
6520 status = hdd_register_interface( pAdapter, rtnl_held );
6521#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6522 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6523#else
6524 pAdapter->dev->open = hdd_mon_open;
6525 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6526#endif
6527 hdd_init_tx_rx( pAdapter );
6528 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6529 //Set adapter to be used for data tx. It will use either GO or softap.
6530 pAdapter->sessionCtx.monitor.pAdapterForTx =
6531 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006532 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6533 {
6534 pAdapter->sessionCtx.monitor.pAdapterForTx =
6535 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006537 /* This workqueue will be used to transmit management packet over
6538 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006539 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6540 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6541 return NULL;
6542 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006543
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6545 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 }
6547 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006548 case WLAN_HDD_FTM:
6549 {
6550 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6551
6552 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306553 {
6554 hddLog(VOS_TRACE_LEVEL_FATAL,
6555 FL("failed to allocate adapter for session %d"), session_type);
6556 return NULL;
6557 }
6558
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6560 * message while loading driver in FTM mode. */
6561 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6562 pAdapter->device_mode = session_type;
6563 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306564
6565 hdd_init_tx_rx( pAdapter );
6566
6567 //Stop the Interface TX queue.
6568 netif_tx_disable(pAdapter->dev);
6569 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006570 }
6571 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 default:
6573 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306574 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6575 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 VOS_ASSERT(0);
6577 return NULL;
6578 }
6579 }
6580
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 if( VOS_STATUS_SUCCESS == status )
6582 {
6583 //Add it to the hdd's session list.
6584 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6585 if( NULL == pHddAdapterNode )
6586 {
6587 status = VOS_STATUS_E_NOMEM;
6588 }
6589 else
6590 {
6591 pHddAdapterNode->pAdapter = pAdapter;
6592 status = hdd_add_adapter_back ( pHddCtx,
6593 pHddAdapterNode );
6594 }
6595 }
6596
6597 if( VOS_STATUS_SUCCESS != status )
6598 {
6599 if( NULL != pAdapter )
6600 {
6601 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6602 pAdapter = NULL;
6603 }
6604 if( NULL != pHddAdapterNode )
6605 {
6606 vos_mem_free( pHddAdapterNode );
6607 }
6608
6609 goto resume_bmps;
6610 }
6611
6612 if(VOS_STATUS_SUCCESS == status)
6613 {
6614 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6615
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006616 //Initialize the WoWL service
6617 if(!hdd_init_wowl(pAdapter))
6618 {
6619 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6620 goto err_free_netdev;
6621 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 return pAdapter;
6624
6625err_free_netdev:
6626 free_netdev(pAdapter->dev);
6627 wlan_hdd_release_intf_addr( pHddCtx,
6628 pAdapter->macAddressCurrent.bytes );
6629
6630resume_bmps:
6631 //If bmps disabled enable it
6632 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6633 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306634 if (pHddCtx->hdd_wlan_suspended)
6635 {
6636 hdd_set_pwrparams(pHddCtx);
6637 }
6638 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 }
6640 return NULL;
6641}
6642
6643VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6644 tANI_U8 rtnl_held )
6645{
6646 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6647 VOS_STATUS status;
6648
6649 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6650 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306651 {
6652 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6653 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006656
6657 while ( pCurrent->pAdapter != pAdapter )
6658 {
6659 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6660 if( VOS_STATUS_SUCCESS != status )
6661 break;
6662
6663 pCurrent = pNext;
6664 }
6665 pAdapterNode = pCurrent;
6666 if( VOS_STATUS_SUCCESS == status )
6667 {
6668 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6669 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306670
6671#ifdef FEATURE_WLAN_TDLS
6672
6673 /* A Mutex Lock is introduced while changing/initializing the mode to
6674 * protect the concurrent access for the Adapters by TDLS module.
6675 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306676 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306677#endif
6678
Jeff Johnson295189b2012-06-20 16:38:30 -07006679 hdd_remove_adapter( pHddCtx, pAdapterNode );
6680 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006681 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006682
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306683#ifdef FEATURE_WLAN_TDLS
6684 mutex_unlock(&pHddCtx->tdls_lock);
6685#endif
6686
Jeff Johnson295189b2012-06-20 16:38:30 -07006687
6688 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306689 if ((!vos_concurrent_open_sessions_running()) &&
6690 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6691 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306693 if (pHddCtx->hdd_wlan_suspended)
6694 {
6695 hdd_set_pwrparams(pHddCtx);
6696 }
6697 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 }
6699
6700 return VOS_STATUS_SUCCESS;
6701 }
6702
6703 return VOS_STATUS_E_FAILURE;
6704}
6705
6706VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6707{
6708 hdd_adapter_list_node_t *pHddAdapterNode;
6709 VOS_STATUS status;
6710
6711 ENTER();
6712
6713 do
6714 {
6715 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6716 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6717 {
6718 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6719 vos_mem_free( pHddAdapterNode );
6720 }
6721 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6722
6723 EXIT();
6724
6725 return VOS_STATUS_SUCCESS;
6726}
6727
6728void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6729{
6730 v_U8_t addIE[1] = {0};
6731
6732 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6733 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6734 eANI_BOOLEAN_FALSE) )
6735 {
6736 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006737 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 }
6739
6740 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6741 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6742 eANI_BOOLEAN_FALSE) )
6743 {
6744 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006745 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 }
6747
6748 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6749 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6750 eANI_BOOLEAN_FALSE) )
6751 {
6752 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006753 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 }
6755}
6756
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306757VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6758 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006759{
6760 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6761 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6762 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306763 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306764 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006765
6766 ENTER();
6767
6768 switch(pAdapter->device_mode)
6769 {
6770 case WLAN_HDD_INFRA_STATION:
6771 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006772 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306773 {
6774 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6775 if( hdd_connIsConnected(pstation) ||
6776 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 {
6778 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6779 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6780 pAdapter->sessionId,
6781 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6782 else
6783 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6784 pAdapter->sessionId,
6785 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6786 //success implies disconnect command got queued up successfully
6787 if(halStatus == eHAL_STATUS_SUCCESS)
6788 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306789 ret = wait_for_completion_interruptible_timeout(
6790 &pAdapter->disconnect_comp_var,
6791 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6792 if (ret <= 0)
6793 {
6794 hddLog(VOS_TRACE_LEVEL_ERROR,
6795 "%s: wait on disconnect_comp_var failed %ld",
6796 __func__, ret);
6797 }
6798 }
6799 else
6800 {
6801 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6802 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 }
6804 memset(&wrqu, '\0', sizeof(wrqu));
6805 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6806 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6807 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6808 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306809 else if(pstation->conn_info.connState ==
6810 eConnectionState_Disconnecting)
6811 {
6812 ret = wait_for_completion_interruptible_timeout(
6813 &pAdapter->disconnect_comp_var,
6814 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6815 if (ret <= 0)
6816 {
6817 hddLog(VOS_TRACE_LEVEL_ERROR,
6818 FL("wait on disconnect_comp_var failed %ld"), ret);
6819 }
6820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 else
6822 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306823 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6824 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306826 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6827 {
6828 while (pAdapter->is_roc_inprogress)
6829 {
6830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6831 "%s: ROC in progress for session %d!!!",
6832 __func__, pAdapter->sessionId);
6833 // waiting for ROC to expire
6834 msleep(500);
6835 /* In GO present case , if retry exceeds 3,
6836 it means something went wrong. */
6837 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6838 {
6839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6840 "%s: ROC completion is not received.!!!", __func__);
6841 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6842 pAdapter->sessionId);
6843 wait_for_completion_interruptible_timeout(
6844 &pAdapter->cancel_rem_on_chan_var,
6845 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6846 break;
6847 }
6848 }
6849 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306850#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306851#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306852 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6853#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306854 if (pAdapter->ipv6_notifier_registered)
6855 {
6856 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6857 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6858 pAdapter->ipv6_notifier_registered = false;
6859 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306860#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306861 if (pAdapter->ipv4_notifier_registered)
6862 {
6863 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6864 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6865 pAdapter->ipv4_notifier_registered = false;
6866 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306867#ifdef WLAN_OPEN_SOURCE
6868 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6869#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306870 /* It is possible that the caller of this function does not
6871 * wish to close the session
6872 */
6873 if (VOS_TRUE == bCloseSession &&
6874 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 {
6876 INIT_COMPLETION(pAdapter->session_close_comp_var);
6877 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306878 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6879 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006880 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306881 unsigned long ret;
6882
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306884 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306885 &pAdapter->session_close_comp_var,
6886 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306887 if ( 0 >= ret)
6888 {
6889 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306890 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306891 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 }
6893 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 break;
6896
6897 case WLAN_HDD_SOFTAP:
6898 case WLAN_HDD_P2P_GO:
6899 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306900 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6901 while (pAdapter->is_roc_inprogress) {
6902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6903 "%s: ROC in progress for session %d!!!",
6904 __func__, pAdapter->sessionId);
6905 msleep(500);
6906 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6908 "%s: ROC completion is not received.!!!", __func__);
6909 WLANSAP_CancelRemainOnChannel(
6910 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6911 wait_for_completion_interruptible_timeout(
6912 &pAdapter->cancel_rem_on_chan_var,
6913 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6914 break;
6915 }
6916 }
6917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 mutex_lock(&pHddCtx->sap_lock);
6919 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6920 {
6921 VOS_STATUS status;
6922 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6923
6924 //Stop Bss.
6925 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6926 if (VOS_IS_STATUS_SUCCESS(status))
6927 {
6928 hdd_hostapd_state_t *pHostapdState =
6929 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6930
6931 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6932
6933 if (!VOS_IS_STATUS_SUCCESS(status))
6934 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306935 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6936 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 }
6938 }
6939 else
6940 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006941 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 }
6943 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306944 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006945
6946 if (eHAL_STATUS_FAILURE ==
6947 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6948 0, NULL, eANI_BOOLEAN_FALSE))
6949 {
6950 hddLog(LOGE,
6951 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006952 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 }
6954
6955 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6956 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6957 eANI_BOOLEAN_FALSE) )
6958 {
6959 hddLog(LOGE,
6960 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6961 }
6962
6963 // Reset WNI_CFG_PROBE_RSP Flags
6964 wlan_hdd_reset_prob_rspies(pAdapter);
6965 kfree(pAdapter->sessionCtx.ap.beacon);
6966 pAdapter->sessionCtx.ap.beacon = NULL;
6967 }
6968 mutex_unlock(&pHddCtx->sap_lock);
6969 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006970
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006972#ifdef WLAN_OPEN_SOURCE
6973 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6974#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006976
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 default:
6978 break;
6979 }
6980
6981 EXIT();
6982 return VOS_STATUS_SUCCESS;
6983}
6984
6985VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6986{
6987 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6988 VOS_STATUS status;
6989 hdd_adapter_t *pAdapter;
6990
6991 ENTER();
6992
6993 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6994
6995 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6996 {
6997 pAdapter = pAdapterNode->pAdapter;
6998 netif_tx_disable(pAdapter->dev);
6999 netif_carrier_off(pAdapter->dev);
7000
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307001 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007002
7003 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7004 pAdapterNode = pNext;
7005 }
7006
7007 EXIT();
7008
7009 return VOS_STATUS_SUCCESS;
7010}
7011
Rajeev Kumarf999e582014-01-09 17:33:29 -08007012
7013#ifdef FEATURE_WLAN_BATCH_SCAN
7014/**---------------------------------------------------------------------------
7015
7016 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7017 structures
7018
7019 \param - pAdapter Pointer to HDD adapter
7020
7021 \return - None
7022
7023 --------------------------------------------------------------------------*/
7024void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7025{
7026 tHddBatchScanRsp *pNode;
7027 tHddBatchScanRsp *pPrev;
7028
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307029 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007030 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307031 hddLog(VOS_TRACE_LEVEL_ERROR,
7032 "%s: Adapter context is Null", __func__);
7033 return;
7034 }
7035
7036 pNode = pAdapter->pBatchScanRsp;
7037 while (pNode)
7038 {
7039 pPrev = pNode;
7040 pNode = pNode->pNext;
7041 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007042 }
7043
7044 pAdapter->pBatchScanRsp = NULL;
7045 pAdapter->numScanList = 0;
7046 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7047 pAdapter->prev_batch_id = 0;
7048
7049 return;
7050}
7051#endif
7052
7053
Jeff Johnson295189b2012-06-20 16:38:30 -07007054VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7055{
7056 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7057 VOS_STATUS status;
7058 hdd_adapter_t *pAdapter;
7059
7060 ENTER();
7061
7062 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7063
7064 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7065 {
7066 pAdapter = pAdapterNode->pAdapter;
7067 netif_tx_disable(pAdapter->dev);
7068 netif_carrier_off(pAdapter->dev);
7069
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007070 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7071
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307073
7074 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7075
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307076 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7077 {
7078 hdd_wmm_adapter_close( pAdapter );
7079 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007081
Rajeev Kumarf999e582014-01-09 17:33:29 -08007082#ifdef FEATURE_WLAN_BATCH_SCAN
7083 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7084 {
7085 hdd_deinit_batch_scan(pAdapter);
7086 }
7087#endif
7088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7090 pAdapterNode = pNext;
7091 }
7092
7093 EXIT();
7094
7095 return VOS_STATUS_SUCCESS;
7096}
7097
7098VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7099{
7100 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7101 VOS_STATUS status;
7102 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307103 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007104
7105 ENTER();
7106
7107 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7108
7109 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7110 {
7111 pAdapter = pAdapterNode->pAdapter;
7112
Kumar Anand82c009f2014-05-29 00:29:42 -07007113 hdd_wmm_init( pAdapter );
7114
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 switch(pAdapter->device_mode)
7116 {
7117 case WLAN_HDD_INFRA_STATION:
7118 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007119 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307120
7121 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7122
Jeff Johnson295189b2012-06-20 16:38:30 -07007123 hdd_init_station_mode(pAdapter);
7124 /* Open the gates for HDD to receive Wext commands */
7125 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007126 pHddCtx->scan_info.mScanPending = FALSE;
7127 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007128
7129 //Trigger the initial scan
7130 hdd_wlan_initial_scan(pAdapter);
7131
7132 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307133 if (eConnectionState_Associated == connState ||
7134 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 {
7136 union iwreq_data wrqu;
7137 memset(&wrqu, '\0', sizeof(wrqu));
7138 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7139 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7140 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007141 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007142
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 /* indicate disconnected event to nl80211 */
7144 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7145 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307147 else if (eConnectionState_Connecting == connState)
7148 {
7149 /*
7150 * Indicate connect failure to supplicant if we were in the
7151 * process of connecting
7152 */
7153 cfg80211_connect_result(pAdapter->dev, NULL,
7154 NULL, 0, NULL, 0,
7155 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7156 GFP_KERNEL);
7157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 break;
7159
7160 case WLAN_HDD_SOFTAP:
7161 /* softAP can handle SSR */
7162 break;
7163
7164 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007167 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 break;
7169
7170 case WLAN_HDD_MONITOR:
7171 /* monitor interface start */
7172 break;
7173 default:
7174 break;
7175 }
7176
7177 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7178 pAdapterNode = pNext;
7179 }
7180
7181 EXIT();
7182
7183 return VOS_STATUS_SUCCESS;
7184}
7185
7186VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7187{
7188 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7189 hdd_adapter_t *pAdapter;
7190 VOS_STATUS status;
7191 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307192 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007193
7194 ENTER();
7195
7196 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7197
7198 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7199 {
7200 pAdapter = pAdapterNode->pAdapter;
7201
7202 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7203 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7204 {
7205 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7206 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7207
Abhishek Singhf4669da2014-05-26 15:07:49 +05307208 hddLog(VOS_TRACE_LEVEL_INFO,
7209 "%s: Set HDD connState to eConnectionState_NotConnected",
7210 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007211 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7212 init_completion(&pAdapter->disconnect_comp_var);
7213 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7214 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7215
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307216 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 &pAdapter->disconnect_comp_var,
7218 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307219 if (0 >= ret)
7220 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7221 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007222
7223 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7224 pHddCtx->isAmpAllowed = VOS_FALSE;
7225 sme_RoamConnect(pHddCtx->hHal,
7226 pAdapter->sessionId, &(pWextState->roamProfile),
7227 &roamId);
7228 }
7229
7230 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7231 pAdapterNode = pNext;
7232 }
7233
7234 EXIT();
7235
7236 return VOS_STATUS_SUCCESS;
7237}
7238
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007239void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7240{
7241 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7242 VOS_STATUS status;
7243 hdd_adapter_t *pAdapter;
7244 hdd_station_ctx_t *pHddStaCtx;
7245 hdd_ap_ctx_t *pHddApCtx;
7246 hdd_hostapd_state_t * pHostapdState;
7247 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7248 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7249 const char *p2pMode = "DEV";
7250 const char *ccMode = "Standalone";
7251 int n;
7252
7253 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7254 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7255 {
7256 pAdapter = pAdapterNode->pAdapter;
7257 switch (pAdapter->device_mode) {
7258 case WLAN_HDD_INFRA_STATION:
7259 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7260 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7261 staChannel = pHddStaCtx->conn_info.operationChannel;
7262 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7263 }
7264 break;
7265 case WLAN_HDD_P2P_CLIENT:
7266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7267 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7268 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7269 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7270 p2pMode = "CLI";
7271 }
7272 break;
7273 case WLAN_HDD_P2P_GO:
7274 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7275 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7276 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7277 p2pChannel = pHddApCtx->operatingChannel;
7278 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7279 }
7280 p2pMode = "GO";
7281 break;
7282 case WLAN_HDD_SOFTAP:
7283 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7284 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7285 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7286 apChannel = pHddApCtx->operatingChannel;
7287 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7288 }
7289 break;
7290 default:
7291 break;
7292 }
7293 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7294 pAdapterNode = pNext;
7295 }
7296 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7297 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7298 }
7299 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7300 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7301 if (p2pChannel > 0) {
7302 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7303 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7304 }
7305 if (apChannel > 0) {
7306 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7307 apChannel, MAC_ADDR_ARRAY(apBssid));
7308 }
7309
7310 if (p2pChannel > 0 && apChannel > 0) {
7311 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7312 }
7313}
7314
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007315bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007316{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007317 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007318}
7319
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007320/* Once SSR is disabled then it cannot be set. */
7321void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007322{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007323 if (HDD_SSR_DISABLED == isSsrRequired)
7324 return;
7325
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 isSsrRequired = value;
7327}
7328
7329VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7330 hdd_adapter_list_node_t** ppAdapterNode)
7331{
7332 VOS_STATUS status;
7333 spin_lock(&pHddCtx->hddAdapters.lock);
7334 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7335 (hdd_list_node_t**) ppAdapterNode );
7336 spin_unlock(&pHddCtx->hddAdapters.lock);
7337 return status;
7338}
7339
7340VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7341 hdd_adapter_list_node_t* pAdapterNode,
7342 hdd_adapter_list_node_t** pNextAdapterNode)
7343{
7344 VOS_STATUS status;
7345 spin_lock(&pHddCtx->hddAdapters.lock);
7346 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7347 (hdd_list_node_t*) pAdapterNode,
7348 (hdd_list_node_t**)pNextAdapterNode );
7349
7350 spin_unlock(&pHddCtx->hddAdapters.lock);
7351 return status;
7352}
7353
7354VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7355 hdd_adapter_list_node_t* pAdapterNode)
7356{
7357 VOS_STATUS status;
7358 spin_lock(&pHddCtx->hddAdapters.lock);
7359 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7360 &pAdapterNode->node );
7361 spin_unlock(&pHddCtx->hddAdapters.lock);
7362 return status;
7363}
7364
7365VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7366 hdd_adapter_list_node_t** ppAdapterNode)
7367{
7368 VOS_STATUS status;
7369 spin_lock(&pHddCtx->hddAdapters.lock);
7370 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7371 (hdd_list_node_t**) ppAdapterNode );
7372 spin_unlock(&pHddCtx->hddAdapters.lock);
7373 return status;
7374}
7375
7376VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7377 hdd_adapter_list_node_t* pAdapterNode)
7378{
7379 VOS_STATUS status;
7380 spin_lock(&pHddCtx->hddAdapters.lock);
7381 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7382 (hdd_list_node_t*) pAdapterNode );
7383 spin_unlock(&pHddCtx->hddAdapters.lock);
7384 return status;
7385}
7386
7387VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7388 hdd_adapter_list_node_t* pAdapterNode)
7389{
7390 VOS_STATUS status;
7391 spin_lock(&pHddCtx->hddAdapters.lock);
7392 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7393 (hdd_list_node_t*) pAdapterNode );
7394 spin_unlock(&pHddCtx->hddAdapters.lock);
7395 return status;
7396}
7397
7398hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7399 tSirMacAddr macAddr )
7400{
7401 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7402 hdd_adapter_t *pAdapter;
7403 VOS_STATUS status;
7404
7405 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7406
7407 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7408 {
7409 pAdapter = pAdapterNode->pAdapter;
7410
7411 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7412 macAddr, sizeof(tSirMacAddr) ) )
7413 {
7414 return pAdapter;
7415 }
7416 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7417 pAdapterNode = pNext;
7418 }
7419
7420 return NULL;
7421
7422}
7423
7424hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7425{
7426 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7427 hdd_adapter_t *pAdapter;
7428 VOS_STATUS status;
7429
7430 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7431
7432 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7433 {
7434 pAdapter = pAdapterNode->pAdapter;
7435
7436 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7437 IFNAMSIZ ) )
7438 {
7439 return pAdapter;
7440 }
7441 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7442 pAdapterNode = pNext;
7443 }
7444
7445 return NULL;
7446
7447}
7448
7449hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7450{
7451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7452 hdd_adapter_t *pAdapter;
7453 VOS_STATUS status;
7454
7455 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7456
7457 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7458 {
7459 pAdapter = pAdapterNode->pAdapter;
7460
7461 if( pAdapter && (mode == pAdapter->device_mode) )
7462 {
7463 return pAdapter;
7464 }
7465 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7466 pAdapterNode = pNext;
7467 }
7468
7469 return NULL;
7470
7471}
7472
7473//Remove this function later
7474hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7475{
7476 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7477 hdd_adapter_t *pAdapter;
7478 VOS_STATUS status;
7479
7480 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7481
7482 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7483 {
7484 pAdapter = pAdapterNode->pAdapter;
7485
7486 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7487 {
7488 return pAdapter;
7489 }
7490
7491 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7492 pAdapterNode = pNext;
7493 }
7494
7495 return NULL;
7496
7497}
7498
Jeff Johnson295189b2012-06-20 16:38:30 -07007499/**---------------------------------------------------------------------------
7500
7501 \brief hdd_set_monitor_tx_adapter() -
7502
7503 This API initializes the adapter to be used while transmitting on monitor
7504 adapter.
7505
7506 \param - pHddCtx - Pointer to the HDD context.
7507 pAdapter - Adapter that will used for TX. This can be NULL.
7508 \return - None.
7509 --------------------------------------------------------------------------*/
7510void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7511{
7512 hdd_adapter_t *pMonAdapter;
7513
7514 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7515
7516 if( NULL != pMonAdapter )
7517 {
7518 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7519 }
7520}
Jeff Johnson295189b2012-06-20 16:38:30 -07007521/**---------------------------------------------------------------------------
7522
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307523 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007524
7525 This API returns the operating channel of the requested device mode
7526
7527 \param - pHddCtx - Pointer to the HDD context.
7528 - mode - Device mode for which operating channel is required
7529 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7530 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7531 \return - channel number. "0" id the requested device is not found OR it is not connected.
7532 --------------------------------------------------------------------------*/
7533v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7534{
7535 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7536 VOS_STATUS status;
7537 hdd_adapter_t *pAdapter;
7538 v_U8_t operatingChannel = 0;
7539
7540 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7541
7542 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7543 {
7544 pAdapter = pAdapterNode->pAdapter;
7545
7546 if( mode == pAdapter->device_mode )
7547 {
7548 switch(pAdapter->device_mode)
7549 {
7550 case WLAN_HDD_INFRA_STATION:
7551 case WLAN_HDD_P2P_CLIENT:
7552 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7553 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7554 break;
7555 case WLAN_HDD_SOFTAP:
7556 case WLAN_HDD_P2P_GO:
7557 /*softap connection info */
7558 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7559 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7560 break;
7561 default:
7562 break;
7563 }
7564
7565 break; //Found the device of interest. break the loop
7566 }
7567
7568 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7569 pAdapterNode = pNext;
7570 }
7571 return operatingChannel;
7572}
7573
7574#ifdef WLAN_FEATURE_PACKET_FILTERING
7575/**---------------------------------------------------------------------------
7576
7577 \brief hdd_set_multicast_list() -
7578
7579 This used to set the multicast address list.
7580
7581 \param - dev - Pointer to the WLAN device.
7582 - skb - Pointer to OS packet (sk_buff).
7583 \return - success/fail
7584
7585 --------------------------------------------------------------------------*/
7586static void hdd_set_multicast_list(struct net_device *dev)
7587{
7588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 int mc_count;
7590 int i = 0;
7591 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307592
7593 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007594 {
7595 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307596 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 return;
7598 }
7599
7600 if (dev->flags & IFF_ALLMULTI)
7601 {
7602 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007603 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307604 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 }
7606 else
7607 {
7608 mc_count = netdev_mc_count(dev);
7609 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007610 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7612 {
7613 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007614 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307615 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 return;
7617 }
7618
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307619 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007620
7621 netdev_for_each_mc_addr(ha, dev) {
7622 if (i == mc_count)
7623 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307624 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7625 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307628 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 i++;
7630 }
7631 }
7632 return;
7633}
7634#endif
7635
7636/**---------------------------------------------------------------------------
7637
7638 \brief hdd_select_queue() -
7639
7640 This function is registered with the Linux OS for network
7641 core to decide which queue to use first.
7642
7643 \param - dev - Pointer to the WLAN device.
7644 - skb - Pointer to OS packet (sk_buff).
7645 \return - ac, Queue Index/access category corresponding to UP in IP header
7646
7647 --------------------------------------------------------------------------*/
7648v_U16_t hdd_select_queue(struct net_device *dev,
7649 struct sk_buff *skb)
7650{
7651 return hdd_wmm_select_queue(dev, skb);
7652}
7653
7654
7655/**---------------------------------------------------------------------------
7656
7657 \brief hdd_wlan_initial_scan() -
7658
7659 This function triggers the initial scan
7660
7661 \param - pAdapter - Pointer to the HDD adapter.
7662
7663 --------------------------------------------------------------------------*/
7664void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7665{
7666 tCsrScanRequest scanReq;
7667 tCsrChannelInfo channelInfo;
7668 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007669 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7671
7672 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7673 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7674 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7675
7676 if(sme_Is11dSupported(pHddCtx->hHal))
7677 {
7678 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7679 if ( HAL_STATUS_SUCCESS( halStatus ) )
7680 {
7681 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7682 if( !scanReq.ChannelInfo.ChannelList )
7683 {
7684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7685 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007686 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 return;
7688 }
7689 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7690 channelInfo.numOfChannels);
7691 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7692 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007693 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 }
7695
7696 scanReq.scanType = eSIR_PASSIVE_SCAN;
7697 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7698 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7699 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7700 }
7701 else
7702 {
7703 scanReq.scanType = eSIR_ACTIVE_SCAN;
7704 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7705 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7706 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7707 }
7708
7709 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7710 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7711 {
7712 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7713 __func__, halStatus );
7714 }
7715
7716 if(sme_Is11dSupported(pHddCtx->hHal))
7717 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7718}
7719
Jeff Johnson295189b2012-06-20 16:38:30 -07007720/**---------------------------------------------------------------------------
7721
7722 \brief hdd_full_power_callback() - HDD full power callback function
7723
7724 This is the function invoked by SME to inform the result of a full power
7725 request issued by HDD
7726
7727 \param - callbackcontext - Pointer to cookie
7728 \param - status - result of request
7729
7730 \return - None
7731
7732 --------------------------------------------------------------------------*/
7733static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7734{
Jeff Johnson72a40512013-12-19 10:14:15 -08007735 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007736
7737 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307738 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007739
7740 if (NULL == callbackContext)
7741 {
7742 hddLog(VOS_TRACE_LEVEL_ERROR,
7743 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007744 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 return;
7746 }
7747
Jeff Johnson72a40512013-12-19 10:14:15 -08007748 /* there is a race condition that exists between this callback
7749 function and the caller since the caller could time out either
7750 before or while this code is executing. we use a spinlock to
7751 serialize these actions */
7752 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007753
7754 if (POWER_CONTEXT_MAGIC != pContext->magic)
7755 {
7756 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007757 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 hddLog(VOS_TRACE_LEVEL_WARN,
7759 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007760 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 return;
7762 }
7763
Jeff Johnson72a40512013-12-19 10:14:15 -08007764 /* context is valid so caller is still waiting */
7765
7766 /* paranoia: invalidate the magic */
7767 pContext->magic = 0;
7768
7769 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007771
7772 /* serialization is complete */
7773 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007774}
7775
7776/**---------------------------------------------------------------------------
7777
7778 \brief hdd_wlan_exit() - HDD WLAN exit function
7779
7780 This is the driver exit point (invoked during rmmod)
7781
7782 \param - pHddCtx - Pointer to the HDD Context
7783
7784 \return - None
7785
7786 --------------------------------------------------------------------------*/
7787void hdd_wlan_exit(hdd_context_t *pHddCtx)
7788{
7789 eHalStatus halStatus;
7790 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7791 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307792 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007793 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007794 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307796 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007797
7798 ENTER();
7799
Jeff Johnson88ba7742013-02-27 14:36:02 -08007800 if (VOS_FTM_MODE != hdd_get_conparam())
7801 {
7802 // Unloading, restart logic is no more required.
7803 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007804
c_hpothu5ab05e92014-06-13 17:34:05 +05307805 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7806 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307808 pAdapter = pAdapterNode->pAdapter;
7809 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307811 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7812 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7813 {
7814 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7815 hdd_UnregisterWext(pAdapter->dev);
7816 }
7817 // Cancel any outstanding scan requests. We are about to close all
7818 // of our adapters, but an adapter structure is what SME passes back
7819 // to our callback function. Hence if there are any outstanding scan
7820 // requests then there is a race condition between when the adapter
7821 // is closed and when the callback is invoked.We try to resolve that
7822 // race condition here by canceling any outstanding scans before we
7823 // close the adapters.
7824 // Note that the scans may be cancelled in an asynchronous manner,
7825 // so ideally there needs to be some kind of synchronization. Rather
7826 // than introduce a new synchronization here, we will utilize the
7827 // fact that we are about to Request Full Power, and since that is
7828 // synchronized, the expectation is that by the time Request Full
7829 // Power has completed all scans will be cancelled.
7830 if (pHddCtx->scan_info.mScanPending)
7831 {
7832 hddLog(VOS_TRACE_LEVEL_INFO,
7833 FL("abort scan mode: %d sessionId: %d"),
7834 pAdapter->device_mode,
7835 pAdapter->sessionId);
7836 hdd_abort_mac_scan(pHddCtx,
7837 pAdapter->sessionId,
7838 eCSR_SCAN_ABORT_DEFAULT);
7839 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307841 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7842 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 }
7844 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307845 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007846 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307847 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007848 wlan_hdd_ftm_close(pHddCtx);
7849 goto free_hdd_ctx;
7850 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307851
Jeff Johnson295189b2012-06-20 16:38:30 -07007852 /* DeRegister with platform driver as client for Suspend/Resume */
7853 vosStatus = hddDeregisterPmOps(pHddCtx);
7854 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7855 {
7856 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7857 VOS_ASSERT(0);
7858 }
7859
7860 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7861 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7862 {
7863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007865
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007866 //Stop the traffic monitor timer
7867 if ( VOS_TIMER_STATE_RUNNING ==
7868 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7869 {
7870 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7871 }
7872
7873 // Destroy the traffic monitor timer
7874 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7875 &pHddCtx->tx_rx_trafficTmr)))
7876 {
7877 hddLog(VOS_TRACE_LEVEL_ERROR,
7878 "%s: Cannot deallocate Traffic monitor timer", __func__);
7879 }
7880
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 //Disable IMPS/BMPS as we do not want the device to enter any power
7882 //save mode during shutdown
7883 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7884 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7885 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7886
7887 //Ensure that device is in full power as we will touch H/W during vos_Stop
7888 init_completion(&powerContext.completion);
7889 powerContext.magic = POWER_CONTEXT_MAGIC;
7890
7891 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7892 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7893
7894 if (eHAL_STATUS_SUCCESS != halStatus)
7895 {
7896 if (eHAL_STATUS_PMC_PENDING == halStatus)
7897 {
7898 /* request was sent -- wait for the response */
7899 lrc = wait_for_completion_interruptible_timeout(
7900 &powerContext.completion,
7901 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 if (lrc <= 0)
7903 {
7904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007905 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 }
7907 }
7908 else
7909 {
7910 hddLog(VOS_TRACE_LEVEL_ERROR,
7911 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007912 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 /* continue -- need to clean up as much as possible */
7914 }
7915 }
7916
Jeff Johnson72a40512013-12-19 10:14:15 -08007917 /* either we never sent a request, we sent a request and received a
7918 response or we sent a request and timed out. if we never sent a
7919 request or if we sent a request and got a response, we want to
7920 clear the magic out of paranoia. if we timed out there is a
7921 race condition such that the callback function could be
7922 executing at the same time we are. of primary concern is if the
7923 callback function had already verified the "magic" but had not
7924 yet set the completion variable when a timeout occurred. we
7925 serialize these activities by invalidating the magic while
7926 holding a shared spinlock which will cause us to block if the
7927 callback is currently executing */
7928 spin_lock(&hdd_context_lock);
7929 powerContext.magic = 0;
7930 spin_unlock(&hdd_context_lock);
7931
Yue Ma0d4891e2013-08-06 17:01:45 -07007932 hdd_debugfs_exit(pHddCtx);
7933
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 // Unregister the Net Device Notifier
7935 unregister_netdevice_notifier(&hdd_netdev_notifier);
7936
Jeff Johnson295189b2012-06-20 16:38:30 -07007937 hdd_stop_all_adapters( pHddCtx );
7938
Jeff Johnson295189b2012-06-20 16:38:30 -07007939#ifdef WLAN_BTAMP_FEATURE
7940 vosStatus = WLANBAP_Stop(pVosContext);
7941 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7942 {
7943 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7944 "%s: Failed to stop BAP",__func__);
7945 }
7946#endif //WLAN_BTAMP_FEATURE
7947
7948 //Stop all the modules
7949 vosStatus = vos_stop( pVosContext );
7950 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7951 {
7952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7953 "%s: Failed to stop VOSS",__func__);
7954 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7955 }
7956
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 //Assert Deep sleep signal now to put Libra HW in lowest power state
7958 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7959 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7960
7961 //Vote off any PMIC voltage supplies
7962 vos_chipPowerDown(NULL, NULL, NULL);
7963
7964 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7965
Leo Chang59cdc7e2013-07-10 10:08:21 -07007966
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007969
7970 //Close the scheduler before calling vos_close to make sure no thread is
7971 // scheduled after the each module close is called i.e after all the data
7972 // structures are freed.
7973 vosStatus = vos_sched_close( pVosContext );
7974 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7975 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7976 "%s: Failed to close VOSS Scheduler",__func__);
7977 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7978 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007979#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007980#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7981 /* Destroy the wake lock */
7982 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7983#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007984 /* Destroy the wake lock */
7985 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007986#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007987
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307988#ifdef CONFIG_ENABLE_LINUX_REG
7989 vosStatus = vos_nv_close();
7990 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7991 {
7992 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7993 "%s: Failed to close NV", __func__);
7994 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7995 }
7996#endif
7997
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 //Close VOSS
7999 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8000 vos_close(pVosContext);
8001
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 //Close Watchdog
8003 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8004 vos_watchdog_close(pVosContext);
8005
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308006 //Clean up HDD Nlink Service
8007 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308008
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308009#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308010 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308011 {
8012 wlan_logging_sock_deactivate_svc();
8013 }
8014#endif
8015
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308016#ifdef WLAN_KD_READY_NOTIFIER
8017 nl_srv_exit(pHddCtx->ptt_pid);
8018#else
8019 nl_srv_exit();
8020#endif /* WLAN_KD_READY_NOTIFIER */
8021
8022
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 /* Cancel the vote for XO Core ON.
8024 * This is done here to ensure there is no race condition since MC, TX and WD threads have
8025 * exited at this point
8026 */
8027 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008028 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07008029 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8030 {
8031 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
8032 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008033 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 }
8035
8036 hdd_close_all_adapters( pHddCtx );
8037
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 /* free the power on lock from platform driver */
8039 if (free_riva_power_on_lock("wlan"))
8040 {
8041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8042 __func__);
8043 }
8044
Jeff Johnson88ba7742013-02-27 14:36:02 -08008045free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308046
8047 //Free up dynamically allocated members inside HDD Adapter
8048 if (pHddCtx->cfg_ini)
8049 {
8050 kfree(pHddCtx->cfg_ini);
8051 pHddCtx->cfg_ini= NULL;
8052 }
8053
Leo Changf04ddad2013-09-18 13:46:38 -07008054 /* FTM mode, WIPHY did not registered
8055 If un-register here, system crash will happen */
8056 if (VOS_FTM_MODE != hdd_get_conparam())
8057 {
8058 wiphy_unregister(wiphy) ;
8059 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 if (hdd_is_ssr_required())
8062 {
8063 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008064 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 msleep(5000);
8066 }
8067 hdd_set_ssr_required (VOS_FALSE);
8068}
8069
8070
8071/**---------------------------------------------------------------------------
8072
8073 \brief hdd_update_config_from_nv() - Function to update the contents of
8074 the running configuration with parameters taken from NV storage
8075
8076 \param - pHddCtx - Pointer to the HDD global context
8077
8078 \return - VOS_STATUS_SUCCESS if successful
8079
8080 --------------------------------------------------------------------------*/
8081static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8082{
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 v_BOOL_t itemIsValid = VOS_FALSE;
8084 VOS_STATUS status;
8085 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8086 v_U8_t macLoop;
8087
8088 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8089 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8090 if(status != VOS_STATUS_SUCCESS)
8091 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008092 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 return VOS_STATUS_E_FAILURE;
8094 }
8095
8096 if (itemIsValid == VOS_TRUE)
8097 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008098 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8100 VOS_MAX_CONCURRENCY_PERSONA);
8101 if(status != VOS_STATUS_SUCCESS)
8102 {
8103 /* Get MAC from NV fail, not update CFG info
8104 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008105 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 return VOS_STATUS_E_FAILURE;
8107 }
8108
8109 /* If first MAC is not valid, treat all others are not valid
8110 * Then all MACs will be got from ini file */
8111 if(vos_is_macaddr_zero(&macFromNV[0]))
8112 {
8113 /* MAC address in NV file is not configured yet */
8114 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8115 return VOS_STATUS_E_INVAL;
8116 }
8117
8118 /* Get MAC address from NV, update CFG info */
8119 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8120 {
8121 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8122 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308123 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 /* This MAC is not valid, skip it
8125 * This MAC will be got from ini file */
8126 }
8127 else
8128 {
8129 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8130 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8131 VOS_MAC_ADDR_SIZE);
8132 }
8133 }
8134 }
8135 else
8136 {
8137 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8138 return VOS_STATUS_E_FAILURE;
8139 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008140
Jeff Johnson295189b2012-06-20 16:38:30 -07008141
8142 return VOS_STATUS_SUCCESS;
8143}
8144
8145/**---------------------------------------------------------------------------
8146
8147 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8148
8149 \param - pAdapter - Pointer to the HDD
8150
8151 \return - None
8152
8153 --------------------------------------------------------------------------*/
8154VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8155{
8156 eHalStatus halStatus;
8157 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308158 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008159
Jeff Johnson295189b2012-06-20 16:38:30 -07008160
8161 // Send ready indication to the HDD. This will kick off the MAC
8162 // into a 'running' state and should kick off an initial scan.
8163 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8164 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8165 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308166 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 "code %08d [x%08x]",__func__, halStatus, halStatus );
8168 return VOS_STATUS_E_FAILURE;
8169 }
8170
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308171 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8173 // And RIVA will crash
8174 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8175 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308176 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8177 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8178
8179
Jeff Johnson295189b2012-06-20 16:38:30 -07008180 return VOS_STATUS_SUCCESS;
8181}
8182
Jeff Johnson295189b2012-06-20 16:38:30 -07008183/* wake lock APIs for HDD */
8184void hdd_prevent_suspend(void)
8185{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008186#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008188#else
8189 wcnss_prevent_suspend();
8190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008191}
8192
8193void hdd_allow_suspend(void)
8194{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008195#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008197#else
8198 wcnss_allow_suspend();
8199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008200}
8201
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308202void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008203{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008204#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008205 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008206#else
8207 /* Do nothing as there is no API in wcnss for timeout*/
8208#endif
8209}
8210
Jeff Johnson295189b2012-06-20 16:38:30 -07008211/**---------------------------------------------------------------------------
8212
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008213 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8214 information between Host and Riva
8215
8216 This function gets reported version of FW
8217 It also finds the version of Riva headers used to compile the host
8218 It compares the above two and prints a warning if they are different
8219 It gets the SW and HW version string
8220 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8221 indicating the features they support through a bitmap
8222
8223 \param - pHddCtx - Pointer to HDD context
8224
8225 \return - void
8226
8227 --------------------------------------------------------------------------*/
8228
8229void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8230{
8231
8232 tSirVersionType versionCompiled;
8233 tSirVersionType versionReported;
8234 tSirVersionString versionString;
8235 tANI_U8 fwFeatCapsMsgSupported = 0;
8236 VOS_STATUS vstatus;
8237
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008238 memset(&versionCompiled, 0, sizeof(versionCompiled));
8239 memset(&versionReported, 0, sizeof(versionReported));
8240
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008241 /* retrieve and display WCNSS version information */
8242 do {
8243
8244 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8245 &versionCompiled);
8246 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8247 {
8248 hddLog(VOS_TRACE_LEVEL_FATAL,
8249 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008250 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008251 break;
8252 }
8253
8254 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8255 &versionReported);
8256 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8257 {
8258 hddLog(VOS_TRACE_LEVEL_FATAL,
8259 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008260 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008261 break;
8262 }
8263
8264 if ((versionCompiled.major != versionReported.major) ||
8265 (versionCompiled.minor != versionReported.minor) ||
8266 (versionCompiled.version != versionReported.version) ||
8267 (versionCompiled.revision != versionReported.revision))
8268 {
8269 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8270 "Host expected %u.%u.%u.%u\n",
8271 WLAN_MODULE_NAME,
8272 (int)versionReported.major,
8273 (int)versionReported.minor,
8274 (int)versionReported.version,
8275 (int)versionReported.revision,
8276 (int)versionCompiled.major,
8277 (int)versionCompiled.minor,
8278 (int)versionCompiled.version,
8279 (int)versionCompiled.revision);
8280 }
8281 else
8282 {
8283 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8284 WLAN_MODULE_NAME,
8285 (int)versionReported.major,
8286 (int)versionReported.minor,
8287 (int)versionReported.version,
8288 (int)versionReported.revision);
8289 }
8290
8291 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8292 versionString,
8293 sizeof(versionString));
8294 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8295 {
8296 hddLog(VOS_TRACE_LEVEL_FATAL,
8297 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008298 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008299 break;
8300 }
8301
8302 pr_info("%s: WCNSS software version %s\n",
8303 WLAN_MODULE_NAME, versionString);
8304
8305 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8306 versionString,
8307 sizeof(versionString));
8308 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8309 {
8310 hddLog(VOS_TRACE_LEVEL_FATAL,
8311 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008312 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008313 break;
8314 }
8315
8316 pr_info("%s: WCNSS hardware version %s\n",
8317 WLAN_MODULE_NAME, versionString);
8318
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008319 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8320 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008321 send the message only if it the riva is 1.1
8322 minor numbers for different riva branches:
8323 0 -> (1.0)Mainline Build
8324 1 -> (1.1)Mainline Build
8325 2->(1.04) Stability Build
8326 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008327 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008328 ((versionReported.minor>=1) && (versionReported.version>=1)))
8329 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8330 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008331
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008332 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008333 {
8334#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8335 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8336 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8337#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008338 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8339 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8340 {
8341 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8342 }
8343
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008344 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008345 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008346
8347 } while (0);
8348
8349}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308350void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8351{
8352 struct sk_buff *skb;
8353 struct nlmsghdr *nlh;
8354 tAniMsgHdr *ani_hdr;
8355
8356 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8357
8358 if(skb == NULL) {
8359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8360 "%s: alloc_skb failed", __func__);
8361 return;
8362 }
8363
8364 nlh = (struct nlmsghdr *)skb->data;
8365 nlh->nlmsg_pid = 0; /* from kernel */
8366 nlh->nlmsg_flags = 0;
8367 nlh->nlmsg_seq = 0;
8368 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8369
8370 ani_hdr = NLMSG_DATA(nlh);
8371 ani_hdr->type = type;
8372
8373 switch(type) {
8374 case WLAN_SVC_SAP_RESTART_IND:
8375 ani_hdr->length = 0;
8376 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8377 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8378 break;
8379 default:
8380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8381 "Attempt to send unknown nlink message %d", type);
8382 kfree_skb(skb);
8383 return;
8384 }
8385
8386 nl_srv_bcast(skb);
8387
8388 return;
8389}
8390
8391
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008392
8393/**---------------------------------------------------------------------------
8394
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308395 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8396
8397 \param - pHddCtx - Pointer to the hdd context
8398
8399 \return - true if hardware supports 5GHz
8400
8401 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308402boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308403{
8404 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8405 * then hardware support 5Ghz.
8406 */
8407 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8408 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308410 return true;
8411 }
8412 else
8413 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308415 __func__);
8416 return false;
8417 }
8418}
8419
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308420/**---------------------------------------------------------------------------
8421
8422 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8423 generate function
8424
8425 This is generate the random mac address for WLAN interface
8426
8427 \param - pHddCtx - Pointer to HDD context
8428 idx - Start interface index to get auto
8429 generated mac addr.
8430 mac_addr - Mac address
8431
8432 \return - 0 for success, < 0 for failure
8433
8434 --------------------------------------------------------------------------*/
8435
8436static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8437 int idx, v_MACADDR_t mac_addr)
8438{
8439 int i;
8440 unsigned int serialno;
8441 serialno = wcnss_get_serial_number();
8442
8443 if (0 != serialno)
8444 {
8445 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8446 bytes of the serial number that can be used to generate
8447 the other 3 bytes of the MAC address. Mask off all but
8448 the lower 3 bytes (this will also make sure we don't
8449 overflow in the next step) */
8450 serialno &= 0x00FFFFFF;
8451
8452 /* we need a unique address for each session */
8453 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8454
8455 /* autogen other Mac addresses */
8456 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8457 {
8458 /* start with the entire default address */
8459 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8460 /* then replace the lower 3 bytes */
8461 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8462 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8463 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8464
8465 serialno++;
8466 hddLog(VOS_TRACE_LEVEL_ERROR,
8467 "%s: Derived Mac Addr: "
8468 MAC_ADDRESS_STR, __func__,
8469 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8470 }
8471
8472 }
8473 else
8474 {
8475 hddLog(LOGE, FL("Failed to Get Serial NO"));
8476 return -1;
8477 }
8478 return 0;
8479}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308480
8481/**---------------------------------------------------------------------------
8482
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308483 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8484 completed to flush out the scan results
8485
8486 11d scan is done during driver load and is a passive scan on all
8487 channels supported by the device, 11d scans may find some APs on
8488 frequencies which are forbidden to be used in the regulatory domain
8489 the device is operating in. If these APs are notified to the supplicant
8490 it may try to connect to these APs, thus flush out all the scan results
8491 which are present in SME after 11d scan is done.
8492
8493 \return - eHalStatus
8494
8495 --------------------------------------------------------------------------*/
8496static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8497 tANI_U32 scanId, eCsrScanStatus status)
8498{
8499 ENTER();
8500
8501 sme_ScanFlushResult(halHandle, 0);
8502
8503 EXIT();
8504
8505 return eHAL_STATUS_SUCCESS;
8506}
8507
8508/**---------------------------------------------------------------------------
8509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 \brief hdd_wlan_startup() - HDD init function
8511
8512 This is the driver startup code executed once a WLAN device has been detected
8513
8514 \param - dev - Pointer to the underlying device
8515
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008516 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008517
8518 --------------------------------------------------------------------------*/
8519
8520int hdd_wlan_startup(struct device *dev )
8521{
8522 VOS_STATUS status;
8523 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008524 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 hdd_context_t *pHddCtx = NULL;
8526 v_CONTEXT_t pVosContext= NULL;
8527#ifdef WLAN_BTAMP_FEATURE
8528 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8529 WLANBAP_ConfigType btAmpConfig;
8530 hdd_config_t *pConfig;
8531#endif
8532 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308534 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008535
8536 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 /*
8538 * cfg80211: wiphy allocation
8539 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308540 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008541
8542 if(wiphy == NULL)
8543 {
8544 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008545 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 }
8547
8548 pHddCtx = wiphy_priv(wiphy);
8549
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 //Initialize the adapter context to zeros.
8551 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8552
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308555 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008556
8557 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8558
8559 /*Get vos context here bcoz vos_open requires it*/
8560 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8561
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008562 if(pVosContext == NULL)
8563 {
8564 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8565 goto err_free_hdd_context;
8566 }
8567
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 //Save the Global VOSS context in adapter context for future.
8569 pHddCtx->pvosContext = pVosContext;
8570
8571 //Save the adapter context in global context for future.
8572 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8573
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 pHddCtx->parent_dev = dev;
8575
8576 init_completion(&pHddCtx->full_pwr_comp_var);
8577 init_completion(&pHddCtx->standby_comp_var);
8578 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008579 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008580 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308581 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308582 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008583
8584#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008585 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008586#else
8587 init_completion(&pHddCtx->driver_crda_req);
8588#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008589
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308590 spin_lock_init(&pHddCtx->schedScan_lock);
8591
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8593
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308594#ifdef FEATURE_WLAN_TDLS
8595 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8596 * invoked by other instances also) to protect the concurrent
8597 * access for the Adapters by TDLS module.
8598 */
8599 mutex_init(&pHddCtx->tdls_lock);
8600#endif
Agarwal Ashish1f422872014-07-22 00:11:55 +05308601 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308602
Agarwal Ashish1f422872014-07-22 00:11:55 +05308603 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 // Load all config first as TL config is needed during vos_open
8605 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8606 if(pHddCtx->cfg_ini == NULL)
8607 {
8608 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8609 goto err_free_hdd_context;
8610 }
8611
8612 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8613
8614 // Read and parse the qcom_cfg.ini file
8615 status = hdd_parse_config_ini( pHddCtx );
8616 if ( VOS_STATUS_SUCCESS != status )
8617 {
8618 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8619 __func__, WLAN_INI_FILE);
8620 goto err_config;
8621 }
Arif Hussaind5218912013-12-05 01:10:55 -08008622#ifdef MEMORY_DEBUG
8623 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8624 vos_mem_init();
8625
8626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8627 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008629
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308630 /* INI has been read, initialise the configuredMcastBcastFilter with
8631 * INI value as this will serve as the default value
8632 */
8633 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8634 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8635 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308636
8637 if (false == hdd_is_5g_supported(pHddCtx))
8638 {
8639 //5Ghz is not supported.
8640 if (1 != pHddCtx->cfg_ini->nBandCapability)
8641 {
8642 hddLog(VOS_TRACE_LEVEL_INFO,
8643 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8644 pHddCtx->cfg_ini->nBandCapability = 1;
8645 }
8646 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308647
8648 /* If SNR Monitoring is enabled, FW has to parse all beacons
8649 * for calcaluting and storing the average SNR, so set Nth beacon
8650 * filter to 1 to enable FW to parse all the beaocons
8651 */
8652 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8653 {
8654 /* The log level is deliberately set to WARN as overriding
8655 * nthBeaconFilter to 1 will increase power cosumption and this
8656 * might just prove helpful to detect the power issue.
8657 */
8658 hddLog(VOS_TRACE_LEVEL_WARN,
8659 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8660 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8661 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008662 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308663 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008664 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008665 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008667 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8668 {
8669 hddLog(VOS_TRACE_LEVEL_FATAL,
8670 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8671 goto err_config;
8672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008674
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008675 // Update VOS trace levels based upon the cfg.ini
8676 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8677 pHddCtx->cfg_ini->vosTraceEnableBAP);
8678 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8679 pHddCtx->cfg_ini->vosTraceEnableTL);
8680 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8681 pHddCtx->cfg_ini->vosTraceEnableWDI);
8682 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8683 pHddCtx->cfg_ini->vosTraceEnableHDD);
8684 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8685 pHddCtx->cfg_ini->vosTraceEnableSME);
8686 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8687 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308688 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8689 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008690 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8691 pHddCtx->cfg_ini->vosTraceEnableWDA);
8692 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8693 pHddCtx->cfg_ini->vosTraceEnableSYS);
8694 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8695 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008696 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8697 pHddCtx->cfg_ini->vosTraceEnableSAP);
8698 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8699 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008700
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 // Update WDI trace levels based upon the cfg.ini
8702 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8703 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8704 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8705 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8706 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8707 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8708 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8709 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008710
Jeff Johnson88ba7742013-02-27 14:36:02 -08008711 if (VOS_FTM_MODE == hdd_get_conparam())
8712 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8714 {
8715 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8716 goto err_free_hdd_context;
8717 }
8718 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308719
8720 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008723
Jeff Johnson88ba7742013-02-27 14:36:02 -08008724 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8726 {
8727 status = vos_watchdog_open(pVosContext,
8728 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8729
8730 if(!VOS_IS_STATUS_SUCCESS( status ))
8731 {
8732 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308733 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 }
8735 }
8736
8737 pHddCtx->isLogpInProgress = FALSE;
8738 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8739
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8741 if(!VOS_IS_STATUS_SUCCESS(status))
8742 {
8743 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 }
8746
Amar Singhala49cbc52013-10-08 18:37:44 -07008747#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008748 /* initialize the NV module. This is required so that
8749 we can initialize the channel information in wiphy
8750 from the NV.bin data. The channel information in
8751 wiphy needs to be initialized before wiphy registration */
8752
8753 status = vos_nv_open();
8754 if (!VOS_IS_STATUS_SUCCESS(status))
8755 {
8756 /* NV module cannot be initialized */
8757 hddLog( VOS_TRACE_LEVEL_FATAL,
8758 "%s: vos_nv_open failed", __func__);
8759 goto err_clkvote;
8760 }
8761
8762 status = vos_init_wiphy_from_nv_bin();
8763 if (!VOS_IS_STATUS_SUCCESS(status))
8764 {
8765 /* NV module cannot be initialized */
8766 hddLog( VOS_TRACE_LEVEL_FATAL,
8767 "%s: vos_init_wiphy failed", __func__);
8768 goto err_vos_nv_close;
8769 }
8770
Amar Singhala49cbc52013-10-08 18:37:44 -07008771#endif
8772
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308773 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 if ( !VOS_IS_STATUS_SUCCESS( status ))
8775 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008776 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308777 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 }
8779
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8781
8782 if ( NULL == pHddCtx->hHal )
8783 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008784 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 goto err_vosclose;
8786 }
8787
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008788 status = vos_preStart( pHddCtx->pvosContext );
8789 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8790 {
8791 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308792 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008793 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008794
Arif Hussaineaf68602013-12-30 23:10:44 -08008795 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8796 {
8797 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8799 __func__, enable_dfs_chan_scan);
8800 }
8801 if (0 == enable_11d || 1 == enable_11d)
8802 {
8803 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8804 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8805 __func__, enable_11d);
8806 }
8807
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008808 /* Note that the vos_preStart() sequence triggers the cfg download.
8809 The cfg download must occur before we update the SME config
8810 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 status = hdd_set_sme_config( pHddCtx );
8812
8813 if ( VOS_STATUS_SUCCESS != status )
8814 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008815 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308816 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008818
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 /* In the integrated architecture we update the configuration from
8820 the INI file and from NV before vOSS has been started so that
8821 the final contents are available to send down to the cCPU */
8822
8823 // Apply the cfg.ini to cfg.dat
8824 if (FALSE == hdd_update_config_dat(pHddCtx))
8825 {
8826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308827 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 }
8829
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308830 // Get mac addr from platform driver
8831 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8832
8833 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308835 /* Store the mac addr for first interface */
8836 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8837
8838 hddLog(VOS_TRACE_LEVEL_ERROR,
8839 "%s: WLAN Mac Addr: "
8840 MAC_ADDRESS_STR, __func__,
8841 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8842
8843 /* Here, passing Arg2 as 1 because we do not want to change the
8844 last 3 bytes (means non OUI bytes) of first interface mac
8845 addr.
8846 */
8847 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8848 {
8849 hddLog(VOS_TRACE_LEVEL_ERROR,
8850 "%s: Failed to generate wlan interface mac addr "
8851 "using MAC from ini file ", __func__);
8852 }
8853 }
8854 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8855 {
8856 // Apply the NV to cfg.dat
8857 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008858#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8859 /* There was not a valid set of MAC Addresses in NV. See if the
8860 default addresses were modified by the cfg.ini settings. If so,
8861 we'll use them, but if not, we'll autogenerate a set of MAC
8862 addresses based upon the device serial number */
8863
8864 static const v_MACADDR_t default_address =
8865 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008866
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308867 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8868 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 {
8870 /* cfg.ini has the default address, invoke autogen logic */
8871
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308872 /* Here, passing Arg2 as 0 because we want to change the
8873 last 3 bytes (means non OUI bytes) of all the interfaces
8874 mac addr.
8875 */
8876 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8877 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308879 hddLog(VOS_TRACE_LEVEL_ERROR,
8880 "%s: Failed to generate wlan interface mac addr "
8881 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8882 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 }
8885 else
8886#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8887 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008888 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 "%s: Invalid MAC address in NV, using MAC from ini file "
8890 MAC_ADDRESS_STR, __func__,
8891 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8892 }
8893 }
8894 {
8895 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308896
8897 /* Set the MAC Address Currently this is used by HAL to
8898 * add self sta. Remove this once self sta is added as
8899 * part of session open.
8900 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8902 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8903 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308904
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 if (!HAL_STATUS_SUCCESS( halStatus ))
8906 {
8907 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8908 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308909 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 }
8911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
8913 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8914 Note: Firmware image will be read and downloaded inside vos_start API */
8915 status = vos_start( pHddCtx->pvosContext );
8916 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8917 {
8918 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308919 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 }
8921
Leo Chang6cec3e22014-01-21 15:33:49 -08008922#ifdef FEATURE_WLAN_CH_AVOID
8923 /* Plug in avoid channel notification callback
8924 * This should happen before ADD_SELF_STA
8925 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308926
8927 /* check the Channel Avoidance is enabled */
8928 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8929 {
8930 sme_AddChAvoidCallback(pHddCtx->hHal,
8931 hdd_hostapd_ch_avoid_cb);
8932 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008933#endif /* FEATURE_WLAN_CH_AVOID */
8934
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008935 /* Exchange capability info between Host and FW and also get versioning info from FW */
8936 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008937
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308938#ifdef CONFIG_ENABLE_LINUX_REG
8939 status = wlan_hdd_init_channels(pHddCtx);
8940 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8941 {
8942 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8943 __func__);
8944 goto err_vosstop;
8945 }
8946#endif
8947
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 status = hdd_post_voss_start_config( pHddCtx );
8949 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8950 {
8951 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8952 __func__);
8953 goto err_vosstop;
8954 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008955
8956#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308957 wlan_hdd_cfg80211_update_reg_info( wiphy );
8958
8959 /* registration of wiphy dev with cfg80211 */
8960 if (0 > wlan_hdd_cfg80211_register(wiphy))
8961 {
8962 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8963 goto err_vosstop;
8964 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008966
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308967#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308968 /* registration of wiphy dev with cfg80211 */
8969 if (0 > wlan_hdd_cfg80211_register(wiphy))
8970 {
8971 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8972 goto err_vosstop;
8973 }
8974
8975 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8976 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8977 {
8978 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8979 __func__);
8980 goto err_unregister_wiphy;
8981 }
8982#endif
8983
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8985 {
8986 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8987 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8988 }
8989 else
8990 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8992 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8993 if (pAdapter != NULL)
8994 {
kaidde69982014-06-18 13:23:21 +08008995 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308997 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8998 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8999 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009000
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309001 /* Generate the P2P Device Address. This consists of the device's
9002 * primary MAC address with the locally administered bit set.
9003 */
9004 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009005 }
9006 else
9007 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309008 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9009 if (p2p_dev_addr != NULL)
9010 {
9011 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9012 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9013 }
9014 else
9015 {
9016 hddLog(VOS_TRACE_LEVEL_FATAL,
9017 "%s: Failed to allocate mac_address for p2p_device",
9018 __func__);
9019 goto err_close_adapter;
9020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009021 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009022
9023 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9024 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9025 if ( NULL == pP2pAdapter )
9026 {
9027 hddLog(VOS_TRACE_LEVEL_FATAL,
9028 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009029 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009030 goto err_close_adapter;
9031 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009034
9035 if( pAdapter == NULL )
9036 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9038 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009040
Arif Hussain66559122013-11-21 10:11:40 -08009041 if (country_code)
9042 {
9043 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009044 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009045 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9046#ifndef CONFIG_ENABLE_LINUX_REG
9047 hdd_checkandupdate_phymode(pAdapter, country_code);
9048#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009049 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9050 (void *)(tSmeChangeCountryCallback)
9051 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009052 country_code,
9053 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309054 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009055 if (eHAL_STATUS_SUCCESS == ret)
9056 {
Arif Hussaincb607082013-12-20 11:57:42 -08009057 ret = wait_for_completion_interruptible_timeout(
9058 &pAdapter->change_country_code,
9059 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9060
9061 if (0 >= ret)
9062 {
9063 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9064 "%s: SME while setting country code timed out", __func__);
9065 }
Arif Hussain66559122013-11-21 10:11:40 -08009066 }
9067 else
9068 {
Arif Hussaincb607082013-12-20 11:57:42 -08009069 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9070 "%s: SME Change Country code from module param fail ret=%d",
9071 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009072 }
9073 }
9074
Jeff Johnson295189b2012-06-20 16:38:30 -07009075#ifdef WLAN_BTAMP_FEATURE
9076 vStatus = WLANBAP_Open(pVosContext);
9077 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9078 {
9079 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9080 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009081 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 }
9083
9084 vStatus = BSL_Init(pVosContext);
9085 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9086 {
9087 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9088 "%s: Failed to Init BSL",__func__);
9089 goto err_bap_close;
9090 }
9091 vStatus = WLANBAP_Start(pVosContext);
9092 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9093 {
9094 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9095 "%s: Failed to start TL",__func__);
9096 goto err_bap_close;
9097 }
9098
9099 pConfig = pHddCtx->cfg_ini;
9100 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9101 status = WLANBAP_SetConfig(&btAmpConfig);
9102
9103#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009104
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009105#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9106 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9107 {
9108 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9109 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9110 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9111 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9112 }
9113#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009114
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309115 wlan_hdd_tdls_init(pHddCtx);
9116
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309117 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9118
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 /* Register with platform driver as client for Suspend/Resume */
9120 status = hddRegisterPmOps(pHddCtx);
9121 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9122 {
9123 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9124#ifdef WLAN_BTAMP_FEATURE
9125 goto err_bap_stop;
9126#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009127 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009128#endif //WLAN_BTAMP_FEATURE
9129 }
9130
Yue Ma0d4891e2013-08-06 17:01:45 -07009131 /* Open debugfs interface */
9132 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9133 {
9134 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9135 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009136 }
9137
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 /* Register TM level change handler function to the platform */
9139 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9140 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9141 {
9142 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9143 goto err_unregister_pmops;
9144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009145
9146 /* register for riva power on lock to platform driver */
9147 if (req_riva_power_on_lock("wlan"))
9148 {
9149 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9150 __func__);
9151 goto err_unregister_pmops;
9152 }
9153
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 // register net device notifier for device change notification
9155 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9156
9157 if(ret < 0)
9158 {
9159 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9160 goto err_free_power_on_lock;
9161 }
9162
9163 //Initialize the nlink service
9164 if(nl_srv_init() != 0)
9165 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309166 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 goto err_reg_netdev;
9168 }
9169
Leo Chang4ce1cc52013-10-21 18:27:15 -07009170#ifdef WLAN_KD_READY_NOTIFIER
9171 pHddCtx->kd_nl_init = 1;
9172#endif /* WLAN_KD_READY_NOTIFIER */
9173
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 //Initialize the BTC service
9175 if(btc_activate_service(pHddCtx) != 0)
9176 {
9177 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9178 goto err_nl_srv;
9179 }
9180
9181#ifdef PTT_SOCK_SVC_ENABLE
9182 //Initialize the PTT service
9183 if(ptt_sock_activate_svc(pHddCtx) != 0)
9184 {
9185 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9186 goto err_nl_srv;
9187 }
9188#endif
9189
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309190#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9191 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9192 {
9193 if(wlan_logging_sock_activate_svc(
9194 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9195 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9196 {
9197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9198 " failed", __func__);
9199 goto err_nl_srv;
9200 }
9201 }
9202#endif
9203
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009207 /* Action frame registered in one adapter which will
9208 * applicable to all interfaces
9209 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309210 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009212
9213 mutex_init(&pHddCtx->sap_lock);
9214
Jeff Johnson295189b2012-06-20 16:38:30 -07009215
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009216#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009217#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9218 /* Initialize the wake lcok */
9219 wake_lock_init(&pHddCtx->rx_wake_lock,
9220 WAKE_LOCK_SUSPEND,
9221 "qcom_rx_wakelock");
9222#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009223 /* Initialize the wake lcok */
9224 wake_lock_init(&pHddCtx->sap_wake_lock,
9225 WAKE_LOCK_SUSPEND,
9226 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009227#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009228
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009229 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9230 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009231
Katya Nigam5c306ea2014-06-19 15:39:54 +05309232 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9234 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309235
9236#ifdef FEATURE_WLAN_SCAN_PNO
9237 /*SME must send channel update configuration to RIVA*/
9238 sme_UpdateChannelConfig(pHddCtx->hHal);
9239#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309240 /* Send the update default channel list to the FW*/
9241 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309242#ifndef CONFIG_ENABLE_LINUX_REG
9243 /*updating wiphy so that regulatory user hints can be processed*/
9244 if (wiphy)
9245 {
9246 regulatory_hint(wiphy, "00");
9247 }
9248#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009249 // Initialize the restart logic
9250 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309251
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009252 //Register the traffic monitor timer now
9253 if ( pHddCtx->cfg_ini->dynSplitscan)
9254 {
9255 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9256 VOS_TIMER_TYPE_SW,
9257 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9258 (void *)pHddCtx);
9259 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309260#ifdef WLAN_FEATURE_EXTSCAN
9261 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9262 wlan_hdd_cfg80211_extscan_callback,
9263 pHddCtx);
9264#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 goto success;
9266
9267err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009268#ifdef WLAN_KD_READY_NOTIFIER
9269 nl_srv_exit(pHddCtx->ptt_pid);
9270#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009272#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009273err_reg_netdev:
9274 unregister_netdevice_notifier(&hdd_netdev_notifier);
9275
9276err_free_power_on_lock:
9277 free_riva_power_on_lock("wlan");
9278
9279err_unregister_pmops:
9280 hddDevTmUnregisterNotifyCallback(pHddCtx);
9281 hddDeregisterPmOps(pHddCtx);
9282
Yue Ma0d4891e2013-08-06 17:01:45 -07009283 hdd_debugfs_exit(pHddCtx);
9284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285#ifdef WLAN_BTAMP_FEATURE
9286err_bap_stop:
9287 WLANBAP_Stop(pVosContext);
9288#endif
9289
9290#ifdef WLAN_BTAMP_FEATURE
9291err_bap_close:
9292 WLANBAP_Close(pVosContext);
9293#endif
9294
Jeff Johnson295189b2012-06-20 16:38:30 -07009295err_close_adapter:
9296 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309297#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309298err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309299#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309300 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009301err_vosstop:
9302 vos_stop(pVosContext);
9303
Amar Singhala49cbc52013-10-08 18:37:44 -07009304err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 status = vos_sched_close( pVosContext );
9306 if (!VOS_IS_STATUS_SUCCESS(status)) {
9307 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9308 "%s: Failed to close VOSS Scheduler", __func__);
9309 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9310 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009311 vos_close(pVosContext );
9312
Amar Singhal0a402232013-10-11 20:57:16 -07009313err_vos_nv_close:
9314
c_hpothue6a36282014-03-19 12:27:38 +05309315#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009316 vos_nv_close();
9317
Jeff Johnson295189b2012-06-20 16:38:30 -07009318err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309319#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009320 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009321
9322err_wdclose:
9323 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9324 vos_watchdog_close(pVosContext);
9325
Jeff Johnson295189b2012-06-20 16:38:30 -07009326err_config:
9327 kfree(pHddCtx->cfg_ini);
9328 pHddCtx->cfg_ini= NULL;
9329
9330err_free_hdd_context:
9331 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 wiphy_free(wiphy) ;
9333 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 VOS_BUG(1);
9335
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009336 if (hdd_is_ssr_required())
9337 {
9338 /* WDI timeout had happened during load, so SSR is needed here */
9339 subsystem_restart("wcnss");
9340 msleep(5000);
9341 }
9342 hdd_set_ssr_required (VOS_FALSE);
9343
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009344 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009345
9346success:
9347 EXIT();
9348 return 0;
9349}
9350
9351/**---------------------------------------------------------------------------
9352
Jeff Johnson32d95a32012-09-10 13:15:23 -07009353 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009354
Jeff Johnson32d95a32012-09-10 13:15:23 -07009355 This is the driver entry point - called in different timeline depending
9356 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009357
9358 \param - None
9359
9360 \return - 0 for success, non zero for failure
9361
9362 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009363static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009364{
9365 VOS_STATUS status;
9366 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 struct device *dev = NULL;
9368 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009369#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9370 int max_retries = 0;
9371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309373#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9374 wlan_logging_sock_init_svc();
9375#endif
9376
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 ENTER();
9378
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009379#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009381#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009382
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309383 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9385 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9386
9387 //Power Up Libra WLAN card first if not already powered up
9388 status = vos_chipPowerUp(NULL,NULL,NULL);
9389 if (!VOS_IS_STATUS_SUCCESS(status))
9390 {
9391 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9392 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309393#ifdef WLAN_OPEN_SOURCE
9394 wake_lock_destroy(&wlan_wake_lock);
9395#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309396
9397#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9398 wlan_logging_sock_deinit_svc();
9399#endif
9400
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009401 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 }
9403
Jeff Johnson295189b2012-06-20 16:38:30 -07009404#ifdef ANI_BUS_TYPE_PCI
9405
9406 dev = wcnss_wlan_get_device();
9407
9408#endif // ANI_BUS_TYPE_PCI
9409
9410#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009411
9412#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9413 /* wait until WCNSS driver downloads NV */
9414 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9415 msleep(1000);
9416 }
9417 if (max_retries >= 5) {
9418 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309419#ifdef WLAN_OPEN_SOURCE
9420 wake_lock_destroy(&wlan_wake_lock);
9421#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309422
9423#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9424 wlan_logging_sock_deinit_svc();
9425#endif
9426
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009427 return -ENODEV;
9428 }
9429#endif
9430
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 dev = wcnss_wlan_get_device();
9432#endif // ANI_BUS_TYPE_PLATFORM
9433
9434
9435 do {
9436 if (NULL == dev) {
9437 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9438 ret_status = -1;
9439 break;
9440 }
9441
Jeff Johnson295189b2012-06-20 16:38:30 -07009442#ifdef TIMER_MANAGER
9443 vos_timer_manager_init();
9444#endif
9445
9446 /* Preopen VOSS so that it is ready to start at least SAL */
9447 status = vos_preOpen(&pVosContext);
9448
9449 if (!VOS_IS_STATUS_SUCCESS(status))
9450 {
9451 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9452 ret_status = -1;
9453 break;
9454 }
9455
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009456#ifndef MODULE
9457 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9458 */
9459 hdd_set_conparam((v_UINT_t)con_mode);
9460#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009461
9462 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009463 if (hdd_wlan_startup(dev))
9464 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009466 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 vos_preClose( &pVosContext );
9468 ret_status = -1;
9469 break;
9470 }
9471
9472 /* Cancel the vote for XO Core ON
9473 * This is done here for safety purposes in case we re-initialize without turning
9474 * it OFF in any error scenario.
9475 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009476 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009478 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9480 {
9481 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009482 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 }
9484 } while (0);
9485
9486 if (0 != ret_status)
9487 {
9488 //Assert Deep sleep signal now to put Libra HW in lowest power state
9489 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9490 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9491
9492 //Vote off any PMIC voltage supplies
9493 vos_chipPowerDown(NULL, NULL, NULL);
9494#ifdef TIMER_MANAGER
9495 vos_timer_exit();
9496#endif
9497#ifdef MEMORY_DEBUG
9498 vos_mem_exit();
9499#endif
9500
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009501#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009503#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309504
9505#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9506 wlan_logging_sock_deinit_svc();
9507#endif
9508
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9510 }
9511 else
9512 {
9513 //Send WLAN UP indication to Nlink Service
9514 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9515
9516 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 }
9518
9519 EXIT();
9520
9521 return ret_status;
9522}
9523
Jeff Johnson32d95a32012-09-10 13:15:23 -07009524/**---------------------------------------------------------------------------
9525
9526 \brief hdd_module_init() - Init Function
9527
9528 This is the driver entry point (invoked when module is loaded using insmod)
9529
9530 \param - None
9531
9532 \return - 0 for success, non zero for failure
9533
9534 --------------------------------------------------------------------------*/
9535#ifdef MODULE
9536static int __init hdd_module_init ( void)
9537{
9538 return hdd_driver_init();
9539}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009540#else /* #ifdef MODULE */
9541static int __init hdd_module_init ( void)
9542{
9543 /* Driver initialization is delayed to fwpath_changed_handler */
9544 return 0;
9545}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009546#endif /* #ifdef MODULE */
9547
Jeff Johnson295189b2012-06-20 16:38:30 -07009548
9549/**---------------------------------------------------------------------------
9550
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009551 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009552
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009553 This is the driver exit point (invoked when module is unloaded using rmmod
9554 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009555
9556 \param - None
9557
9558 \return - None
9559
9560 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009561static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009562{
9563 hdd_context_t *pHddCtx = NULL;
9564 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309565 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309566 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009567
9568 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9569
9570 //Get the global vos context
9571 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9572
9573 if(!pVosContext)
9574 {
9575 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9576 goto done;
9577 }
9578
9579 //Get the HDD context.
9580 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9581
9582 if(!pHddCtx)
9583 {
9584 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9585 }
9586 else
9587 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309588 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9589
9590 if (pHddCtx->isLogpInProgress)
9591 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309593 "%s:SSR in Progress; block rmmod !!!", __func__);
9594 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9595 msecs_to_jiffies(30000));
9596 if(!rc)
9597 {
9598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9599 "%s:SSR timedout, fatal error", __func__);
9600 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009601 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
Vinay Krishna Erannae362b452014-09-23 13:09:46 +05309604 rtnl_lock();
Mihir Shete18156292014-03-11 15:38:30 +05309605 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Vinay Krishna Erannae362b452014-09-23 13:09:46 +05309607 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -07009608
Agarwal Ashish8db39882014-07-30 21:56:07 +05309609 /* Driver Need to send country code 00 in below condition
9610 * 1) If gCountryCodePriority is set to 1; and last country
9611 * code set is through 11d. This needs to be done in case
9612 * when NV country code is 00.
9613 * This Needs to be done as when kernel store last country
9614 * code and if stored country code is not through 11d,
9615 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9616 * in next load/unload as soon as we get any country through
9617 * 11d. In sme_HandleChangeCountryCodeByUser
9618 * pMsg->countryCode will be last countryCode and
9619 * pMac->scan.countryCode11d will be country through 11d so
9620 * due to mismatch driver will disable 11d.
9621 *
9622 * 2) When NV country Code is non-zero ;
9623 * There are chances that kernel last country and default
9624 * country can be same. In this case if Driver doesn't pass 00 to
9625 * kernel, at the time of driver loading next timer, driver will not
9626 * call any hint to kernel as country is same. This can add 3 sec
9627 * delay in driver loading.
9628 */
9629
9630 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309631 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Agarwal Ashish8db39882014-07-30 21:56:07 +05309632 sme_Is11dSupported(pHddCtx->hHal)) || (vos_is_nv_country_non_zero() ))
Agarwal Ashish5e414792014-06-08 15:25:23 +05309633 {
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309634 hddLog(VOS_TRACE_LEVEL_INFO,
9635 FL("CountryCode 00 is being set while unloading driver"));
Agarwal Ashish5e414792014-06-08 15:25:23 +05309636 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9637 }
9638
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 //Do all the cleanup before deregistering the driver
9640 hdd_wlan_exit(pHddCtx);
9641 }
9642
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 vos_preClose( &pVosContext );
9644
9645#ifdef TIMER_MANAGER
9646 vos_timer_exit();
9647#endif
9648#ifdef MEMORY_DEBUG
9649 vos_mem_exit();
9650#endif
9651
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309652#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9653 wlan_logging_sock_deinit_svc();
9654#endif
9655
Jeff Johnson295189b2012-06-20 16:38:30 -07009656done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009657#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009659#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309660
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9662}
9663
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009664/**---------------------------------------------------------------------------
9665
9666 \brief hdd_module_exit() - Exit function
9667
9668 This is the driver exit point (invoked when module is unloaded using rmmod)
9669
9670 \param - None
9671
9672 \return - None
9673
9674 --------------------------------------------------------------------------*/
9675static void __exit hdd_module_exit(void)
9676{
9677 hdd_driver_exit();
9678}
9679
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009680#ifdef MODULE
9681static int fwpath_changed_handler(const char *kmessage,
9682 struct kernel_param *kp)
9683{
Jeff Johnson76052702013-04-16 13:55:05 -07009684 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009685}
9686
9687static int con_mode_handler(const char *kmessage,
9688 struct kernel_param *kp)
9689{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009690 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009691}
9692#else /* #ifdef MODULE */
9693/**---------------------------------------------------------------------------
9694
Jeff Johnson76052702013-04-16 13:55:05 -07009695 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009696
Jeff Johnson76052702013-04-16 13:55:05 -07009697 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009698 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009699 - invoked when module parameter fwpath is modified from userspace to signal
9700 initializing the WLAN driver or when con_mode is modified from userspace
9701 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009702
9703 \return - 0 for success, non zero for failure
9704
9705 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009706static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009707{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009708 int ret_status;
9709
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009710 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009711 ret_status = hdd_driver_init();
9712 wlan_hdd_inited = ret_status ? 0 : 1;
9713 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009714 }
9715
9716 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009717
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009718 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009719
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009720 ret_status = hdd_driver_init();
9721 wlan_hdd_inited = ret_status ? 0 : 1;
9722 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009723}
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725/**---------------------------------------------------------------------------
9726
Jeff Johnson76052702013-04-16 13:55:05 -07009727 \brief fwpath_changed_handler() - Handler Function
9728
9729 Handle changes to the fwpath parameter
9730
9731 \return - 0 for success, non zero for failure
9732
9733 --------------------------------------------------------------------------*/
9734static int fwpath_changed_handler(const char *kmessage,
9735 struct kernel_param *kp)
9736{
9737 int ret;
9738
9739 ret = param_set_copystring(kmessage, kp);
9740 if (0 == ret)
9741 ret = kickstart_driver();
9742 return ret;
9743}
9744
9745/**---------------------------------------------------------------------------
9746
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009747 \brief con_mode_handler() -
9748
9749 Handler function for module param con_mode when it is changed by userspace
9750 Dynamically linked - do nothing
9751 Statically linked - exit and init driver, as in rmmod and insmod
9752
Jeff Johnson76052702013-04-16 13:55:05 -07009753 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009754
Jeff Johnson76052702013-04-16 13:55:05 -07009755 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009756
9757 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009758static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009759{
Jeff Johnson76052702013-04-16 13:55:05 -07009760 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009761
Jeff Johnson76052702013-04-16 13:55:05 -07009762 ret = param_set_int(kmessage, kp);
9763 if (0 == ret)
9764 ret = kickstart_driver();
9765 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009766}
9767#endif /* #ifdef MODULE */
9768
9769/**---------------------------------------------------------------------------
9770
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 \brief hdd_get_conparam() -
9772
9773 This is the driver exit point (invoked when module is unloaded using rmmod)
9774
9775 \param - None
9776
9777 \return - tVOS_CON_MODE
9778
9779 --------------------------------------------------------------------------*/
9780tVOS_CON_MODE hdd_get_conparam ( void )
9781{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009782#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009784#else
9785 return (tVOS_CON_MODE)curr_con_mode;
9786#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009787}
9788void hdd_set_conparam ( v_UINT_t newParam )
9789{
9790 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009791#ifndef MODULE
9792 curr_con_mode = con_mode;
9793#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009794}
9795/**---------------------------------------------------------------------------
9796
9797 \brief hdd_softap_sta_deauth() - function
9798
9799 This to take counter measure to handle deauth req from HDD
9800
9801 \param - pAdapter - Pointer to the HDD
9802
9803 \param - enable - boolean value
9804
9805 \return - None
9806
9807 --------------------------------------------------------------------------*/
9808
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009809VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009810{
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009812 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009813
9814 ENTER();
9815
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009816 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9817 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009818
9819 //Ignore request to deauth bcmc station
9820 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009821 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009822
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009823 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009824
9825 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009826 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009827}
9828
9829/**---------------------------------------------------------------------------
9830
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309831 \brief hdd_del_all_sta() - function
9832
9833 This function removes all the stations associated on stopping AP/P2P GO.
9834
9835 \param - pAdapter - Pointer to the HDD
9836
9837 \return - None
9838
9839 --------------------------------------------------------------------------*/
9840
9841int hdd_del_all_sta(hdd_adapter_t *pAdapter)
9842{
9843 v_U16_t i;
9844 VOS_STATUS vos_status;
9845
9846 ENTER();
9847
9848 hddLog(VOS_TRACE_LEVEL_INFO,
9849 "%s: Delete all STAs associated.",__func__);
9850 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9851 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
9852 )
9853 {
9854 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
9855 {
9856 if ((pAdapter->aStaInfo[i].isUsed) &&
9857 (!pAdapter->aStaInfo[i].isDeauthInProgress))
9858 {
9859 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
9860 hddLog(VOS_TRACE_LEVEL_ERROR,
9861 "%s: Delete STA with staid = %d and MAC::"
9862 MAC_ADDRESS_STR,
9863 __func__, i, MAC_ADDR_ARRAY(macAddr));
9864 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
9865 if (VOS_IS_STATUS_SUCCESS(vos_status))
9866 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
9867 }
9868 }
9869 }
9870
9871 EXIT();
9872 return 0;
9873}
9874
9875/**---------------------------------------------------------------------------
9876
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 \brief hdd_softap_sta_disassoc() - function
9878
9879 This to take counter measure to handle deauth req from HDD
9880
9881 \param - pAdapter - Pointer to the HDD
9882
9883 \param - enable - boolean value
9884
9885 \return - None
9886
9887 --------------------------------------------------------------------------*/
9888
9889void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9890{
9891 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9892
9893 ENTER();
9894
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309895 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009896
9897 //Ignore request to disassoc bcmc station
9898 if( pDestMacAddress[0] & 0x1 )
9899 return;
9900
9901 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9902}
9903
9904void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9905{
9906 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9907
9908 ENTER();
9909
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309910 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009911
9912 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9913}
9914
Jeff Johnson295189b2012-06-20 16:38:30 -07009915/**---------------------------------------------------------------------------
9916 *
9917 * \brief hdd_get__concurrency_mode() -
9918 *
9919 *
9920 * \param - None
9921 *
9922 * \return - CONCURRENCY MODE
9923 *
9924 * --------------------------------------------------------------------------*/
9925tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9926{
9927 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9928 hdd_context_t *pHddCtx;
9929
9930 if (NULL != pVosContext)
9931 {
9932 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9933 if (NULL != pHddCtx)
9934 {
9935 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9936 }
9937 }
9938
9939 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009940 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 return VOS_STA;
9942}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309943v_BOOL_t
9944wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
9945{
9946 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309948 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
9949 if (pAdapter == NULL)
9950 {
9951 hddLog(VOS_TRACE_LEVEL_INFO,
9952 FL("GO doesn't exist"));
9953 return TRUE;
9954 }
9955 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9956 {
9957 hddLog(VOS_TRACE_LEVEL_INFO,
9958 FL("GO started"));
9959 return TRUE;
9960 }
9961 else
9962 /* wait till GO changes its interface to p2p device */
9963 hddLog(VOS_TRACE_LEVEL_INFO,
9964 FL("Del_bss called, avoid apps suspend"));
9965 return FALSE;
9966
9967}
Jeff Johnson295189b2012-06-20 16:38:30 -07009968/* Decide whether to allow/not the apps power collapse.
9969 * Allow apps power collapse if we are in connected state.
9970 * if not, allow only if we are in IMPS */
9971v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9972{
9973 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009974 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009975 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9977 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9978 hdd_adapter_t *pAdapter = NULL;
9979 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009980 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009981
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9983 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009984
Yathish9f22e662012-12-10 14:21:35 -08009985 concurrent_state = hdd_get_concurrency_mode();
9986
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309987 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
9988 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
9989 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -08009990#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309991
Yathish9f22e662012-12-10 14:21:35 -08009992 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309993 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -08009994 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9995 return TRUE;
9996#endif
9997
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 /*loop through all adapters. TBD fix for Concurrency */
9999 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10000 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10001 {
10002 pAdapter = pAdapterNode->pAdapter;
10003 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10004 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10005 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010006 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010007 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -080010008 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010009 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10010 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010012 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010013 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10014 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 return FALSE;
10016 }
10017 }
10018 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10019 pAdapterNode = pNext;
10020 }
10021 return TRUE;
10022}
10023
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010024/* Decides whether to send suspend notification to Riva
10025 * if any adapter is in BMPS; then it is required */
10026v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10027{
10028 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10029 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10030
10031 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10032 {
10033 return TRUE;
10034 }
10035 return FALSE;
10036}
10037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10039{
10040 switch(mode)
10041 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010042 case VOS_STA_MODE:
10043 case VOS_P2P_CLIENT_MODE:
10044 case VOS_P2P_GO_MODE:
10045 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010046 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010047 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 break;
10049 default:
10050 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010052 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10053 "Number of open sessions for mode %d = %d"),
10054 pHddCtx->concurrency_mode, mode,
10055 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010056}
10057
10058
10059void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10060{
10061 switch(mode)
10062 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010063 case VOS_STA_MODE:
10064 case VOS_P2P_CLIENT_MODE:
10065 case VOS_P2P_GO_MODE:
10066 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010067 pHddCtx->no_of_open_sessions[mode]--;
10068 if (!(pHddCtx->no_of_open_sessions[mode]))
10069 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 break;
10071 default:
10072 break;
10073 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010074 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10075 "Number of open sessions for mode %d = %d"),
10076 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10077
10078}
10079/**---------------------------------------------------------------------------
10080 *
10081 * \brief wlan_hdd_incr_active_session()
10082 *
10083 * This function increments the number of active sessions
10084 * maintained per device mode
10085 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10086 * Incase of SAP/P2P GO upon bss start it is incremented
10087 *
10088 * \param pHddCtx - HDD Context
10089 * \param mode - device mode
10090 *
10091 * \return - None
10092 *
10093 * --------------------------------------------------------------------------*/
10094void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10095{
10096 switch (mode) {
10097 case VOS_STA_MODE:
10098 case VOS_P2P_CLIENT_MODE:
10099 case VOS_P2P_GO_MODE:
10100 case VOS_STA_SAP_MODE:
10101 pHddCtx->no_of_active_sessions[mode]++;
10102 break;
10103 default:
10104 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10105 break;
10106 }
10107 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10108 mode,
10109 pHddCtx->no_of_active_sessions[mode]);
10110}
10111
10112/**---------------------------------------------------------------------------
10113 *
10114 * \brief wlan_hdd_decr_active_session()
10115 *
10116 * This function decrements the number of active sessions
10117 * maintained per device mode
10118 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10119 * Incase of SAP/P2P GO upon bss stop it is decremented
10120 *
10121 * \param pHddCtx - HDD Context
10122 * \param mode - device mode
10123 *
10124 * \return - None
10125 *
10126 * --------------------------------------------------------------------------*/
10127void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10128{
10129 switch (mode) {
10130 case VOS_STA_MODE:
10131 case VOS_P2P_CLIENT_MODE:
10132 case VOS_P2P_GO_MODE:
10133 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010134 if (pHddCtx->no_of_active_sessions[mode] > 0)
10135 pHddCtx->no_of_active_sessions[mode]--;
10136 else
10137 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10138 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010139 break;
10140 default:
10141 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10142 break;
10143 }
10144 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10145 mode,
10146 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010147}
10148
Jeff Johnsone7245742012-09-05 17:12:55 -070010149/**---------------------------------------------------------------------------
10150 *
10151 * \brief wlan_hdd_restart_init
10152 *
10153 * This function initalizes restart timer/flag. An internal function.
10154 *
10155 * \param - pHddCtx
10156 *
10157 * \return - None
10158 *
10159 * --------------------------------------------------------------------------*/
10160
10161static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10162{
10163 /* Initialize */
10164 pHddCtx->hdd_restart_retries = 0;
10165 atomic_set(&pHddCtx->isRestartInProgress, 0);
10166 vos_timer_init(&pHddCtx->hdd_restart_timer,
10167 VOS_TIMER_TYPE_SW,
10168 wlan_hdd_restart_timer_cb,
10169 pHddCtx);
10170}
10171/**---------------------------------------------------------------------------
10172 *
10173 * \brief wlan_hdd_restart_deinit
10174 *
10175 * This function cleans up the resources used. An internal function.
10176 *
10177 * \param - pHddCtx
10178 *
10179 * \return - None
10180 *
10181 * --------------------------------------------------------------------------*/
10182
10183static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10184{
10185
10186 VOS_STATUS vos_status;
10187 /* Block any further calls */
10188 atomic_set(&pHddCtx->isRestartInProgress, 1);
10189 /* Cleanup */
10190 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10191 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010192 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010193 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10194 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010195 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010196
10197}
10198
10199/**---------------------------------------------------------------------------
10200 *
10201 * \brief wlan_hdd_framework_restart
10202 *
10203 * This function uses a cfg80211 API to start a framework initiated WLAN
10204 * driver module unload/load.
10205 *
10206 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10207 *
10208 *
10209 * \param - pHddCtx
10210 *
10211 * \return - VOS_STATUS_SUCCESS: Success
10212 * VOS_STATUS_E_EMPTY: Adapter is Empty
10213 * VOS_STATUS_E_NOMEM: No memory
10214
10215 * --------------------------------------------------------------------------*/
10216
10217static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10218{
10219 VOS_STATUS status = VOS_STATUS_SUCCESS;
10220 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010221 int len = (sizeof (struct ieee80211_mgmt));
10222 struct ieee80211_mgmt *mgmt = NULL;
10223
10224 /* Prepare the DEAUTH managment frame with reason code */
10225 mgmt = kzalloc(len, GFP_KERNEL);
10226 if(mgmt == NULL)
10227 {
10228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10229 "%s: memory allocation failed (%d bytes)", __func__, len);
10230 return VOS_STATUS_E_NOMEM;
10231 }
10232 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010233
10234 /* Iterate over all adapters/devices */
10235 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10236 do
10237 {
10238 if( (status == VOS_STATUS_SUCCESS) &&
10239 pAdapterNode &&
10240 pAdapterNode->pAdapter)
10241 {
10242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10243 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10244 pAdapterNode->pAdapter->dev->name,
10245 pAdapterNode->pAdapter->device_mode,
10246 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010247 /*
10248 * CFG80211 event to restart the driver
10249 *
10250 * 'cfg80211_send_unprot_deauth' sends a
10251 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10252 * of SME(Linux Kernel) state machine.
10253 *
10254 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10255 * the driver.
10256 *
10257 */
10258
10259 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010260 }
10261 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10262 pAdapterNode = pNext;
10263 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10264
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010265
10266 /* Free the allocated management frame */
10267 kfree(mgmt);
10268
Jeff Johnsone7245742012-09-05 17:12:55 -070010269 /* Retry until we unload or reach max count */
10270 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10271 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10272
10273 return status;
10274
10275}
10276/**---------------------------------------------------------------------------
10277 *
10278 * \brief wlan_hdd_restart_timer_cb
10279 *
10280 * Restart timer callback. An internal function.
10281 *
10282 * \param - User data:
10283 *
10284 * \return - None
10285 *
10286 * --------------------------------------------------------------------------*/
10287
10288void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10289{
10290 hdd_context_t *pHddCtx = usrDataForCallback;
10291 wlan_hdd_framework_restart(pHddCtx);
10292 return;
10293
10294}
10295
10296
10297/**---------------------------------------------------------------------------
10298 *
10299 * \brief wlan_hdd_restart_driver
10300 *
10301 * This function sends an event to supplicant to restart the WLAN driver.
10302 *
10303 * This function is called from vos_wlanRestart.
10304 *
10305 * \param - pHddCtx
10306 *
10307 * \return - VOS_STATUS_SUCCESS: Success
10308 * VOS_STATUS_E_EMPTY: Adapter is Empty
10309 * VOS_STATUS_E_ALREADY: Request already in progress
10310
10311 * --------------------------------------------------------------------------*/
10312VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10313{
10314 VOS_STATUS status = VOS_STATUS_SUCCESS;
10315
10316 /* A tight check to make sure reentrancy */
10317 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10318 {
Mihir Shetefd528652014-06-23 19:07:50 +053010319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010320 "%s: WLAN restart is already in progress", __func__);
10321
10322 return VOS_STATUS_E_ALREADY;
10323 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010324 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010325#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010326 wcnss_reset_intr();
10327#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010328
Jeff Johnsone7245742012-09-05 17:12:55 -070010329 return status;
10330}
10331
Mihir Shetee1093ba2014-01-21 20:13:32 +053010332/**---------------------------------------------------------------------------
10333 *
10334 * \brief wlan_hdd_init_channels
10335 *
10336 * This function is used to initialize the channel list in CSR
10337 *
10338 * This function is called from hdd_wlan_startup
10339 *
10340 * \param - pHddCtx: HDD context
10341 *
10342 * \return - VOS_STATUS_SUCCESS: Success
10343 * VOS_STATUS_E_FAULT: Failure reported by SME
10344
10345 * --------------------------------------------------------------------------*/
10346static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10347{
10348 eHalStatus status;
10349
10350 status = sme_InitChannels(pHddCtx->hHal);
10351 if (HAL_STATUS_SUCCESS(status))
10352 {
10353 return VOS_STATUS_SUCCESS;
10354 }
10355 else
10356 {
10357 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10358 __func__, status);
10359 return VOS_STATUS_E_FAULT;
10360 }
10361}
10362
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010363static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10364{
10365 eHalStatus status;
10366
10367 status = sme_InitChannelsForCC(pHddCtx->hHal);
10368 if (HAL_STATUS_SUCCESS(status))
10369 {
10370 return VOS_STATUS_SUCCESS;
10371 }
10372 else
10373 {
10374 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10375 __func__, status);
10376 return VOS_STATUS_E_FAULT;
10377 }
10378}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010379/*
10380 * API to find if there is any STA or P2P-Client is connected
10381 */
10382VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10383{
10384 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10385}
Jeff Johnsone7245742012-09-05 17:12:55 -070010386
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010387int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10388{
10389 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10390 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010391 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010392
10393 pScanInfo = &pHddCtx->scan_info;
10394 if (pScanInfo->mScanPending)
10395 {
10396 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10397 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10398 eCSR_SCAN_ABORT_DEFAULT);
10399
10400 status = wait_for_completion_interruptible_timeout(
10401 &pScanInfo->abortscan_event_var,
10402 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010403 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010404 {
10405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010406 "%s: Timeout or Interrupt occurred while waiting for abort"
10407 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010408 return -ETIMEDOUT;
10409 }
10410 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010411 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010412}
10413
Jeff Johnson295189b2012-06-20 16:38:30 -070010414//Register the module init/exit functions
10415module_init(hdd_module_init);
10416module_exit(hdd_module_exit);
10417
10418MODULE_LICENSE("Dual BSD/GPL");
10419MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10420MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10421
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010422module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10423 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010424
Jeff Johnson76052702013-04-16 13:55:05 -070010425module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010426 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010427
10428module_param(enable_dfs_chan_scan, int,
10429 S_IRUSR | S_IRGRP | S_IROTH);
10430
10431module_param(enable_11d, int,
10432 S_IRUSR | S_IRGRP | S_IROTH);
10433
10434module_param(country_code, charp,
10435 S_IRUSR | S_IRGRP | S_IROTH);